diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /js/src/tests/test262/built-ins/Temporal/TimeZone | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/src/tests/test262/built-ins/Temporal/TimeZone')
288 files changed, 8077 insertions, 0 deletions
diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/basic.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/basic.js new file mode 100644 index 0000000000..c92d6c9c48 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/basic.js @@ -0,0 +1,37 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone +description: Basic tests for the Temporal.TimeZone constructor. +features: [Temporal] +---*/ + +const valid = [ + ["+01:00"], + ["-01:00"], + ["+0330", "+03:30"], + ["-0650", "-06:50"], + ["-08", "-08:00"], + ["\u221201:00", "-01:00"], + ["\u22120650", "-06:50"], + ["\u221208", "-08:00"], + ["+01:00:00", "+01:00"], + ["-010000", "-01:00"], + ["+03:30:00.000000001", "+03:30:00.000000001"], + ["-033000.1", "-03:30:00.1"], + ["UTC"], +]; +for (const [zone, id = zone] of valid) { + const result = new Temporal.TimeZone(zone); + assert.sameValue(typeof result, "object", `object should be created for ${zone}`); + assert.sameValue(result.id, id, `id for ${zone} should be ${id}`); +} + +const invalid = ["+00:01.1", "-01.1"]; +for (const zone of invalid) { + assert.throws(RangeError, () => new Temporal.TimeZone(zone), `should throw for ${zone}`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/browser.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/builtin.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/builtin.js new file mode 100644 index 0000000000..dac509ac72 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/builtin.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone +description: Tests that Temporal.TimeZone meets the requirements for built-in objects +info: | + Unless specified otherwise, a built-in object that is callable as a function is a built-in + function object with the characteristics described in 10.3. Unless specified otherwise, the + [[Extensible]] internal slot of a built-in object initially has the value true. + + Unless otherwise specified every built-in function and every built-in constructor has the + Function prototype object [...] as the value of its [[Prototype]] internal slot. +features: [Temporal] +---*/ + +assert.sameValue(Object.isExtensible(Temporal.TimeZone), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.TimeZone), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.TimeZone), + Function.prototype, "prototype"); + +assert.sameValue(typeof Temporal.TimeZone.prototype, + "object", "prototype property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/constructor.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/constructor.js new file mode 100644 index 0000000000..ee80801036 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/constructor.js @@ -0,0 +1,15 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone +description: Temporal.TimeZone constructor cannot be called as a function +info: | + 1. If NewTarget is undefined, throw a TypeError exception. +features: [Temporal] +---*/ + +assert.throws(TypeError, () => Temporal.TimeZone("UTC")); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/from/argument-object-invalid.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/argument-object-invalid.js new file mode 100644 index 0000000000..c9cf7db86c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/argument-object-invalid.js @@ -0,0 +1,14 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.from +description: TimeZone.from() with invalid objects. +features: [Temporal] +---*/ + +assert.throws(RangeError, () => Temporal.TimeZone.from({ timeZone: "local" })); +assert.throws(RangeError, () => Temporal.TimeZone.from({ timeZone: { timeZone: "UTC" } })); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/from/argument-object.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/argument-object.js new file mode 100644 index 0000000000..f32b0b68ed --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/argument-object.js @@ -0,0 +1,51 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.from +description: An object is returned unchanged +features: [Temporal] +---*/ + +class CustomTimeZone extends Temporal.TimeZone {} + +const objects = [ + new Temporal.TimeZone("UTC"), + new CustomTimeZone("UTC"), + {}, + { getPlainDateTimeFor: null }, + { id: "Etc/Custom" }, +]; + +const thisValues = [ + Temporal.TimeZone, + CustomTimeZone, + {}, + null, + undefined, + 7, +]; + +for (const thisValue of thisValues) { + for (const object of objects) { + const result = Temporal.TimeZone.from.call(thisValue, object); + assert.sameValue(result, object); + } + + const zdt = new Temporal.ZonedDateTime(0n, "UTC"); + const fromZdt = Temporal.TimeZone.from.call(thisValue, zdt); + assert.sameValue(fromZdt, zdt.timeZone); + assert.sameValue(fromZdt.id, "UTC"); + + const tz = new Temporal.TimeZone("UTC"); + const fromPropertyBagObject = Temporal.TimeZone.from.call(thisValue, { timeZone: tz }); + assert.sameValue(fromPropertyBagObject, tz); + assert.sameValue(fromPropertyBagObject.id, "UTC"); + + const fromPropertyBagString = Temporal.TimeZone.from.call(thisValue, { timeZone: "UTC" }); + assert(fromPropertyBagString instanceof Temporal.TimeZone); + assert.sameValue(fromPropertyBagString.id, "UTC"); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/from/argument-primitive.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/argument-primitive.js new file mode 100644 index 0000000000..814a94be16 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/argument-primitive.js @@ -0,0 +1,48 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.from +description: RangeError thrown if a value is passed that converts to an invalid string +features: [Temporal] +---*/ + +class CustomTimeZone extends Temporal.TimeZone {} + +const primitives = [ + undefined, + null, + true, + "string", + "local", + "Z", + "-00:00[UTC]", + "+00:01.1", + "-01.1", + "1994-11-05T08:15:30+25:00", + "1994-11-05T13:15:30-25:00", + 7, + 4.2, + 12n, +]; + +const thisValues = [ + Temporal.TimeZone, + CustomTimeZone, + {}, + null, + undefined, + 7, +]; + +for (const thisValue of thisValues) { + for (const primitive of primitives) { + assert.throws(RangeError, () => Temporal.TimeZone.from.call(thisValue, primitive)); + } + + const symbol = Symbol(); + assert.throws(TypeError, () => Temporal.TimeZone.from.call(thisValue, symbol)); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/from/argument-valid.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/argument-valid.js new file mode 100644 index 0000000000..d5d4a9b094 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/argument-valid.js @@ -0,0 +1,37 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.from +description: Built-in time zones are parsed correctly out of valid strings +features: [Temporal] +---*/ + +const valids = [ + ["+01:00"], + ["-01:00"], + ["+0330", "+03:30"], + ["-0650", "-06:50"], + ["-08", "-08:00"], + ["\u221201:00", "-01:00"], + ["\u22120650", "-06:50"], + ["\u221208", "-08:00"], + ["+01:00:00", "+01:00"], + ["-010000", "-01:00"], + ["+03:30:00.000000001", "+03:30:00.000000001"], + ["-033000.1", "-03:30:00.1"], + ["UTC"], + ["1994-11-05T08:15:30-05:00", "-05:00"], + ["1994-11-05T08:15:30\u221205:00", "-05:00"], + ["1994-11-05T13:15:30Z", "UTC"], +]; + +for (const [valid, canonical = valid] of valids) { + const result = Temporal.TimeZone.from(valid); + assert.sameValue(Object.getPrototypeOf(result), Temporal.TimeZone.prototype); + assert.sameValue(result.id, canonical); + assert.sameValue(result.toString(), canonical); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/from/browser.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/from/builtin.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/builtin.js new file mode 100644 index 0000000000..4c961e488c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/builtin.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.from +description: Tests that Temporal.TimeZone.from meets the requirements for built-in objects +info: | + Built-in functions that are not constructors do not have a "prototype" property unless + otherwise specified in the description of a particular function. + + Unless specified otherwise, a built-in object that is callable as a function is a built-in + function object with the characteristics described in 10.3. Unless specified otherwise, the + [[Extensible]] internal slot of a built-in object initially has the value true. + + Unless otherwise specified every built-in function and every built-in constructor has the + Function prototype object [...] as the value of its [[Prototype]] internal slot. +features: [Temporal] +---*/ + +assert.sameValue(Object.isExtensible(Temporal.TimeZone.from), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.TimeZone.from), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.TimeZone.from), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.TimeZone.from.hasOwnProperty("prototype"), + false, "prototype property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/from/length.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/length.js new file mode 100644 index 0000000000..eea90f16d9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/length.js @@ -0,0 +1,28 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.from +description: Temporal.TimeZone.from.length is 1 +info: | + 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: [Temporal] +---*/ + +verifyProperty(Temporal.TimeZone.from, "length", { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/from/name.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/name.js new file mode 100644 index 0000000000..10d0a45f42 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/name.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.from +description: Temporal.TimeZone.from.name is "from" +info: | + 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: [Temporal] +---*/ + +verifyProperty(Temporal.TimeZone.from, "name", { + value: "from", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/from/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/not-a-constructor.js new file mode 100644 index 0000000000..5e15f2d0c9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/not-a-constructor.js @@ -0,0 +1,23 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.from +description: Temporal.TimeZone.from does not implement [[Construct]], is not new-able +info: | + Built-in function objects that are not identified as constructors do not implement the + [[Construct]] internal method unless otherwise specified in the description of a particular + function. +includes: [isConstructor.js] +features: [Reflect.construct, Temporal] +---*/ + +assert.throws(TypeError, () => { + new Temporal.TimeZone.from(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.TimeZone.from), false, + "isConstructor(Temporal.TimeZone.from)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/from/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/prop-desc.js new file mode 100644 index 0000000000..2e9e56cb2a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/prop-desc.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.from +description: The "from" property of Temporal.TimeZone +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.TimeZone.from, + "function", + "`typeof TimeZone.from` is `function`" +); + +verifyProperty(Temporal.TimeZone, "from", { + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/from/shell.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/shell.js new file mode 100644 index 0000000000..eda1477282 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/shell.js @@ -0,0 +1,24 @@ +// GENERATED, DO NOT EDIT +// file: isConstructor.js +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: | + Test if a given function is a constructor function. +defines: [isConstructor] +features: [Reflect.construct] +---*/ + +function isConstructor(f) { + if (typeof f !== "function") { + throw new Test262Error("isConstructor invoked with a non-function value"); + } + + try { + Reflect.construct(function(){}, [], f); + } catch (e) { + return false; + } + return true; +} diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/from/subclassing-ignored.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/subclassing-ignored.js new file mode 100644 index 0000000000..159bc5d1de --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/subclassing-ignored.js @@ -0,0 +1,22 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.from +description: The receiver is never called when calling from() +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +TemporalHelpers.checkSubclassingIgnoredStatic( + Temporal.TimeZone, + "from", + ["UTC"], + (result) => { + assert.sameValue(result.id, "UTC", "id property of result"); + assert.sameValue(result.toString(), "UTC", "toString() of result"); + }, +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/from/timezone-case-insensitive.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/timezone-case-insensitive.js new file mode 100644 index 0000000000..0cef43c4bc --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/timezone-case-insensitive.js @@ -0,0 +1,15 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.from +description: Time zone names are case insensitive +features: [Temporal] +---*/ + +const timeZone = 'UtC'; +const result = Temporal.TimeZone.from(timeZone); +assert.sameValue(result.id, 'UTC', `Time zone created from string "${timeZone}"`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/from/timezone-instance-does-not-get-timeZone-property.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/timezone-instance-does-not-get-timeZone-property.js new file mode 100644 index 0000000000..8969c30850 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/timezone-instance-does-not-get-timeZone-property.js @@ -0,0 +1,23 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.from +description: > + A Temporal.TimeZone instance passed to from() does not have its + 'timeZone' property observably checked +features: [Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +Object.defineProperty(timeZone, "timeZone", { + get() { + throw new Test262Error("timeZone.timeZone should not be accessed"); + }, +}); + +Temporal.TimeZone.from(timeZone); +Temporal.TimeZone.from({ timeZone }); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/from/timezone-string-datetime.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/timezone-string-datetime.js new file mode 100644 index 0000000000..f5dff22629 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/timezone-string-datetime.js @@ -0,0 +1,45 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.from +description: Conversion of ISO date-time strings to Temporal.TimeZone instances +features: [Temporal] +---*/ + +let timeZone = "2021-08-19T17:30"; +assert.throws(RangeError, () => Temporal.TimeZone.from(timeZone), "bare date-time string is not a time zone"); +assert.throws(RangeError, () => Temporal.TimeZone.from({ timeZone }), "bare date-time string is not a time zone"); + +timeZone = "2021-08-19T17:30Z"; +const result1 = Temporal.TimeZone.from(timeZone); +assert.sameValue(result1.id, "UTC", "date-time + Z is UTC time zone"); +const result2 = Temporal.TimeZone.from({ timeZone }); +assert.sameValue(result2.id, "UTC", "date-time + Z is UTC time zone (string in property bag)"); + +timeZone = "2021-08-19T17:30-07:00"; +const result3 = Temporal.TimeZone.from(timeZone); +assert.sameValue(result3.id, "-07:00", "date-time + offset is the offset time zone"); +const result4 = Temporal.TimeZone.from({ timeZone }); +assert.sameValue(result4.id, "-07:00", "date-time + offset is the offset time zone (string in property bag)"); + +timeZone = "2021-08-19T17:30[UTC]"; +const result5 = Temporal.TimeZone.from(timeZone); +assert.sameValue(result5.id, "UTC", "date-time + IANA annotation is the IANA time zone"); +const result6 = Temporal.TimeZone.from({ timeZone }); +assert.sameValue(result6.id, "UTC", "date-time + IANA annotation is the IANA time zone (string in property bag)"); + +timeZone = "2021-08-19T17:30Z[UTC]"; +const result7 = Temporal.TimeZone.from(timeZone); +assert.sameValue(result7.id, "UTC", "date-time + Z + IANA annotation is the IANA time zone"); +const result8 = Temporal.TimeZone.from({ timeZone }); +assert.sameValue(result8.id, "UTC", "date-time + Z + IANA annotation is the IANA time zone (string in property bag)"); + +timeZone = "2021-08-19T17:30-07:00[UTC]"; +const result9 = Temporal.TimeZone.from(timeZone); +assert.sameValue(result9.id, "UTC", "date-time + offset + IANA annotation is the IANA time zone"); +const result10 = Temporal.TimeZone.from({ timeZone }); +assert.sameValue(result10.id, "UTC", "date-time + offset + IANA annotation is the IANA time zone (string in property bag)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/from/timezone-string-leap-second.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/timezone-string-leap-second.js new file mode 100644 index 0000000000..d28b4c58b9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/timezone-string-leap-second.js @@ -0,0 +1,22 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.from +description: Leap second is a valid ISO string for TimeZone +features: [Temporal] +---*/ + +let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; + +const result1 = Temporal.TimeZone.from(timeZone); +assert.sameValue(result1.id, "UTC", "leap second is a valid ISO string for TimeZone"); +const result2 = Temporal.TimeZone.from({ timeZone }); +assert.sameValue(result2.id, "UTC", "leap second is a valid ISO string for TimeZone (nested property)"); + +timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; +assert.throws(RangeError, () => Temporal.TimeZone.from(timeZone), "leap second in time zone name not valid"); +assert.throws(RangeError, () => Temporal.TimeZone.from({ timeZone }), "leap second in time zone name not valid (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/from/timezone-string-multiple-offsets.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/timezone-string-multiple-offsets.js new file mode 100644 index 0000000000..8b4c6693bd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/timezone-string-multiple-offsets.js @@ -0,0 +1,18 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.from +description: Time zone strings with UTC offset fractional part are not confused with time fractional part +features: [Temporal] +---*/ + +const timeZone = "2021-08-19T17:30:45.123456789+01:46[+01:45:30.987654321]"; + +const result1 = Temporal.TimeZone.from(timeZone); +assert.sameValue(result1.id, "+01:45:30.987654321", "Time zone string determined from bracket name"); +const result2 = Temporal.TimeZone.from({ timeZone }); +assert.sameValue(result2.id, "+01:45:30.987654321", "Time zone string determined from bracket name"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/from/timezone-string-year-zero.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/timezone-string-year-zero.js new file mode 100644 index 0000000000..8f53321f36 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/timezone-string-year-zero.js @@ -0,0 +1,28 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.from +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+00:00[UTC]", +]; +invalidStrings.forEach((timeZone) => { + assert.throws( + RangeError, + () => Temporal.TimeZone.from(timeZone), + "reject minus zero as extended year" + ); + assert.throws( + RangeError, + () => Temporal.TimeZone.from({ timeZone }), + "reject minus zero as extended year (nested property)" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/from/timezone-string.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/timezone-string.js new file mode 100644 index 0000000000..23ade0107b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/timezone-string.js @@ -0,0 +1,16 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.from +description: Time zone IDs are valid input for a time zone +features: [Temporal] +---*/ + +["UTC", "+01:30"].forEach((timeZone) => { + const result = Temporal.TimeZone.from(timeZone); + assert.sameValue(result.id, timeZone, `Time zone created from string "${timeZone}"`); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/from/timezone-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/timezone-wrong-type.js new file mode 100644 index 0000000000..de8b879960 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/timezone-wrong-type.js @@ -0,0 +1,40 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.from +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for TimeZone +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], + [new Temporal.Calendar("iso8601"), "calendar instance"], +]; + +for (const [timeZone, description] of rangeErrorTests) { + assert.throws(RangeError, () => Temporal.TimeZone.from(timeZone), `${description} does not convert to a valid ISO string`); + assert.throws(RangeError, () => Temporal.TimeZone.from({ timeZone }), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [timeZone, description] of typeErrorTests) { + assert.throws(TypeError, () => Temporal.TimeZone.from(timeZone), `${description} is not a valid object and does not convert to a string`); + assert.throws(TypeError, () => Temporal.TimeZone.from({ timeZone }), `${description} is not a valid object and does not convert to a string (nested property)`); +} + +const timeZone = undefined; +assert.throws(RangeError, () => Temporal.TimeZone.from({ timeZone }), `undefined is always a RangeError as nested property`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/length.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/length.js new file mode 100644 index 0000000000..104589025d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/length.js @@ -0,0 +1,28 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone +description: Temporal.TimeZone.length is 1 +info: | + 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: [Temporal] +---*/ + +verifyProperty(Temporal.TimeZone, "length", { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/missing-arguments.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/missing-arguments.js new file mode 100644 index 0000000000..cb0e8d07e3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/missing-arguments.js @@ -0,0 +1,14 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone +description: RangeError thrown when constructor invoked with no argument +features: [Temporal] +---*/ + +assert.throws(RangeError, () => new Temporal.TimeZone()); +assert.throws(RangeError, () => new Temporal.TimeZone(undefined)); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/name.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/name.js new file mode 100644 index 0000000000..ab2fd88203 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/name.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone +description: Temporal.TimeZone.name is "TimeZone" +info: | + 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: [Temporal] +---*/ + +verifyProperty(Temporal.TimeZone, "name", { + value: "TimeZone", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prop-desc.js new file mode 100644 index 0000000000..afe5731f3a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prop-desc.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone +description: The "TimeZone" property of Temporal +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.TimeZone, + "function", + "`typeof TimeZone` is `function`" +); + +verifyProperty(Temporal, "TimeZone", { + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/browser.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/constructor.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/constructor.js new file mode 100644 index 0000000000..b61097db22 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/constructor.js @@ -0,0 +1,20 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.constructor +description: Test for Temporal.TimeZone.prototype.constructor. +info: The initial value of Temporal.TimeZone.prototype.constructor is %Temporal.TimeZone%. +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +verifyProperty(Temporal.TimeZone.prototype, "constructor", { + value: Temporal.TimeZone, + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-not-datetime.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-not-datetime.js new file mode 100644 index 0000000000..0f6f7205f1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-not-datetime.js @@ -0,0 +1,21 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: Appropriate error thrown when argument cannot be converted to Temporal.PlainDateTime +features: [Temporal] +---*/ + +const timeZone = Temporal.TimeZone.from("UTC"); +assert.throws(RangeError, () => timeZone.getInstantFor(undefined), "undefined"); +assert.throws(RangeError, () => timeZone.getInstantFor(null), "null"); +assert.throws(RangeError, () => timeZone.getInstantFor(true), "boolean"); +assert.throws(RangeError, () => timeZone.getInstantFor(""), "empty string"); +assert.throws(TypeError, () => timeZone.getInstantFor(Symbol()), "Symbol"); +assert.throws(RangeError, () => timeZone.getInstantFor(5), "number"); +assert.throws(RangeError, () => timeZone.getInstantFor(5n), "bigint"); +assert.throws(TypeError, () => timeZone.getInstantFor({ year: 2020 }), "plain object"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-number.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-number.js new file mode 100644 index 0000000000..aa44a13264 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-number.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: A number is converted to a string, then to Temporal.PlainDateTime +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +let arg = 19761118; + +const result = instance.getInstantFor(arg); +assert.sameValue(result.epochNanoseconds, 217_123_200_000_000_000n, "19761118 is a valid ISO string for PlainDateTime"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.getInstantFor(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDateTime` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-plaindate.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-plaindate.js new file mode 100644 index 0000000000..8fd29130dc --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-plaindate.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: Fast path for converting Temporal.PlainDate to Temporal.PlainDateTime by reading internal slots +info: | + sec-temporal.timezone.prototype.getinstantfor step 3: + 3. Set _dateTime_ to ? ToTemporalDateTime(_dateTime_). + sec-temporal-totemporaldatetime step 2.b: + b. If _item_ has an [[InitializedTemporalDate]] internal slot, then + i. Return ? CreateTemporalDateTime(_item_.[[ISOYear]], _item_.[[ISOMonth]], _item_.[[ISODay]], 0, 0, 0, 0, 0, 0, _item_.[[Calendar]]). +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +TemporalHelpers.checkToTemporalPlainDateTimeFastPath((date) => { + const timezone = new Temporal.TimeZone("UTC"); + const result = timezone.getInstantFor(date); + assert.sameValue(result.epochNanoseconds, 957_225_600_000_000_000n, "epochNanoseconds result"); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-case-insensitive.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-case-insensitive.js new file mode 100644 index 0000000000..4c94c62aca --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-case-insensitive.js @@ -0,0 +1,23 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: The calendar name is case-insensitive +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const calendar = "IsO8601"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.getInstantFor(arg); +assert.sameValue(result1.epochNanoseconds, 217_123_200_000_000_000n, "Calendar is case-insensitive"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.getInstantFor(arg); +assert.sameValue(result2.epochNanoseconds, 217_123_200_000_000_000n, "Calendar is case-insensitive (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-instance-does-not-get-calendar-property.js new file mode 100644 index 0000000000..47c1b978e0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-instance-does-not-get-calendar-property.js @@ -0,0 +1,28 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: > + A Temporal.Calendar instance passed to getInstantFor() in a property bag does + not have its 'calendar' property observably checked +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const calendar = new Temporal.Calendar("iso8601"); +Object.defineProperty(calendar, "calendar", { + get() { + throw new Test262Error("calendar.calendar should not be accessed"); + }, +}); + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +instance.getInstantFor(arg); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +instance.getInstantFor(arg); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-leap-second.js new file mode 100644 index 0000000000..1de3bedd7a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,31 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.getInstantFor(arg); +assert.sameValue( + result1.epochNanoseconds, + 217_123_200_000_000_000n, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.getInstantFor(arg); +assert.sameValue( + result2.epochNanoseconds, + 217_123_200_000_000_000n, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-number.js new file mode 100644 index 0000000000..dad8b8a66b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-number.js @@ -0,0 +1,44 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.getInstantFor(arg); +assert.sameValue(result1.epochNanoseconds, 217_123_200_000_000_000n, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.getInstantFor(arg); +assert.sameValue(result2.epochNanoseconds, 217_123_200_000_000_000n, "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + assert.throws( + RangeError, + () => instance.getInstantFor(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.getInstantFor(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-string.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-string.js new file mode 100644 index 0000000000..bb725d603d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-string.js @@ -0,0 +1,19 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: A calendar ID is valid input for Calendar +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const calendar = "iso8601"; + +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.getInstantFor(arg); +assert.sameValue(result.epochNanoseconds, 217_123_200_000_000_000n, `Calendar created from string "${calendar}"`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 0000000000..3455ef686c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.TimeZone("UTC"); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.getInstantFor(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.getInstantFor(arg), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.getInstantFor(arg), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.getInstantFor(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.getInstantFor(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-year-zero.js new file mode 100644 index 0000000000..26303205c5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.TimeZone("UTC"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.getInstantFor(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-string-calendar-annotation.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-string-calendar-annotation.js new file mode 100644 index 0000000000..b73ebd9dab --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-string-calendar-annotation.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: Various forms of calendar annotation; critical flag has no effect +features: [Temporal] +---*/ + +const tests = [ + ["1976-11-18T15:23[u-ca=iso8601]", "without time zone"], + ["1976-11-18T15:23[UTC][u-ca=iso8601]", "with time zone"], + ["1976-11-18T15:23[!u-ca=iso8601]", "with ! and no time zone"], + ["1976-11-18T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], + ["1976-11-18T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], + ["1976-11-18T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], +]; + +const instance = new Temporal.TimeZone("UTC"); + +tests.forEach(([arg, description]) => { + const result = instance.getInstantFor(arg); + + assert.sameValue( + result.epochNanoseconds, + 217_178_580_000_000_000n, + `calendar annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-string-critical-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-string-critical-unknown-annotation.js new file mode 100644 index 0000000000..61e7bac72f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-string-critical-unknown-annotation.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: Unknown annotations with critical flag are rejected +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01T00:00[!foo=bar]", + "1970-01-01T00:00[UTC][!foo=bar]", + "1970-01-01T00:00[u-ca=iso8601][!foo=bar]", + "1970-01-01T00:00[UTC][!foo=bar][u-ca=iso8601]", + "1970-01-01T00:00[foo=bar][!_foo-bar0=Dont-Ignore-This-99999999999]", +]; +const instance = new Temporal.TimeZone("UTC"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.getInstantFor(arg), + `reject unknown annotation with critical flag: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-string-date-with-utc-offset.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-string-date-with-utc-offset.js new file mode 100644 index 0000000000..61906eddb7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-string-date-with-utc-offset.js @@ -0,0 +1,48 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: UTC offset not valid with format that does not include a time +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const validStrings = [ + "1976-11-18T15:23+00:00", + "1976-11-18T15:23+00:00[UTC]", + "1976-11-18T15:23+00:00[!UTC]", + "1976-11-18T15:23-02:30[America/St_Johns]", +]; + +for (const arg of validStrings) { + const result = instance.getInstantFor(arg); + + assert.sameValue( + result.epochNanoseconds, + 217_178_580_000_000_000n, + `"${arg}" is a valid UTC offset with time for PlainDateTime` + ); +} + +const invalidStrings = [ + "2022-09-15Z", + "2022-09-15Z[UTC]", + "2022-09-15Z[Europe/Vienna]", + "2022-09-15+00:00", + "2022-09-15+00:00[UTC]", + "2022-09-15-02:30", + "2022-09-15-02:30[America/St_Johns]", +]; + +for (const arg of invalidStrings) { + assert.throws( + RangeError, + () => instance.getInstantFor(arg), + `"${arg}" UTC offset without time is not valid for PlainDateTime` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-string-multiple-time-zone.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-string-multiple-time-zone.js new file mode 100644 index 0000000000..2b5a2f5506 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-string-multiple-time-zone.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: More than one time zone annotation is not syntactical +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01T00:00[UTC][UTC]", + "1970-01-01T00:00[!UTC][UTC]", + "1970-01-01T00:00[UTC][!UTC]", + "1970-01-01T00:00[UTC][u-ca=iso8601][UTC]", + "1970-01-01T00:00[UTC][foo=bar][UTC]", +]; +const instance = new Temporal.TimeZone("UTC"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.getInstantFor(arg), + `reject more than one time zone annotation: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-string-time-separators.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-string-time-separators.js new file mode 100644 index 0000000000..40835e2e8b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-string-time-separators.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: Time separator in string argument can vary +features: [Temporal] +---*/ + +const tests = [ + ["1976-11-18T15:23", "uppercase T"], + ["1976-11-18t15:23", "lowercase T"], + ["1976-11-18 15:23", "space between date and time"], +]; + +const instance = new Temporal.TimeZone("UTC"); + +tests.forEach(([arg, description]) => { + const result = instance.getInstantFor(arg); + + assert.sameValue( + result.epochNanoseconds, + 217_178_580_000_000_000n, + `variant time separators (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-string-time-zone-annotation.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-string-time-zone-annotation.js new file mode 100644 index 0000000000..37cb390128 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-string-time-zone-annotation.js @@ -0,0 +1,34 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: Various forms of time zone annotation; critical flag has no effect +features: [Temporal] +---*/ + +const tests = [ + ["1976-11-18T15:23[Asia/Kolkata]", "named, with no offset"], + ["1976-11-18T15:23[!Europe/Vienna]", "named, with ! and no offset"], + ["1976-11-18T15:23[+00:00]", "numeric, with no offset"], + ["1976-11-18T15:23[!-02:30]", "numeric, with ! and no offset"], + ["1976-11-18T15:23+00:00[UTC]", "named, with offset"], + ["1976-11-18T15:23+00:00[!Africa/Abidjan]", "named, with offset and !"], + ["1976-11-18T15:23+00:00[+01:00]", "numeric, with offset"], + ["1976-11-18T15:23+00:00[!-08:00]", "numeric, with offset and !"], +]; + +const instance = new Temporal.TimeZone("UTC"); + +tests.forEach(([arg, description]) => { + const result = instance.getInstantFor(arg); + + assert.sameValue( + result.epochNanoseconds, + 217_178_580_000_000_000n, + `time zone annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-string-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-string-unknown-annotation.js new file mode 100644 index 0000000000..87e98bfd39 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-string-unknown-annotation.js @@ -0,0 +1,31 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: Various forms of unknown annotation +features: [Temporal] +---*/ + +const tests = [ + ["1976-11-18T15:23[foo=bar]", "alone"], + ["1976-11-18T15:23[UTC][foo=bar]", "with time zone"], + ["1976-11-18T15:23[u-ca=iso8601][foo=bar]", "with calendar"], + ["1976-11-18T15:23[UTC][foo=bar][u-ca=iso8601]", "with time zone and calendar"], + ["1976-11-18T15:23[foo=bar][_foo-bar0=Ignore-This-999999999999]", "with another unknown annotation"], +]; + +const instance = new Temporal.TimeZone("UTC"); + +tests.forEach(([arg, description]) => { + const result = instance.getInstantFor(arg); + + assert.sameValue( + result.epochNanoseconds, + 217_178_580_000_000_000n, + `unknown annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-string-with-utc-designator.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-string-with-utc-designator.js new file mode 100644 index 0000000000..d1d8bf36b2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-string-with-utc-designator.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: RangeError thrown if a string with UTC designator is used as a PlainDateTime +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "2019-10-01T09:00:00Z", + "2019-10-01T09:00:00Z[UTC]", +]; +const instance = new Temporal.TimeZone("UTC"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.getInstantFor(arg), + "String with UTC designator should not be valid as a PlainDateTime" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-wrong-type.js new file mode 100644 index 0000000000..b7b49c2876 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDateTime +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.getInstantFor(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDateTime, "Temporal.PlainDateTime, object"], + [Temporal.PlainDateTime.prototype, "Temporal.PlainDateTime.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.getInstantFor(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-zoneddatetime-balance-negative-time-units.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-zoneddatetime-balance-negative-time-units.js new file mode 100644 index 0000000000..a675238fcd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-zoneddatetime-balance-negative-time-units.js @@ -0,0 +1,46 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: Negative time fields are balanced upwards if the argument is given as ZonedDateTime +info: | + sec-temporal-balancetime steps 3–14: + 3. Set _microsecond_ to _microsecond_ + floor(_nanosecond_ / 1000). + 4. Set _nanosecond_ to _nanosecond_ modulo 1000. + 5. Set _millisecond_ to _millisecond_ + floor(_microsecond_ / 1000). + 6. Set _microsecond_ to _microsecond_ modulo 1000. + 7. Set _second_ to _second_ + floor(_millisecond_ / 1000). + 8. Set _millisecond_ to _millisecond_ modulo 1000. + 9. Set _minute_ to _minute_ + floor(_second_ / 60). + 10. Set _second_ to _second_ modulo 60. + 11. Set _hour_ to _hour_ + floor(_minute_ / 60). + 12. Set _minute_ to _minute_ modulo 60. + 13. Let _days_ be floor(_hour_ / 24). + 14. Set _hour_ to _hour_ modulo 24. + sec-temporal-balanceisodatetime step 1: + 1. Let _balancedTime_ be ? BalanceTime(_hour_, _minute_, _second_, _millisecond_, _microsecond_, _nanosecond_). + sec-temporal-builtintimezonegetplaindatetimefor step 3: + 3. Set _result_ to ? BalanceISODateTime(_result_.[[Year]], _result_.[[Month]], _result_.[[Day]], _result_.[[Hour]], _result_.[[Minute]], _result_.[[Second]], _result_.[[Millisecond]], _result_.[[Microsecond]], _result_.[[Nanosecond]] + _offsetNanoseconds_). + sec-temporal-totemporaldatetime step 3.b: + b. If _item_ has an [[InitializedTemporalZonedDateTime]] internal slot, then + ... + ii. 1. Return ? BuiltinTimeZoneGetPlainDateTimeFor(_item_.[[TimeZone]], _instant_, _item_.[[Calendar]]). + sec-temporal.timezone.prototype.getinstantfor step 3: + 3. Set _dateTime_ ? ToTemporalDateTime(_dateTime_). +features: [Temporal] +---*/ + +// This code path is encountered if the time zone offset is negative and its +// absolute value in nanoseconds is greater than the nanosecond field of the +// exact time's epoch parts +const tz = new Temporal.TimeZone("-00:00:00.000000002"); +const datetime = new Temporal.ZonedDateTime(3661_001_001_001n, tz); + +const conversionTimeZone = new Temporal.TimeZone("UTC"); // should not be used to interpret the argument +const instant = conversionTimeZone.getInstantFor(datetime); + +assert.sameValue(instant.epochNanoseconds, 3661_001_000_999n); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-zoneddatetime-negative-epochnanoseconds.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-zoneddatetime-negative-epochnanoseconds.js new file mode 100644 index 0000000000..28519c78f4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-zoneddatetime-negative-epochnanoseconds.js @@ -0,0 +1,25 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: A pre-epoch value is handled correctly by the modulo operation in GetISOPartsFromEpoch +info: | + sec-temporal-getisopartsfromepoch step 1: + 1. Let _remainderNs_ be the mathematical value whose sign is the sign of _epochNanoseconds_ and whose magnitude is abs(_epochNanoseconds_) modulo 10<sup>6</sup>. + sec-temporal-builtintimezonegetplaindatetimefor step 2: + 2. Let _result_ be ! GetISOPartsFromEpoch(_instant_.[[Nanoseconds]]). +features: [Temporal] +---*/ + +const datetime = new Temporal.ZonedDateTime(-13849764_999_999_999n, "UTC"); + +// This code path shows up anywhere we convert an exact time, before the Unix +// epoch, with nonzero microseconds or nanoseconds, into a wall time. + +const instance = new Temporal.TimeZone("UTC"); +const result = instance.getInstantFor(datetime); +assert.sameValue(result.epochNanoseconds, -13849764_999_999_999n); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js new file mode 100644 index 0000000000..692df372bd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js @@ -0,0 +1,19 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: RangeError thrown if time zone reports an offset that is not an integer number of nanoseconds +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +[3600_000_000_000.5, NaN, -Infinity, Infinity].forEach((wrongOffset) => { + const timeZone = TemporalHelpers.specificOffsetTimeZone(wrongOffset); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + const builtinTimeZone = new Temporal.TimeZone("UTC"); + assert.throws(RangeError, () => builtinTimeZone.getInstantFor(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js new file mode 100644 index 0000000000..dc7e23df25 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js @@ -0,0 +1,23 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: TypeError thrown if timeZone.getOffsetNanosecondsFor is not callable +features: [BigInt, Symbol, Temporal, arrow-function] +---*/ + +[undefined, null, true, Math.PI, 'string', Symbol('sym'), 42n, {}].forEach((notCallable) => { + const timeZone = new Temporal.TimeZone("UTC"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + const builtinTimeZone = new Temporal.TimeZone("UTC"); + timeZone.getOffsetNanosecondsFor = notCallable; + assert.throws( + TypeError, + () => builtinTimeZone.getInstantFor(datetime), + `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js new file mode 100644 index 0000000000..1047793714 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js @@ -0,0 +1,19 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: RangeError thrown if time zone reports an offset that is out of range +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +[-86400_000_000_000, 86400_000_000_000].forEach((wrongOffset) => { + const timeZone = TemporalHelpers.specificOffsetTimeZone(wrongOffset); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + const builtinTimeZone = new Temporal.TimeZone("UTC"); + assert.throws(RangeError, () => builtinTimeZone.getInstantFor(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js new file mode 100644 index 0000000000..889712d4e3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js @@ -0,0 +1,28 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: TypeError thrown if time zone reports an offset that is not a Number +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +[ + undefined, + null, + true, + "+01:00", + Symbol(), + 3600_000_000_000n, + {}, + { valueOf() { return 3600_000_000_000; } }, +].forEach((wrongOffset) => { + const timeZone = TemporalHelpers.specificOffsetTimeZone(wrongOffset); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + const builtinTimeZone = new Temporal.TimeZone("UTC"); + assert.throws(TypeError, () => builtinTimeZone.getInstantFor(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/balance-negative-time-units.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/balance-negative-time-units.js new file mode 100644 index 0000000000..122b502b3d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/balance-negative-time-units.js @@ -0,0 +1,48 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: Negative time fields are balanced upwards +info: | + sec-temporal-balancetime steps 3–14: + 3. Set _microsecond_ to _microsecond_ + floor(_nanosecond_ / 1000). + 4. Set _nanosecond_ to _nanosecond_ modulo 1000. + 5. Set _millisecond_ to _millisecond_ + floor(_microsecond_ / 1000). + 6. Set _microsecond_ to _microsecond_ modulo 1000. + 7. Set _second_ to _second_ + floor(_millisecond_ / 1000). + 8. Set _millisecond_ to _millisecond_ modulo 1000. + 9. Set _minute_ to _minute_ + floor(_second_ / 60). + 10. Set _second_ to _second_ modulo 60. + 11. Set _hour_ to _hour_ + floor(_minute_ / 60). + 12. Set _minute_ to _minute_ modulo 60. + 13. Let _days_ be floor(_hour_ / 24). + 14. Set _hour_ to _hour_ modulo 24. + sec-temporal-addtime step 8: + 8. Return ? BalanceTime(_hour_, _minute_, _second_, _millisecond_, _microsecond_, _nanosecond_). + sec-temporal-adddatetime step 1: + 1. Let _timeResult_ be ? AddTime(_hour_, _minute_, _second_, _millisecond_, _microsecond_, _nanosecond_, _hours_, _minutes_, _seconds_, _milliseconds_, _microseconds_, _nanoseconds_). + sec-temporal-builtintimezonegetinstantfor step 13.a: + a. Let _earlier_ be ? AddDateTime(_dateTime_.[[ISOYear]], _dateTime_.[[ISOMonth]], _dateTime_.[[ISODay]], _dateTime_.[[ISOHour]], _dateTime_.[[ISOMinute]], _dateTime_.[[ISOSecond]], _dateTime_.[[ISOMillisecond]], _dateTime_.[[ISOMicrosecond]], _dateTime_.[[ISONanosecond]], 0, 0, 0, 0, 0, 0, 0, 0, 0, −_nanoseconds_, *"constrain"*). + sec-temporal.timezone.prototype.getinstantfor step 6: + 6. Return ? BuiltinTimeZoneGetInstantFor(_timeZone_, _dateTime_, _disambiguation_). +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const shiftInstant = new Temporal.Instant(3661_001_001_001n); +const tz = TemporalHelpers.oneShiftTimeZone(shiftInstant, 2); +const datetime = new Temporal.PlainDateTime(1970, 1, 1, 1, 1, 1, 1, 1, 1); + +// This code path is encountered if disambiguation is `earlier` and the shift is +// a spring-forward change +tz.getInstantFor(datetime, { disambiguation: "earlier" }); + +const expected = [ + "1970-01-01T01:01:01.001001001", + "1970-01-01T01:01:01.001000999", +]; +assert.compareArray(tz.getPossibleInstantsForCalledWith, expected); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/branding.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/branding.js new file mode 100644 index 0000000000..7559ad528d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/branding.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const getInstantFor = Temporal.TimeZone.prototype.getInstantFor; + +assert.sameValue(typeof getInstantFor, "function"); + +const args = [new Temporal.PlainDateTime(2022, 6, 22)]; + +assert.throws(TypeError, () => getInstantFor.apply(undefined, args), "undefined"); +assert.throws(TypeError, () => getInstantFor.apply(null, args), "null"); +assert.throws(TypeError, () => getInstantFor.apply(true, args), "true"); +assert.throws(TypeError, () => getInstantFor.apply("", args), "empty string"); +assert.throws(TypeError, () => getInstantFor.apply(Symbol(), args), "symbol"); +assert.throws(TypeError, () => getInstantFor.apply(1, args), "1"); +assert.throws(TypeError, () => getInstantFor.apply({}, args), "plain object"); +assert.throws(TypeError, () => getInstantFor.apply(Temporal.TimeZone, args), "Temporal.TimeZone"); +assert.throws(TypeError, () => getInstantFor.apply(Temporal.TimeZone.prototype, args), "Temporal.TimeZone.prototype"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/browser.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/builtin.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/builtin.js new file mode 100644 index 0000000000..04fa262fdd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/builtin.js @@ -0,0 +1,36 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: > + Tests that Temporal.TimeZone.prototype.getInstantFor + meets the requirements for built-in objects defined by the + introduction of chapter 17 of the ECMAScript Language Specification. +info: | + Built-in functions that are not constructors do not have a "prototype" property unless + otherwise specified in the description of a particular function. + + Unless specified otherwise, a built-in object that is callable as a function is a built-in + function object with the characteristics described in 10.3. Unless specified otherwise, the + [[Extensible]] internal slot of a built-in object initially has the value true. + + Unless otherwise specified every built-in function and every built-in constructor has the + Function prototype object [...] as the value of its [[Prototype]] internal slot. +features: [Temporal] +---*/ + +assert.sameValue(Object.isExtensible(Temporal.TimeZone.prototype.getInstantFor), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.TimeZone.prototype.getInstantFor), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.TimeZone.prototype.getInstantFor), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.TimeZone.prototype.getInstantFor.hasOwnProperty("prototype"), + false, "prototype property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/calendar-dateadd-called-with-options-undefined.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/calendar-dateadd-called-with-options-undefined.js new file mode 100644 index 0000000000..534d4f3606 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/calendar-dateadd-called-with-options-undefined.js @@ -0,0 +1,25 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: > + BuiltinTimeZoneGetInstantFor calls Calendar.dateAdd with undefined as the + options value +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = TemporalHelpers.calendarDateAddUndefinedOptions(); +const timeZone = TemporalHelpers.oneShiftTimeZone(new Temporal.Instant(0n), 3600e9); +const pdt = new Temporal.PlainDateTime(1970, 1, 1, 0, 0, 0, 0, 0, 0, calendar); + +["earlier", "compatible", "later"].forEach((disambiguation) => { + calendar.dateAddCallCount = 0; + + timeZone.getInstantFor(pdt, { disambiguation }); + assert.sameValue(calendar.dateAddCallCount, 1, `calling with disambiguation ${disambiguation}`); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/calendar-datefromfields-called-with-null-prototype-fields.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/calendar-datefromfields-called-with-null-prototype-fields.js new file mode 100644 index 0000000000..f1de0b562b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/calendar-datefromfields-called-with-null-prototype-fields.js @@ -0,0 +1,19 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: > + Calendar.dateFromFields method is called with a null-prototype fields object +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = TemporalHelpers.calendarCheckFieldsPrototypePollution(); +const instance = new Temporal.TimeZone("UTC"); +const arg = { year: 2000, month: 5, day: 2, calendar }; +instance.getInstantFor(arg); +assert.sameValue(calendar.dateFromFieldsCallCount, 1, "dateFromFields should be called on the property bag's calendar"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/calendar-fields-iterable.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/calendar-fields-iterable.js new file mode 100644 index 0000000000..7df5f51aec --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/calendar-fields-iterable.js @@ -0,0 +1,40 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: Verify the result of calendar.fields() is treated correctly. +info: | + sec-temporal.timezone.prototype.getinstantfor step 3: + 3. Set _dateTime_ to ? ToTemporalDateTime(_dateTime_). + sec-temporal-totemporaldatetime step 2.c: + c. Let _fieldNames_ be ? CalendarFields(_calendar_, « *"day"*, *"hour"*, *"microsecond"*, *"millisecond"*, *"minute"*, *"month"*, *"monthCode"*, *"nanosecond"*, *"second"*, *"year"* »). + sec-temporal-calendarfields step 4: + 4. Let _result_ be ? IterableToList(_fieldsArray_). +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + "day", + "hour", + "microsecond", + "millisecond", + "minute", + "month", + "monthCode", + "nanosecond", + "second", + "year", +]; + +const calendar = TemporalHelpers.calendarFieldsIterable(); +const timeZone = new Temporal.TimeZone("UTC"); +timeZone.getInstantFor({ year: 2000, month: 5, day: 2, calendar }); + +assert.sameValue(calendar.fieldsCallCount, 1, "fields() method called once"); +assert.compareArray(calendar.fieldsCalledWith[0], expected, "fields() method called with correct args"); +assert(calendar.iteratorExhausted[0], "iterated through the whole iterable"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/calendar-temporal-object.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/calendar-temporal-object.js new file mode 100644 index 0000000000..1a99d7eebf --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/calendar-temporal-object.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots +info: | + sec-temporal.timezone.prototype.getinstantfor step 3: + 3. Set _dateTime_ to ? ToTemporalDateTime(_dateTime_). + sec-temporal-totemporaldatetime step 2.c: + c. Let _calendar_ be ? GetTemporalCalendarWithISODefault(_item_). + sec-temporal-gettemporalcalendarwithisodefault step 2: + 2. Return ? ToTemporalCalendarWithISODefault(_calendar_). + sec-temporal-totemporalcalendarwithisodefault step 2: + 3. Return ? ToTemporalCalendar(_temporalCalendarLike_). + sec-temporal-totemporalcalendar step 1.a: + a. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then + i. Return _temporalCalendarLike_.[[Calendar]]. +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +TemporalHelpers.checkToTemporalCalendarFastPath((temporalObject) => { + const timeZone = new Temporal.TimeZone("UTC"); + timeZone.getInstantFor({ year: 2000, month: 5, day: 2, calendar: temporalObject }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/disambiguation-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/disambiguation-invalid-string.js new file mode 100644 index 0000000000..486928a675 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/disambiguation-invalid-string.js @@ -0,0 +1,22 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: RangeError thrown when disambiguation option not one of the allowed string values +info: | + sec-getoption step 10: + 10. If _values_ is not *undefined* and _values_ does not contain an element equal to _value_, throw a *RangeError* exception. + sec-temporal-totemporaldisambiguation step 1: + 1. Return ? GetOption(_normalizedOptions_, *"disambiguation"*, « String », « *"compatible"*, *"earlier"*, *"later"*, *"reject"* », *"compatible"*). + sec-temporal.timezone.prototype.getinstantfor step 5: + 5. Let _disambiguation_ be ? ToTemporalDisambiguation(_options_). +features: [Temporal] +---*/ + +const datetime = new Temporal.PlainDateTime(2001, 9, 9, 1, 46, 40, 987, 654, 321); +const timeZone = new Temporal.TimeZone("UTC"); +assert.throws(RangeError, () => timeZone.getInstantFor(datetime, { disambiguation: "other string" })); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/disambiguation-undefined.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/disambiguation-undefined.js new file mode 100644 index 0000000000..5d5562d208 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/disambiguation-undefined.js @@ -0,0 +1,35 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: Fallback value for disambiguation option +info: | + sec-getoption step 3: + 3. If _value_ is *undefined*, return _fallback_. + sec-temporal-totemporaldisambiguation step 1: + 1. Return ? GetOption(_normalizedOptions_, *"disambiguation"*, « String », « *"compatible"*, *"earlier"*, *"later"*, *"reject"* », *"compatible"*). + sec-temporal.timezone.prototype.getinstantfor step 5: + 5. Let _disambiguation_ be ? ToTemporalDisambiguation(_options_). +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const timeZone = TemporalHelpers.springForwardFallBackTimeZone(); +const springForwardDateTime = new Temporal.PlainDateTime(2000, 4, 2, 2, 30); +const fallBackDateTime = new Temporal.PlainDateTime(2000, 10, 29, 1, 30); + +[ + [springForwardDateTime, 954671400_000_000_000n], + [fallBackDateTime, 972808200_000_000_000n], +].forEach(([datetime, expected]) => { + const explicit = timeZone.getInstantFor(datetime, { disambiguation: undefined }); + assert.sameValue(explicit.epochNanoseconds, expected, "default disambiguation is compatible"); + const implicit = timeZone.getInstantFor(datetime, {}); + assert.sameValue(implicit.epochNanoseconds, expected, "default disambiguation is compatible"); + const lambda = timeZone.getInstantFor(datetime, () => {}); + assert.sameValue(lambda.epochNanoseconds, expected, "default disambiguation is compatible"); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/disambiguation-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/disambiguation-wrong-type.js new file mode 100644 index 0000000000..de79fec20b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/disambiguation-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: Type conversions for disambiguation option +info: | + sec-getoption step 9.a: + a. Set _value_ to ? ToString(_value_). + sec-temporal-totemporaldisambiguation step 1: + 1. Return ? GetOption(_normalizedOptions_, *"disambiguation"*, « String », « *"compatible"*, *"earlier"*, *"later"*, *"reject"* », *"compatible"*). + sec-temporal.timezone.prototype.getinstantfor step 5: + 5. Let _disambiguation_ be ? ToTemporalDisambiguation(_options_). +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const datetime = new Temporal.PlainDateTime(2001, 9, 9, 1, 46, 40, 987, 654, 321); +const timeZone = new Temporal.TimeZone("UTC"); +TemporalHelpers.checkStringOptionWrongType("disambiguation", "compatible", + (disambiguation) => timeZone.getInstantFor(datetime, { disambiguation }), + (result, descr) => assert.sameValue(result.epochNanoseconds, 1_000_000_000_987_654_321n, descr), +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/infinity-throws-rangeerror.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/infinity-throws-rangeerror.js new file mode 100644 index 0000000000..3b92774dc0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/infinity-throws-rangeerror.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Throws if any value in the property bag is Infinity or -Infinity +esid: sec-temporal.timezone.prototype.getinstantfor +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); +const base = { year: 2000, month: 5, day: 2, hour: 15, minute: 30, second: 45, millisecond: 987, microsecond: 654, nanosecond: 321 }; + +[Infinity, -Infinity].forEach((inf) => { + ["year", "month", "day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond"].forEach((prop) => { + assert.throws(RangeError, () => instance.getInstantFor({ ...base, [prop]: inf }), `${prop} property cannot be ${inf}`); + + const calls = []; + const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop); + assert.throws(RangeError, () => instance.getInstantFor({ ...base, [prop]: obj })); + assert.compareArray(calls, [`get ${prop}.valueOf`, `call ${prop}.valueOf`], "it fails after fetching the primitive value"); + }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/leap-second.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/leap-second.js new file mode 100644 index 0000000000..c3a777ba19 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/leap-second.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: Leap second is a valid ISO string for PlainDateTime +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.getInstantFor(arg); +assert.sameValue( + result1.epochNanoseconds, + 1_483_228_799_000_000_000n, + "leap second is a valid ISO string for PlainDateTime" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.getInstantFor(arg); +assert.sameValue( + result2.epochNanoseconds, + 1_483_228_799_000_000_000n, + "second: 60 is ignored in property bag for PlainDateTime" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/length.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/length.js new file mode 100644 index 0000000000..cac2c6708f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/length.js @@ -0,0 +1,28 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: Temporal.TimeZone.prototype.getInstantFor.length is 1 +info: | + 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: [Temporal] +---*/ + +verifyProperty(Temporal.TimeZone.prototype.getInstantFor, "length", { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/name.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/name.js new file mode 100644 index 0000000000..54a73180a9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/name.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: Temporal.TimeZone.prototype.getInstantFor.name is "getInstantFor". +info: | + 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: [Temporal] +---*/ + +verifyProperty(Temporal.TimeZone.prototype.getInstantFor, "name", { + value: "getInstantFor", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/not-a-constructor.js new file mode 100644 index 0000000000..db08812ba2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/not-a-constructor.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: > + Temporal.TimeZone.prototype.getInstantFor does not implement [[Construct]], is not new-able +info: | + Built-in function objects that are not identified as constructors do not implement the + [[Construct]] internal method unless otherwise specified in the description of a particular + function. +includes: [isConstructor.js] +features: [Reflect.construct, Temporal] +---*/ + +assert.throws(TypeError, () => { + new Temporal.TimeZone.prototype.getInstantFor(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.TimeZone.prototype.getInstantFor), false, + "isConstructor(Temporal.TimeZone.prototype.getInstantFor)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/options-object.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/options-object.js new file mode 100644 index 0000000000..a28eb42587 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/options-object.js @@ -0,0 +1,25 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: Empty or a function object may be used as options +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const result1 = instance.getInstantFor(new Temporal.PlainDateTime(2019, 10, 29, 10, 46, 38), {}); +assert.sameValue( + result1.epochNanoseconds, 1572345998000000000n, + "options may be an empty plain object" +); + +const result2 = instance.getInstantFor(new Temporal.PlainDateTime(2019, 10, 29, 10, 46, 38), () => {}); +assert.sameValue( + result2.epochNanoseconds, 1572345998000000000n, + "options may be a function object" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/options-undefined.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/options-undefined.js new file mode 100644 index 0000000000..dfb10527cb --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/options-undefined.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +includes: [temporalHelpers.js] +description: Verify that undefined options are handled correctly. +features: [BigInt, Temporal] +---*/ + +const datetimeEarlier = new Temporal.PlainDateTime(2000, 10, 29, 1, 34, 56, 987, 654, 321); +const datetimeLater = new Temporal.PlainDateTime(2000, 4, 2, 2, 34, 56, 987, 654, 321); +const timeZone = TemporalHelpers.springForwardFallBackTimeZone(); + +[ + [datetimeEarlier, 972808496987654321n], + [datetimeLater, 954671696987654321n], +].forEach(([datetime, expected]) => { + const explicit = timeZone.getInstantFor(datetime, undefined); + assert.sameValue(explicit.epochNanoseconds, expected, "default disambiguation is compatible"); + + const implicit = timeZone.getInstantFor(datetime); + assert.sameValue(implicit.epochNanoseconds, expected, "default disambiguation is compatible"); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/options-wrong-type.js new file mode 100644 index 0000000000..ae333bdcd0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.TimeZone("UTC"); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.getInstantFor(new Temporal.PlainDateTime(2019, 10, 29, 10, 46, 38), value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/order-of-operations.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/order-of-operations.js new file mode 100644 index 0000000000..9a57f159b6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/order-of-operations.js @@ -0,0 +1,88 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: Properties on an object passed to getInstantFor() are accessed in the correct order +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + // GetTemporalCalendarWithISODefault + "get fields.calendar", + "has fields.calendar.calendar", + // CalendarFields + "get fields.calendar.fields", + "call fields.calendar.fields", + // PrepareTemporalFields + "get fields.day", + "get fields.day.valueOf", + "call fields.day.valueOf", + "get fields.hour", + "get fields.hour.valueOf", + "call fields.hour.valueOf", + "get fields.microsecond", + "get fields.microsecond.valueOf", + "call fields.microsecond.valueOf", + "get fields.millisecond", + "get fields.millisecond.valueOf", + "call fields.millisecond.valueOf", + "get fields.minute", + "get fields.minute.valueOf", + "call fields.minute.valueOf", + "get fields.month", + "get fields.month.valueOf", + "call fields.month.valueOf", + "get fields.monthCode", + "get fields.monthCode.toString", + "call fields.monthCode.toString", + "get fields.nanosecond", + "get fields.nanosecond.valueOf", + "call fields.nanosecond.valueOf", + "get fields.second", + "get fields.second.valueOf", + "call fields.second.valueOf", + "get fields.year", + "get fields.year.valueOf", + "call fields.year.valueOf", + // InterpretTemporalDateTimeFields + "get fields.calendar.dateFromFields", + "call fields.calendar.dateFromFields", + // ToTemporalDisambiguation + "get options.disambiguation", + "get options.disambiguation.toString", + "call options.disambiguation.toString", + // BuiltinTimeZoneGetInstantFor + "get this.getPossibleInstantsFor", + "call this.getPossibleInstantsFor", +]; +const actual = []; + +const instance = new Temporal.TimeZone("UTC"); +TemporalHelpers.observeProperty(actual, instance, "getPossibleInstantsFor", function getPossibleInstantsFor(...args) { + actual.push("call this.getPossibleInstantsFor"); + return Temporal.TimeZone.prototype.getPossibleInstantsFor.apply(instance, args); +}, "this"); + +const fields = TemporalHelpers.propertyBagObserver(actual, { + year: 2000, + month: 5, + monthCode: "M05", + day: 2, + hour: 12, + minute: 34, + second: 56, + millisecond: 987, + microsecond: 654, + nanosecond: 321, + calendar: TemporalHelpers.calendarObserver(actual, "fields.calendar"), +}, "fields"); + +const options = TemporalHelpers.propertyBagObserver(actual, { disambiguation: "compatible" }, "options"); + +instance.getInstantFor(fields, options); +assert.compareArray(actual, expected, "order of operations"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/prop-desc.js new file mode 100644 index 0000000000..d55828c9c7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/prop-desc.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: The "getInstantFor" property of Temporal.TimeZone.prototype +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.TimeZone.prototype.getInstantFor, + "function", + "`typeof TimeZone.prototype.getInstantFor` is `function`" +); + +verifyProperty(Temporal.TimeZone.prototype, "getInstantFor", { + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/read-time-fields-before-datefromfields.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/read-time-fields-before-datefromfields.js new file mode 100644 index 0000000000..fb655ff31a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/read-time-fields-before-datefromfields.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: The time fields are read from the object before being passed to dateFromFields(). +info: | + sec-temporal.timezone.prototype.getinstantfor step 3: + 3. Set _dateTime_ to ? ToTemporalDateTime(_dateTime_). + sec-temporal-totemporaldatetime step 2.e: + e. Let _result_ be ? InterpretTemporalDateTimeFields(_calendar_, _fields_, _options_). + sec-temporal-interprettemporaldatetimefields steps 1–2: + 1. Let _timeResult_ be ? ToTemporalTimeRecord(_fields_). + 2. Let _temporalDate_ be ? DateFromFields(_calendar_, _fields_, _options_). +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const timezone = new Temporal.TimeZone("UTC"); +const calendar = TemporalHelpers.calendarMakeInfinityTime(); +const result = timezone.getInstantFor({ year: 1970, month: 1, day: 1, calendar }); + +assert.sameValue(result.epochNanoseconds, 0n, "epochNanoseconds result"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/shell.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/shell.js new file mode 100644 index 0000000000..eda1477282 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/shell.js @@ -0,0 +1,24 @@ +// GENERATED, DO NOT EDIT +// file: isConstructor.js +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: | + Test if a given function is a constructor function. +defines: [isConstructor] +features: [Reflect.construct] +---*/ + +function isConstructor(f) { + if (typeof f !== "function") { + throw new Test262Error("isConstructor invoked with a non-function value"); + } + + try { + Reflect.construct(function(){}, [], f); + } catch (e) { + return false; + } + return true; +} diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/year-zero.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/year-zero.js new file mode 100644 index 0000000000..c915c56ae9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/year-zero.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-12-07", + "-000000-12-07T03:24:30", + "-000000-12-07T03:24:30+01:00", + "-000000-12-07T03:24:30+00:00[UTC]", +]; +const instance = new Temporal.TimeZone("UTC"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.getInstantFor(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/argument-string-calendar-annotation.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/argument-string-calendar-annotation.js new file mode 100644 index 0000000000..532b96f7b3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/argument-string-calendar-annotation.js @@ -0,0 +1,34 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getnexttransition +description: Various forms of calendar annotation; critical flag has no effect +features: [Temporal] +---*/ + +const tests = [ + ["1970-01-01T00:00Z[u-ca=iso8601]", "without time zone"], + ["1970-01-01T00:00Z[UTC][u-ca=gregory]", "with time zone"], + ["1970-01-01T00:00Z[!u-ca=hebrew]", "with ! and no time zone"], + ["1970-01-01T00:00Z[UTC][!u-ca=chinese]", "with ! and time zone"], + ["1970-01-01T00:00Z[u-ca=discord]", "annotation is ignored"], + ["1970-01-01T00:00Z[!u-ca=discord]", "annotation with ! is ignored"], + ["1970-01-01T00:00Z[u-ca=iso8601][u-ca=discord]", "two annotations are ignored"], + ["1970-01-01T00:00Z[u-ca=iso8601][!u-ca=discord]", "two annotations are ignored even with !"], +]; + +const instance = new Temporal.TimeZone("UTC"); + +tests.forEach(([arg, description]) => { + const result = instance.getNextTransition(arg); + + assert.sameValue( + result, + null, + `calendar annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/argument-string-critical-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/argument-string-critical-unknown-annotation.js new file mode 100644 index 0000000000..20a6ebdc90 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/argument-string-critical-unknown-annotation.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getnexttransition +description: Unknown annotations with critical flag are rejected +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01T00:00Z[!foo=bar]", + "1970-01-01T00:00Z[UTC][!foo=bar]", + "1970-01-01T00:00Z[u-ca=iso8601][!foo=bar]", + "1970-01-01T00:00Z[UTC][!foo=bar][u-ca=iso8601]", + "1970-01-01T00:00Z[foo=bar][!_foo-bar0=Dont-Ignore-This-99999999999]", +]; +const instance = new Temporal.TimeZone("UTC"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.getNextTransition(arg), + `reject unknown annotation with critical flag: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/argument-string-date-with-utc-offset.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/argument-string-date-with-utc-offset.js new file mode 100644 index 0000000000..21bfddc055 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/argument-string-date-with-utc-offset.js @@ -0,0 +1,52 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getnexttransition +description: UTC offset not valid with format that does not include a time +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const validStrings = [ + "1970-01-01T00Z", + "1970-01-01T00Z[UTC]", + "1970-01-01T00Z[!UTC]", + "1970-01-01T00Z[Europe/Vienna]", + "1970-01-01T00+00:00", + "1970-01-01T00+00:00[UTC]", + "1970-01-01T00+00:00[!UTC]", + "1969-12-31T16-08:00[America/Vancouver]", +]; + +for (const arg of validStrings) { + const result = instance.getNextTransition(arg); + + assert.sameValue( + result, + null, + `"${arg}" is a valid UTC offset with time for Instant` + ); +} + +const invalidStrings = [ + "2022-09-15Z", + "2022-09-15Z[UTC]", + "2022-09-15Z[Europe/Vienna]", + "2022-09-15+00:00", + "2022-09-15+00:00[UTC]", + "2022-09-15-02:30", + "2022-09-15-02:30[America/St_Johns]", +]; + +for (const arg of invalidStrings) { + assert.throws( + RangeError, + () => instance.getNextTransition(arg), + `"${arg}" UTC offset without time is not valid for Instant` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/argument-string-invalid.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/argument-string-invalid.js new file mode 100644 index 0000000000..565495d123 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/argument-string-invalid.js @@ -0,0 +1,69 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getnexttransition +description: > + RangeError thrown if an invalid ISO string (or syntactically valid ISO string + that is not supported) is used as an Instant +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + // invalid ISO strings: + "", + "invalid iso8601", + "2020-01-00T00:00Z", + "2020-01-32T00:00Z", + "2020-02-30T00:00Z", + "2021-02-29T00:00Z", + "2020-00-01T00:00Z", + "2020-13-01T00:00Z", + "2020-01-01TZ", + "2020-01-01T25:00:00Z", + "2020-01-01T01:60:00Z", + "2020-01-01T01:60:61Z", + "2020-01-01T00:00Zjunk", + "2020-01-01T00:00:00Zjunk", + "2020-01-01T00:00:00.000000000Zjunk", + "2020-01-01T00:00:00+00:00junk", + "2020-01-01T00:00:00+00:00[UTC]junk", + "2020-01-01T00:00:00+00:00[UTC][u-ca=iso8601]junk", + "02020-01-01T00:00Z", + "2020-001-01T00:00Z", + "2020-01-001T00:00Z", + "2020-01-01T001Z", + "2020-01-01T01:001Z", + "2020-01-01T01:01:001Z", + // valid, but forms not supported in Temporal: + "2020-W01-1T00:00Z", + "2020-001T00:00Z", + "+0002020-01-01T00:00Z", + // may be valid in other contexts, but insufficient information for Instant: + "2020-01", + "+002020-01", + "01-01", + "2020-W01", + "P1Y", + "-P12Y", + "2020-01-01", + "2020-01-01T00", + "2020-01-01T00:00", + "2020-01-01T00:00:00", + "2020-01-01T00:00:00.000000000", + // valid, but outside the supported range: + "-999999-01-01T00:00Z", + "+999999-01-01T00:00Z", +]; + +const instance = new Temporal.TimeZone("UTC"); +for (const arg of invalidStrings) { + assert.throws( + RangeError, + () => instance.getNextTransition(arg), + `"${arg}" should not be a valid ISO string for an Instant` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/argument-string-multiple-time-zone.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/argument-string-multiple-time-zone.js new file mode 100644 index 0000000000..dde0f843f7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/argument-string-multiple-time-zone.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getnexttransition +description: More than one time zone annotation is not syntactical +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01T00:00Z[UTC][UTC]", + "1970-01-01T00:00Z[!UTC][UTC]", + "1970-01-01T00:00Z[UTC][!UTC]", + "1970-01-01T00:00Z[UTC][u-ca=iso8601][UTC]", + "1970-01-01T00:00Z[UTC][foo=bar][UTC]", +]; +const instance = new Temporal.TimeZone("UTC"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.getNextTransition(arg), + `reject more than one time zone annotation: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/argument-string-time-separators.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/argument-string-time-separators.js new file mode 100644 index 0000000000..238f591e32 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/argument-string-time-separators.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getnexttransition +description: Time separator in string argument can vary +features: [Temporal] +---*/ + +const tests = [ + ["1970-01-01T00:00Z", "uppercase T"], + ["1970-01-01t00:00Z", "lowercase T"], + ["1970-01-01 00:00Z", "space between date and time"], +]; + +const instance = new Temporal.TimeZone("UTC"); + +tests.forEach(([arg, description]) => { + const result = instance.getNextTransition(arg); + + assert.sameValue( + result, + null, + `variant time separators (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/argument-string-time-zone-annotation.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/argument-string-time-zone-annotation.js new file mode 100644 index 0000000000..599af7cde9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/argument-string-time-zone-annotation.js @@ -0,0 +1,34 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getnexttransition +description: Various forms of time zone annotation; critical flag has no effect +features: [Temporal] +---*/ + +const tests = [ + ["1970-01-01T00:00Z[Asia/Kolkata]", "named, with Z"], + ["1970-01-01T00:00Z[!Europe/Vienna]", "named, with Z and !"], + ["1970-01-01T00:00Z[+00:00]", "numeric, with Z"], + ["1970-01-01T00:00Z[!-02:30]", "numeric, with Z and !"], + ["1970-01-01T00:00+00:00[UTC]", "named, with offset"], + ["1970-01-01T00:00+00:00[!Africa/Abidjan]", "named, with offset and !"], + ["1970-01-01T00:00+00:00[-08:00]", "numeric, with offset"], + ["1970-01-01T00:00+00:00[!+01:00]", "numeric, with offset and !"], +]; + +const instance = new Temporal.TimeZone("UTC"); + +tests.forEach(([arg, description]) => { + const result = instance.getNextTransition(arg); + + assert.sameValue( + result, + null, + `time zone annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/argument-string-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/argument-string-unknown-annotation.js new file mode 100644 index 0000000000..970c337233 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/argument-string-unknown-annotation.js @@ -0,0 +1,31 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getnexttransition +description: Various forms of unknown annotation +features: [Temporal] +---*/ + +const tests = [ + ["1970-01-01T00:00Z[foo=bar]", "alone"], + ["1970-01-01T00:00Z[UTC][foo=bar]", "with time zone"], + ["1970-01-01T00:00Z[u-ca=iso8601][foo=bar]", "with calendar"], + ["1970-01-01T00:00Z[UTC][foo=bar][u-ca=iso8601]", "with time zone and calendar"], + ["1970-01-01T00:00Z[foo=bar][_foo-bar0=Ignore-This-999999999999]", "with another unknown annotation"], +]; + +const instance = new Temporal.TimeZone("UTC"); + +tests.forEach(([arg, description]) => { + const result = instance.getNextTransition(arg); + + assert.sameValue( + result, + null, + `unknown annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/argument-wrong-type.js new file mode 100644 index 0000000000..653d0c0265 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/argument-wrong-type.js @@ -0,0 +1,40 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getnexttransition +description: > + Appropriate error thrown when argument cannot be converted to a valid string + for Instant +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], + [{}, "plain object"], + [Temporal.Instant, "Temporal.Instant, object"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.getNextTransition(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [Temporal.Instant.prototype, "Temporal.Instant.prototype, object"], // fails brand check in toString() +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.getNextTransition(arg), `${description} does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/argument-zoneddatetime.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/argument-zoneddatetime.js new file mode 100644 index 0000000000..7530526ada --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/argument-zoneddatetime.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getnexttransition +description: Fast path for converting Temporal.ZonedDateTime to Temporal.Instant +info: | + sec-temporal.timezone.prototype.getnexttransition step 3: + 3. Set _startingPoint_ to ? ToTemporalInstant(_startingPoint_). + sec-temporal-totemporalinstant step 1.b: + b. If _item_ has an [[InitializedTemporalZonedDateTime]] internal slot, then + i. Return ! CreateTemporalInstant(_item_.[[Nanoseconds]]). +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +TemporalHelpers.checkToTemporalInstantFastPath((datetime) => { + const timeZone = Temporal.TimeZone.from("UTC"); + const result = timeZone.getNextTransition(datetime); + assert.sameValue(result, null, "transition result"); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/branding.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/branding.js new file mode 100644 index 0000000000..c7174ec417 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/branding.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getnexttransition +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const getNextTransition = Temporal.TimeZone.prototype.getNextTransition; + +assert.sameValue(typeof getNextTransition, "function"); + +const args = [new Temporal.Instant(0n)]; + +assert.throws(TypeError, () => getNextTransition.apply(undefined, args), "undefined"); +assert.throws(TypeError, () => getNextTransition.apply(null, args), "null"); +assert.throws(TypeError, () => getNextTransition.apply(true, args), "true"); +assert.throws(TypeError, () => getNextTransition.apply("", args), "empty string"); +assert.throws(TypeError, () => getNextTransition.apply(Symbol(), args), "symbol"); +assert.throws(TypeError, () => getNextTransition.apply(1, args), "1"); +assert.throws(TypeError, () => getNextTransition.apply({}, args), "plain object"); +assert.throws(TypeError, () => getNextTransition.apply(Temporal.TimeZone, args), "Temporal.TimeZone"); +assert.throws(TypeError, () => getNextTransition.apply(Temporal.TimeZone.prototype, args), "Temporal.TimeZone.prototype"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/browser.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/builtin.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/builtin.js new file mode 100644 index 0000000000..cd8968e63d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/builtin.js @@ -0,0 +1,36 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getnexttransition +description: > + Tests that Temporal.TimeZone.prototype.getNextTransition + meets the requirements for built-in objects defined by the + introduction of chapter 17 of the ECMAScript Language Specification. +info: | + Built-in functions that are not constructors do not have a "prototype" property unless + otherwise specified in the description of a particular function. + + Unless specified otherwise, a built-in object that is callable as a function is a built-in + function object with the characteristics described in 10.3. Unless specified otherwise, the + [[Extensible]] internal slot of a built-in object initially has the value true. + + Unless otherwise specified every built-in function and every built-in constructor has the + Function prototype object [...] as the value of its [[Prototype]] internal slot. +features: [Temporal] +---*/ + +assert.sameValue(Object.isExtensible(Temporal.TimeZone.prototype.getNextTransition), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.TimeZone.prototype.getNextTransition), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.TimeZone.prototype.getNextTransition), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.TimeZone.prototype.getNextTransition.hasOwnProperty("prototype"), + false, "prototype property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/instant-string-limits.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/instant-string-limits.js new file mode 100644 index 0000000000..72368443c0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/instant-string-limits.js @@ -0,0 +1,47 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getnexttransition +description: String arguments at the limit of the representable range +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const minInstantStrings = [ + "-271821-04-20T00:00Z", + "-271821-04-19T23:00-01:00", + "-271821-04-19T00:00:00.000000001-23:59:59.999999999", +]; +for (const str of minInstantStrings) { + assert.sameValue(instance.getNextTransition(str), null, `instant string ${str} should be valid`); +} + +const maxInstantStrings = [ + "+275760-09-13T00:00Z", + "+275760-09-13T01:00+01:00", + "+275760-09-13T23:59:59.999999999+23:59:59.999999999", +]; + +for (const str of maxInstantStrings) { + assert.sameValue(instance.getNextTransition(str), null, `instant string ${str} should be valid`); +} + +const outOfRangeInstantStrings = [ + "-271821-04-19T23:59:59.999999999Z", + "-271821-04-19T23:00-00:59:59.999999999", + "-271821-04-19T00:00:00-23:59:59.999999999", + "-271821-04-19T00:00:00-24:00", + "+275760-09-13T00:00:00.000000001Z", + "+275760-09-13T01:00+00:59:59.999999999", + "+275760-09-14T00:00+23:59:59.999999999", + "+275760-09-14T00:00+24:00", +]; + +for (const str of outOfRangeInstantStrings) { + assert.throws(RangeError, () => instance.getNextTransition(str), `instant string ${str} should not be valid`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/instant-string.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/instant-string.js new file mode 100644 index 0000000000..9001c6aab2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/instant-string.js @@ -0,0 +1,34 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getnexttransition +description: Conversion of ISO date-time strings to Temporal.Instant instances +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +let str = "1970-01-01T00:00"; +assert.throws(RangeError, () => instance.getNextTransition(str), "bare date-time string is not an instant"); +str = "1970-01-01T00:00[UTC]"; +assert.throws(RangeError, () => instance.getNextTransition(str), "date-time + IANA annotation is not an instant"); + +// The following are all valid strings so should not throw: + +const valids = [ + "1970-01-01T00:00Z", + "1970-01-01T00:00+01:00", + "1970-01-01T00:00Z[UTC]", + "1970-01-01T00:00+01:00[UTC]", + "1970-01-01T00:00Z[u-ca=hebrew]", + "1970-01-01T00:00+01:00[u-ca=hebrew]", + "1970-01-01T00:00+01:00[Etc/Ignored][u-ca=hebrew]", +]; +for (const str of valids) { + const result = instance.getNextTransition(str); + assert.sameValue(result, null); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/leap-second.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/leap-second.js new file mode 100644 index 0000000000..192613db05 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/leap-second.js @@ -0,0 +1,21 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getnexttransition +description: Leap second is a valid ISO string for Instant +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const arg = "2016-12-31T23:59:60Z"; +const result = instance.getNextTransition(arg); +assert.sameValue( + result, + null, + "leap second is a valid ISO string for Instant" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/length.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/length.js new file mode 100644 index 0000000000..f0d93b0f09 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/length.js @@ -0,0 +1,28 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getnexttransition +description: Temporal.TimeZone.prototype.getNextTransition.length is 1 +info: | + 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: [Temporal] +---*/ + +verifyProperty(Temporal.TimeZone.prototype.getNextTransition, "length", { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/name.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/name.js new file mode 100644 index 0000000000..ec444a82f7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/name.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getnexttransition +description: Temporal.TimeZone.prototype.getNextTransition.name is "getNextTransition". +info: | + 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: [Temporal] +---*/ + +verifyProperty(Temporal.TimeZone.prototype.getNextTransition, "name", { + value: "getNextTransition", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/not-a-constructor.js new file mode 100644 index 0000000000..4de7b386db --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/not-a-constructor.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getnexttransition +description: > + Temporal.TimeZone.prototype.getNextTransition does not implement [[Construct]], is not new-able +info: | + Built-in function objects that are not identified as constructors do not implement the + [[Construct]] internal method unless otherwise specified in the description of a particular + function. +includes: [isConstructor.js] +features: [Reflect.construct, Temporal] +---*/ + +assert.throws(TypeError, () => { + new Temporal.TimeZone.prototype.getNextTransition(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.TimeZone.prototype.getNextTransition), false, + "isConstructor(Temporal.TimeZone.prototype.getNextTransition)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/prop-desc.js new file mode 100644 index 0000000000..cabccb702f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/prop-desc.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getnexttransition +description: The "getNextTransition" property of Temporal.TimeZone.prototype +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.TimeZone.prototype.getNextTransition, + "function", + "`typeof TimeZone.prototype.getNextTransition` is `function`" +); + +verifyProperty(Temporal.TimeZone.prototype, "getNextTransition", { + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/shell.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/shell.js new file mode 100644 index 0000000000..eda1477282 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/shell.js @@ -0,0 +1,24 @@ +// GENERATED, DO NOT EDIT +// file: isConstructor.js +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: | + Test if a given function is a constructor function. +defines: [isConstructor] +features: [Reflect.construct] +---*/ + +function isConstructor(f) { + if (typeof f !== "function") { + throw new Test262Error("isConstructor invoked with a non-function value"); + } + + try { + Reflect.construct(function(){}, [], f); + } catch (e) { + return false; + } + return true; +} diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/year-zero.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/year-zero.js new file mode 100644 index 0000000000..3681c72a73 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/year-zero.js @@ -0,0 +1,25 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getnexttransition +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-03-30T00:45Z", + "-000000-03-30T01:45+01:00", + "-000000-03-30T01:45:00+00:00[UTC]", +]; +const instance = new Temporal.TimeZone("UTC"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.getNextTransition(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/argument-string-calendar-annotation.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/argument-string-calendar-annotation.js new file mode 100644 index 0000000000..6ea2a3e226 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/argument-string-calendar-annotation.js @@ -0,0 +1,34 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetnanosecondsfor +description: Various forms of calendar annotation; critical flag has no effect +features: [Temporal] +---*/ + +const tests = [ + ["1970-01-01T00:00Z[u-ca=iso8601]", "without time zone"], + ["1970-01-01T00:00Z[UTC][u-ca=gregory]", "with time zone"], + ["1970-01-01T00:00Z[!u-ca=hebrew]", "with ! and no time zone"], + ["1970-01-01T00:00Z[UTC][!u-ca=chinese]", "with ! and time zone"], + ["1970-01-01T00:00Z[u-ca=discord]", "annotation is ignored"], + ["1970-01-01T00:00Z[!u-ca=discord]", "annotation with ! is ignored"], + ["1970-01-01T00:00Z[u-ca=iso8601][u-ca=discord]", "two annotations are ignored"], + ["1970-01-01T00:00Z[u-ca=iso8601][!u-ca=discord]", "two annotations are ignored even with !"], +]; + +const instance = new Temporal.TimeZone("UTC"); + +tests.forEach(([arg, description]) => { + const result = instance.getOffsetNanosecondsFor(arg); + + assert.sameValue( + result, + 0, + `calendar annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/argument-string-critical-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/argument-string-critical-unknown-annotation.js new file mode 100644 index 0000000000..82fc2b3fb1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/argument-string-critical-unknown-annotation.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetnanosecondsfor +description: Unknown annotations with critical flag are rejected +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01T00:00Z[!foo=bar]", + "1970-01-01T00:00Z[UTC][!foo=bar]", + "1970-01-01T00:00Z[u-ca=iso8601][!foo=bar]", + "1970-01-01T00:00Z[UTC][!foo=bar][u-ca=iso8601]", + "1970-01-01T00:00Z[foo=bar][!_foo-bar0=Dont-Ignore-This-99999999999]", +]; +const instance = new Temporal.TimeZone("UTC"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.getOffsetNanosecondsFor(arg), + `reject unknown annotation with critical flag: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/argument-string-date-with-utc-offset.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/argument-string-date-with-utc-offset.js new file mode 100644 index 0000000000..14e2a99224 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/argument-string-date-with-utc-offset.js @@ -0,0 +1,52 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetnanosecondsfor +description: UTC offset not valid with format that does not include a time +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const validStrings = [ + "1970-01-01T00Z", + "1970-01-01T00Z[UTC]", + "1970-01-01T00Z[!UTC]", + "1970-01-01T00Z[Europe/Vienna]", + "1970-01-01T00+00:00", + "1970-01-01T00+00:00[UTC]", + "1970-01-01T00+00:00[!UTC]", + "1969-12-31T16-08:00[America/Vancouver]", +]; + +for (const arg of validStrings) { + const result = instance.getOffsetNanosecondsFor(arg); + + assert.sameValue( + result, + 0, + `"${arg}" is a valid UTC offset with time for Instant` + ); +} + +const invalidStrings = [ + "2022-09-15Z", + "2022-09-15Z[UTC]", + "2022-09-15Z[Europe/Vienna]", + "2022-09-15+00:00", + "2022-09-15+00:00[UTC]", + "2022-09-15-02:30", + "2022-09-15-02:30[America/St_Johns]", +]; + +for (const arg of invalidStrings) { + assert.throws( + RangeError, + () => instance.getOffsetNanosecondsFor(arg), + `"${arg}" UTC offset without time is not valid for Instant` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/argument-string-invalid.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/argument-string-invalid.js new file mode 100644 index 0000000000..d64e0434da --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/argument-string-invalid.js @@ -0,0 +1,69 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetnanosecondsfor +description: > + RangeError thrown if an invalid ISO string (or syntactically valid ISO string + that is not supported) is used as an Instant +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + // invalid ISO strings: + "", + "invalid iso8601", + "2020-01-00T00:00Z", + "2020-01-32T00:00Z", + "2020-02-30T00:00Z", + "2021-02-29T00:00Z", + "2020-00-01T00:00Z", + "2020-13-01T00:00Z", + "2020-01-01TZ", + "2020-01-01T25:00:00Z", + "2020-01-01T01:60:00Z", + "2020-01-01T01:60:61Z", + "2020-01-01T00:00Zjunk", + "2020-01-01T00:00:00Zjunk", + "2020-01-01T00:00:00.000000000Zjunk", + "2020-01-01T00:00:00+00:00junk", + "2020-01-01T00:00:00+00:00[UTC]junk", + "2020-01-01T00:00:00+00:00[UTC][u-ca=iso8601]junk", + "02020-01-01T00:00Z", + "2020-001-01T00:00Z", + "2020-01-001T00:00Z", + "2020-01-01T001Z", + "2020-01-01T01:001Z", + "2020-01-01T01:01:001Z", + // valid, but forms not supported in Temporal: + "2020-W01-1T00:00Z", + "2020-001T00:00Z", + "+0002020-01-01T00:00Z", + // may be valid in other contexts, but insufficient information for Instant: + "2020-01", + "+002020-01", + "01-01", + "2020-W01", + "P1Y", + "-P12Y", + "2020-01-01", + "2020-01-01T00", + "2020-01-01T00:00", + "2020-01-01T00:00:00", + "2020-01-01T00:00:00.000000000", + // valid, but outside the supported range: + "-999999-01-01T00:00Z", + "+999999-01-01T00:00Z", +]; + +const instance = new Temporal.TimeZone("UTC"); +for (const arg of invalidStrings) { + assert.throws( + RangeError, + () => instance.getOffsetNanosecondsFor(arg), + `"${arg}" should not be a valid ISO string for an Instant` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/argument-string-multiple-time-zone.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/argument-string-multiple-time-zone.js new file mode 100644 index 0000000000..34fe823de8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/argument-string-multiple-time-zone.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetnanosecondsfor +description: More than one time zone annotation is not syntactical +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01T00:00Z[UTC][UTC]", + "1970-01-01T00:00Z[!UTC][UTC]", + "1970-01-01T00:00Z[UTC][!UTC]", + "1970-01-01T00:00Z[UTC][u-ca=iso8601][UTC]", + "1970-01-01T00:00Z[UTC][foo=bar][UTC]", +]; +const instance = new Temporal.TimeZone("UTC"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.getOffsetNanosecondsFor(arg), + `reject more than one time zone annotation: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/argument-string-time-separators.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/argument-string-time-separators.js new file mode 100644 index 0000000000..53200b0167 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/argument-string-time-separators.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetnanosecondsfor +description: Time separator in string argument can vary +features: [Temporal] +---*/ + +const tests = [ + ["1970-01-01T00:00Z", "uppercase T"], + ["1970-01-01t00:00Z", "lowercase T"], + ["1970-01-01 00:00Z", "space between date and time"], +]; + +const instance = new Temporal.TimeZone("UTC"); + +tests.forEach(([arg, description]) => { + const result = instance.getOffsetNanosecondsFor(arg); + + assert.sameValue( + result, + 0, + `variant time separators (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/argument-string-time-zone-annotation.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/argument-string-time-zone-annotation.js new file mode 100644 index 0000000000..dbe320a3e8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/argument-string-time-zone-annotation.js @@ -0,0 +1,34 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetnanosecondsfor +description: Various forms of time zone annotation; critical flag has no effect +features: [Temporal] +---*/ + +const tests = [ + ["1970-01-01T00:00Z[Asia/Kolkata]", "named, with Z"], + ["1970-01-01T00:00Z[!Europe/Vienna]", "named, with Z and !"], + ["1970-01-01T00:00Z[+00:00]", "numeric, with Z"], + ["1970-01-01T00:00Z[!-02:30]", "numeric, with Z and !"], + ["1970-01-01T00:00+00:00[UTC]", "named, with offset"], + ["1970-01-01T00:00+00:00[!Africa/Abidjan]", "named, with offset and !"], + ["1970-01-01T00:00+00:00[-08:00]", "numeric, with offset"], + ["1970-01-01T00:00+00:00[!+01:00]", "numeric, with offset and !"], +]; + +const instance = new Temporal.TimeZone("UTC"); + +tests.forEach(([arg, description]) => { + const result = instance.getOffsetNanosecondsFor(arg); + + assert.sameValue( + result, + 0, + `time zone annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/argument-string-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/argument-string-unknown-annotation.js new file mode 100644 index 0000000000..9bcd3aae91 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/argument-string-unknown-annotation.js @@ -0,0 +1,31 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetnanosecondsfor +description: Various forms of unknown annotation +features: [Temporal] +---*/ + +const tests = [ + ["1970-01-01T00:00Z[foo=bar]", "alone"], + ["1970-01-01T00:00Z[UTC][foo=bar]", "with time zone"], + ["1970-01-01T00:00Z[u-ca=iso8601][foo=bar]", "with calendar"], + ["1970-01-01T00:00Z[UTC][foo=bar][u-ca=iso8601]", "with time zone and calendar"], + ["1970-01-01T00:00Z[foo=bar][_foo-bar0=Ignore-This-999999999999]", "with another unknown annotation"], +]; + +const instance = new Temporal.TimeZone("UTC"); + +tests.forEach(([arg, description]) => { + const result = instance.getOffsetNanosecondsFor(arg); + + assert.sameValue( + result, + 0, + `unknown annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/argument-wrong-type.js new file mode 100644 index 0000000000..ae48d515a2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/argument-wrong-type.js @@ -0,0 +1,40 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetnanosecondsfor +description: > + Appropriate error thrown when argument cannot be converted to a valid string + for Instant +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], + [{}, "plain object"], + [Temporal.Instant, "Temporal.Instant, object"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.getOffsetNanosecondsFor(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [Temporal.Instant.prototype, "Temporal.Instant.prototype, object"], // fails brand check in toString() +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.getOffsetNanosecondsFor(arg), `${description} does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/argument-zoneddatetime.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/argument-zoneddatetime.js new file mode 100644 index 0000000000..fe220ed296 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/argument-zoneddatetime.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetnanosecondsfor +description: Fast path for converting Temporal.ZonedDateTime to Temporal.Instant +info: | + sec-temporal.timezone.prototype.getoffsetnanosecondsfor step 3: + 3. Set _instant_ to ? ToTemporalInstant(_instant_). + sec-temporal-totemporalinstant step 1.b: + b. If _item_ has an [[InitializedTemporalZonedDateTime]] internal slot, then + i. Return ! CreateTemporalInstant(_item_.[[Nanoseconds]]). +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +TemporalHelpers.checkToTemporalInstantFastPath((datetime) => { + const timeZone = Temporal.TimeZone.from("UTC"); + const result = timeZone.getOffsetNanosecondsFor(datetime); + assert.sameValue(result, 0, "offset result"); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/branding.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/branding.js new file mode 100644 index 0000000000..4e7fe91645 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/branding.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetnanosecondsfor +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const getOffsetNanosecondsFor = Temporal.TimeZone.prototype.getOffsetNanosecondsFor; + +assert.sameValue(typeof getOffsetNanosecondsFor, "function"); + +const args = [new Temporal.Instant(0n)]; + +assert.throws(TypeError, () => getOffsetNanosecondsFor.apply(undefined, args), "undefined"); +assert.throws(TypeError, () => getOffsetNanosecondsFor.apply(null, args), "null"); +assert.throws(TypeError, () => getOffsetNanosecondsFor.apply(true, args), "true"); +assert.throws(TypeError, () => getOffsetNanosecondsFor.apply("", args), "empty string"); +assert.throws(TypeError, () => getOffsetNanosecondsFor.apply(Symbol(), args), "symbol"); +assert.throws(TypeError, () => getOffsetNanosecondsFor.apply(1, args), "1"); +assert.throws(TypeError, () => getOffsetNanosecondsFor.apply({}, args), "plain object"); +assert.throws(TypeError, () => getOffsetNanosecondsFor.apply(Temporal.TimeZone, args), "Temporal.TimeZone"); +assert.throws(TypeError, () => getOffsetNanosecondsFor.apply(Temporal.TimeZone.prototype, args), "Temporal.TimeZone.prototype"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/browser.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/builtin.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/builtin.js new file mode 100644 index 0000000000..359d05bb82 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/builtin.js @@ -0,0 +1,36 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetnanosecondsfor +description: > + Tests that Temporal.TimeZone.prototype.getOffsetNanosecondsFor + meets the requirements for built-in objects defined by the + introduction of chapter 17 of the ECMAScript Language Specification. +info: | + Built-in functions that are not constructors do not have a "prototype" property unless + otherwise specified in the description of a particular function. + + Unless specified otherwise, a built-in object that is callable as a function is a built-in + function object with the characteristics described in 10.3. Unless specified otherwise, the + [[Extensible]] internal slot of a built-in object initially has the value true. + + Unless otherwise specified every built-in function and every built-in constructor has the + Function prototype object [...] as the value of its [[Prototype]] internal slot. +features: [Temporal] +---*/ + +assert.sameValue(Object.isExtensible(Temporal.TimeZone.prototype.getOffsetNanosecondsFor), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.TimeZone.prototype.getOffsetNanosecondsFor), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.TimeZone.prototype.getOffsetNanosecondsFor), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.TimeZone.prototype.getOffsetNanosecondsFor.hasOwnProperty("prototype"), + false, "prototype property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/instant-string-limits.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/instant-string-limits.js new file mode 100644 index 0000000000..5036be6a0d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/instant-string-limits.js @@ -0,0 +1,47 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetnanosecondsfor +description: String arguments at the limit of the representable range +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const minInstantStrings = [ + "-271821-04-20T00:00Z", + "-271821-04-19T23:00-01:00", + "-271821-04-19T00:00:00.000000001-23:59:59.999999999", +]; +for (const str of minInstantStrings) { + assert.sameValue(instance.getOffsetNanosecondsFor(str), 0, `instant string ${str} should be valid`); +} + +const maxInstantStrings = [ + "+275760-09-13T00:00Z", + "+275760-09-13T01:00+01:00", + "+275760-09-13T23:59:59.999999999+23:59:59.999999999", +]; + +for (const str of maxInstantStrings) { + assert.sameValue(instance.getOffsetNanosecondsFor(str), 0, `instant string ${str} should be valid`); +} + +const outOfRangeInstantStrings = [ + "-271821-04-19T23:59:59.999999999Z", + "-271821-04-19T23:00-00:59:59.999999999", + "-271821-04-19T00:00:00-23:59:59.999999999", + "-271821-04-19T00:00:00-24:00", + "+275760-09-13T00:00:00.000000001Z", + "+275760-09-13T01:00+00:59:59.999999999", + "+275760-09-14T00:00+23:59:59.999999999", + "+275760-09-14T00:00+24:00", +]; + +for (const str of outOfRangeInstantStrings) { + assert.throws(RangeError, () => instance.getOffsetNanosecondsFor(str), `instant string ${str} should not be valid`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/instant-string.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/instant-string.js new file mode 100644 index 0000000000..4da23857fa --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/instant-string.js @@ -0,0 +1,34 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetnanosecondsfor +description: Conversion of ISO date-time strings to Temporal.Instant instances +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +let str = "1970-01-01T00:00"; +assert.throws(RangeError, () => instance.getOffsetNanosecondsFor(str), "bare date-time string is not an instant"); +str = "1970-01-01T00:00[UTC]"; +assert.throws(RangeError, () => instance.getOffsetNanosecondsFor(str), "date-time + IANA annotation is not an instant"); + +// The following are all valid strings so should not throw: + +const valids = [ + "1970-01-01T00:00Z", + "1970-01-01T00:00+01:00", + "1970-01-01T00:00Z[UTC]", + "1970-01-01T00:00+01:00[UTC]", + "1970-01-01T00:00Z[u-ca=hebrew]", + "1970-01-01T00:00+01:00[u-ca=hebrew]", + "1970-01-01T00:00+01:00[Etc/Ignored][u-ca=hebrew]", +]; +for (const str of valids) { + const result = instance.getOffsetNanosecondsFor(str); + assert.sameValue(result, 0); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/leap-second.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/leap-second.js new file mode 100644 index 0000000000..8725c00af7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/leap-second.js @@ -0,0 +1,21 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetnanosecondsfor +description: Leap second is a valid ISO string for Instant +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const arg = "2016-12-31T23:59:60Z"; +const result = instance.getOffsetNanosecondsFor(arg); +assert.sameValue( + result, + 0, + "leap second is a valid ISO string for Instant" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/length.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/length.js new file mode 100644 index 0000000000..b79d635026 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/length.js @@ -0,0 +1,28 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetnanosecondsfor +description: Temporal.TimeZone.prototype.getOffsetNanosecondsFor.length is 1 +info: | + 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: [Temporal] +---*/ + +verifyProperty(Temporal.TimeZone.prototype.getOffsetNanosecondsFor, "length", { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/name.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/name.js new file mode 100644 index 0000000000..bd828e7f1e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/name.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetnanosecondsfor +description: Temporal.TimeZone.prototype.getOffsetNanosecondsFor.name is "getOffsetNanosecondsFor". +info: | + 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: [Temporal] +---*/ + +verifyProperty(Temporal.TimeZone.prototype.getOffsetNanosecondsFor, "name", { + value: "getOffsetNanosecondsFor", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/not-a-constructor.js new file mode 100644 index 0000000000..0f4ee59b39 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/not-a-constructor.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetnanosecondsfor +description: > + Temporal.TimeZone.prototype.getOffsetNanosecondsFor does not implement [[Construct]], is not new-able +info: | + Built-in function objects that are not identified as constructors do not implement the + [[Construct]] internal method unless otherwise specified in the description of a particular + function. +includes: [isConstructor.js] +features: [Reflect.construct, Temporal] +---*/ + +assert.throws(TypeError, () => { + new Temporal.TimeZone.prototype.getOffsetNanosecondsFor(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.TimeZone.prototype.getOffsetNanosecondsFor), false, + "isConstructor(Temporal.TimeZone.prototype.getOffsetNanosecondsFor)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/prop-desc.js new file mode 100644 index 0000000000..b1925f757f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/prop-desc.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetnanosecondsfor +description: The "getOffsetNanosecondsFor" property of Temporal.TimeZone.prototype +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.TimeZone.prototype.getOffsetNanosecondsFor, + "function", + "`typeof TimeZone.prototype.getOffsetNanosecondsFor` is `function`" +); + +verifyProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/shell.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/shell.js new file mode 100644 index 0000000000..eda1477282 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/shell.js @@ -0,0 +1,24 @@ +// GENERATED, DO NOT EDIT +// file: isConstructor.js +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: | + Test if a given function is a constructor function. +defines: [isConstructor] +features: [Reflect.construct] +---*/ + +function isConstructor(f) { + if (typeof f !== "function") { + throw new Test262Error("isConstructor invoked with a non-function value"); + } + + try { + Reflect.construct(function(){}, [], f); + } catch (e) { + return false; + } + return true; +} diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/year-zero.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/year-zero.js new file mode 100644 index 0000000000..dc940fe01f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/year-zero.js @@ -0,0 +1,25 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetnanosecondsfor +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-03-30T00:45Z", + "-000000-03-30T01:45+01:00", + "-000000-03-30T01:45:00+00:00[UTC]", +]; +const instance = new Temporal.TimeZone("UTC"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.getOffsetNanosecondsFor(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-not-absolute-getOffsetNanosecondsFor-override.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-not-absolute-getOffsetNanosecondsFor-override.js new file mode 100644 index 0000000000..8e924f16b2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-not-absolute-getOffsetNanosecondsFor-override.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetstringfor +description: timeZone.getOffsetNanosecondsFor not called when argument cannot be converted to Temporal.Instant +features: [Temporal] +---*/ + +const timeZone = Temporal.TimeZone.from("UTC"); +let called = false; +timeZone.getOffsetNanosecondsFor = () => called = true; +assert.throws(RangeError, () => timeZone.getOffsetStringFor(undefined), "undefined"); +assert.throws(RangeError, () => timeZone.getOffsetStringFor(null), "null"); +assert.throws(RangeError, () => timeZone.getOffsetStringFor(true), "boolean"); +assert.throws(RangeError, () => timeZone.getOffsetStringFor(""), "empty string"); +assert.throws(TypeError, () => timeZone.getOffsetStringFor(Symbol()), "Symbol"); +assert.throws(RangeError, () => timeZone.getOffsetStringFor(5), "number"); +assert.throws(RangeError, () => timeZone.getOffsetStringFor(5n), "bigint"); +assert.throws(RangeError, () => timeZone.getOffsetStringFor({}), "plain object"); +assert.sameValue(called, false); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-string-calendar-annotation.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-string-calendar-annotation.js new file mode 100644 index 0000000000..720755cbe2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-string-calendar-annotation.js @@ -0,0 +1,34 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetstringfor +description: Various forms of calendar annotation; critical flag has no effect +features: [Temporal] +---*/ + +const tests = [ + ["1970-01-01T00:00Z[u-ca=iso8601]", "without time zone"], + ["1970-01-01T00:00Z[UTC][u-ca=gregory]", "with time zone"], + ["1970-01-01T00:00Z[!u-ca=hebrew]", "with ! and no time zone"], + ["1970-01-01T00:00Z[UTC][!u-ca=chinese]", "with ! and time zone"], + ["1970-01-01T00:00Z[u-ca=discord]", "annotation is ignored"], + ["1970-01-01T00:00Z[!u-ca=discord]", "annotation with ! is ignored"], + ["1970-01-01T00:00Z[u-ca=iso8601][u-ca=discord]", "two annotations are ignored"], + ["1970-01-01T00:00Z[u-ca=iso8601][!u-ca=discord]", "two annotations are ignored even with !"], +]; + +const instance = new Temporal.TimeZone("UTC"); + +tests.forEach(([arg, description]) => { + const result = instance.getOffsetStringFor(arg); + + assert.sameValue( + result, + "+00:00", + `calendar annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-string-critical-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-string-critical-unknown-annotation.js new file mode 100644 index 0000000000..598ce51c77 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-string-critical-unknown-annotation.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetstringfor +description: Unknown annotations with critical flag are rejected +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01T00:00Z[!foo=bar]", + "1970-01-01T00:00Z[UTC][!foo=bar]", + "1970-01-01T00:00Z[u-ca=iso8601][!foo=bar]", + "1970-01-01T00:00Z[UTC][!foo=bar][u-ca=iso8601]", + "1970-01-01T00:00Z[foo=bar][!_foo-bar0=Dont-Ignore-This-99999999999]", +]; +const instance = new Temporal.TimeZone("UTC"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.getOffsetStringFor(arg), + `reject unknown annotation with critical flag: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-string-date-with-utc-offset.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-string-date-with-utc-offset.js new file mode 100644 index 0000000000..fab5bdf3c0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-string-date-with-utc-offset.js @@ -0,0 +1,52 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetstringfor +description: UTC offset not valid with format that does not include a time +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const validStrings = [ + "1970-01-01T00Z", + "1970-01-01T00Z[UTC]", + "1970-01-01T00Z[!UTC]", + "1970-01-01T00Z[Europe/Vienna]", + "1970-01-01T00+00:00", + "1970-01-01T00+00:00[UTC]", + "1970-01-01T00+00:00[!UTC]", + "1969-12-31T16-08:00[America/Vancouver]", +]; + +for (const arg of validStrings) { + const result = instance.getOffsetStringFor(arg); + + assert.sameValue( + result, + "+00:00", + `"${arg}" is a valid UTC offset with time for Instant` + ); +} + +const invalidStrings = [ + "2022-09-15Z", + "2022-09-15Z[UTC]", + "2022-09-15Z[Europe/Vienna]", + "2022-09-15+00:00", + "2022-09-15+00:00[UTC]", + "2022-09-15-02:30", + "2022-09-15-02:30[America/St_Johns]", +]; + +for (const arg of invalidStrings) { + assert.throws( + RangeError, + () => instance.getOffsetStringFor(arg), + `"${arg}" UTC offset without time is not valid for Instant` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-string-invalid.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-string-invalid.js new file mode 100644 index 0000000000..4e31f6c70d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-string-invalid.js @@ -0,0 +1,69 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetstringfor +description: > + RangeError thrown if an invalid ISO string (or syntactically valid ISO string + that is not supported) is used as an Instant +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + // invalid ISO strings: + "", + "invalid iso8601", + "2020-01-00T00:00Z", + "2020-01-32T00:00Z", + "2020-02-30T00:00Z", + "2021-02-29T00:00Z", + "2020-00-01T00:00Z", + "2020-13-01T00:00Z", + "2020-01-01TZ", + "2020-01-01T25:00:00Z", + "2020-01-01T01:60:00Z", + "2020-01-01T01:60:61Z", + "2020-01-01T00:00Zjunk", + "2020-01-01T00:00:00Zjunk", + "2020-01-01T00:00:00.000000000Zjunk", + "2020-01-01T00:00:00+00:00junk", + "2020-01-01T00:00:00+00:00[UTC]junk", + "2020-01-01T00:00:00+00:00[UTC][u-ca=iso8601]junk", + "02020-01-01T00:00Z", + "2020-001-01T00:00Z", + "2020-01-001T00:00Z", + "2020-01-01T001Z", + "2020-01-01T01:001Z", + "2020-01-01T01:01:001Z", + // valid, but forms not supported in Temporal: + "2020-W01-1T00:00Z", + "2020-001T00:00Z", + "+0002020-01-01T00:00Z", + // may be valid in other contexts, but insufficient information for Instant: + "2020-01", + "+002020-01", + "01-01", + "2020-W01", + "P1Y", + "-P12Y", + "2020-01-01", + "2020-01-01T00", + "2020-01-01T00:00", + "2020-01-01T00:00:00", + "2020-01-01T00:00:00.000000000", + // valid, but outside the supported range: + "-999999-01-01T00:00Z", + "+999999-01-01T00:00Z", +]; + +const instance = new Temporal.TimeZone("UTC"); +for (const arg of invalidStrings) { + assert.throws( + RangeError, + () => instance.getOffsetStringFor(arg), + `"${arg}" should not be a valid ISO string for an Instant` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-string-multiple-time-zone.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-string-multiple-time-zone.js new file mode 100644 index 0000000000..d95713738e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-string-multiple-time-zone.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetstringfor +description: More than one time zone annotation is not syntactical +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01T00:00Z[UTC][UTC]", + "1970-01-01T00:00Z[!UTC][UTC]", + "1970-01-01T00:00Z[UTC][!UTC]", + "1970-01-01T00:00Z[UTC][u-ca=iso8601][UTC]", + "1970-01-01T00:00Z[UTC][foo=bar][UTC]", +]; +const instance = new Temporal.TimeZone("UTC"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.getOffsetStringFor(arg), + `reject more than one time zone annotation: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-string-time-separators.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-string-time-separators.js new file mode 100644 index 0000000000..12749410a1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-string-time-separators.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetstringfor +description: Time separator in string argument can vary +features: [Temporal] +---*/ + +const tests = [ + ["1970-01-01T00:00Z", "uppercase T"], + ["1970-01-01t00:00Z", "lowercase T"], + ["1970-01-01 00:00Z", "space between date and time"], +]; + +const instance = new Temporal.TimeZone("UTC"); + +tests.forEach(([arg, description]) => { + const result = instance.getOffsetStringFor(arg); + + assert.sameValue( + result, + "+00:00", + `variant time separators (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-string-time-zone-annotation.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-string-time-zone-annotation.js new file mode 100644 index 0000000000..511cdbfbdd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-string-time-zone-annotation.js @@ -0,0 +1,34 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetstringfor +description: Various forms of time zone annotation; critical flag has no effect +features: [Temporal] +---*/ + +const tests = [ + ["1970-01-01T00:00Z[Asia/Kolkata]", "named, with Z"], + ["1970-01-01T00:00Z[!Europe/Vienna]", "named, with Z and !"], + ["1970-01-01T00:00Z[+00:00]", "numeric, with Z"], + ["1970-01-01T00:00Z[!-02:30]", "numeric, with Z and !"], + ["1970-01-01T00:00+00:00[UTC]", "named, with offset"], + ["1970-01-01T00:00+00:00[!Africa/Abidjan]", "named, with offset and !"], + ["1970-01-01T00:00+00:00[-08:00]", "numeric, with offset"], + ["1970-01-01T00:00+00:00[!+01:00]", "numeric, with offset and !"], +]; + +const instance = new Temporal.TimeZone("UTC"); + +tests.forEach(([arg, description]) => { + const result = instance.getOffsetStringFor(arg); + + assert.sameValue( + result, + "+00:00", + `time zone annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-string-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-string-unknown-annotation.js new file mode 100644 index 0000000000..167cc5da5c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-string-unknown-annotation.js @@ -0,0 +1,31 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetstringfor +description: Various forms of unknown annotation +features: [Temporal] +---*/ + +const tests = [ + ["1970-01-01T00:00Z[foo=bar]", "alone"], + ["1970-01-01T00:00Z[UTC][foo=bar]", "with time zone"], + ["1970-01-01T00:00Z[u-ca=iso8601][foo=bar]", "with calendar"], + ["1970-01-01T00:00Z[UTC][foo=bar][u-ca=iso8601]", "with time zone and calendar"], + ["1970-01-01T00:00Z[foo=bar][_foo-bar0=Ignore-This-999999999999]", "with another unknown annotation"], +]; + +const instance = new Temporal.TimeZone("UTC"); + +tests.forEach(([arg, description]) => { + const result = instance.getOffsetStringFor(arg); + + assert.sameValue( + result, + "+00:00", + `unknown annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-wrong-type.js new file mode 100644 index 0000000000..28882da3b8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-wrong-type.js @@ -0,0 +1,40 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetstringfor +description: > + Appropriate error thrown when argument cannot be converted to a valid string + for Instant +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], + [{}, "plain object"], + [Temporal.Instant, "Temporal.Instant, object"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.getOffsetStringFor(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [Temporal.Instant.prototype, "Temporal.Instant.prototype, object"], // fails brand check in toString() +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.getOffsetStringFor(arg), `${description} does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-zoneddatetime.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-zoneddatetime.js new file mode 100644 index 0000000000..9d6e927ebb --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-zoneddatetime.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetstringfor +description: Fast path for converting Temporal.ZonedDateTime to Temporal.Instant +info: | + sec-temporal.timezone.prototype.getoffsetstringfor step 3: + 3. Set _instant_ to ? ToTemporalInstant(_instant_). + sec-temporal-totemporalinstant step 1.b: + b. If _item_ has an [[InitializedTemporalZonedDateTime]] internal slot, then + i. Return ! CreateTemporalInstant(_item_.[[Nanoseconds]]). +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +TemporalHelpers.checkToTemporalInstantFastPath((datetime) => { + const timeZone = Temporal.TimeZone.from("UTC"); + const result = timeZone.getOffsetStringFor(datetime); + assert.sameValue(result, "+00:00", "offset result"); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/basic.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/basic.js new file mode 100644 index 0000000000..4197d97c8d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/basic.js @@ -0,0 +1,23 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetstringfor +description: Basic tests for Temporal.TimeZone.prototype.getOffsetStringFor +features: [BigInt, Temporal] +---*/ + +const instant = new Temporal.Instant(0n); + +function test(timeZoneIdentifier, expectedOffsetString, description) { + const timeZone = new Temporal.TimeZone(timeZoneIdentifier); + assert.sameValue(timeZone.getOffsetStringFor(instant), expectedOffsetString, description); +} + +test("UTC", "+00:00", "offset of UTC is +00:00"); +test("+01:00", "+01:00", "positive offset"); +test("-05:00", "-05:00", "negative offset"); +test("+00:44:59.123456789", "+00:44:59.123456789", "sub-minute offset is not rounded"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/branding.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/branding.js new file mode 100644 index 0000000000..fe9d632cbf --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/branding.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetstringfor +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const getOffsetStringFor = Temporal.TimeZone.prototype.getOffsetStringFor; + +assert.sameValue(typeof getOffsetStringFor, "function"); + +const args = [new Temporal.Instant(0n)]; + +assert.throws(TypeError, () => getOffsetStringFor.apply(undefined, args), "undefined"); +assert.throws(TypeError, () => getOffsetStringFor.apply(null, args), "null"); +assert.throws(TypeError, () => getOffsetStringFor.apply(true, args), "true"); +assert.throws(TypeError, () => getOffsetStringFor.apply("", args), "empty string"); +assert.throws(TypeError, () => getOffsetStringFor.apply(Symbol(), args), "symbol"); +assert.throws(TypeError, () => getOffsetStringFor.apply(1, args), "1"); +assert.throws(TypeError, () => getOffsetStringFor.apply({}, args), "plain object"); +assert.throws(TypeError, () => getOffsetStringFor.apply(Temporal.TimeZone, args), "Temporal.TimeZone"); +assert.throws(TypeError, () => getOffsetStringFor.apply(Temporal.TimeZone.prototype, args), "Temporal.TimeZone.prototype"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/browser.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/builtin.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/builtin.js new file mode 100644 index 0000000000..97df7d3f62 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/builtin.js @@ -0,0 +1,36 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetstringfor +description: > + Tests that Temporal.TimeZone.prototype.getOffsetStringFor + meets the requirements for built-in objects defined by the + introduction of chapter 17 of the ECMAScript Language Specification. +info: | + Built-in functions that are not constructors do not have a "prototype" property unless + otherwise specified in the description of a particular function. + + Unless specified otherwise, a built-in object that is callable as a function is a built-in + function object with the characteristics described in 10.3. Unless specified otherwise, the + [[Extensible]] internal slot of a built-in object initially has the value true. + + Unless otherwise specified every built-in function and every built-in constructor has the + Function prototype object [...] as the value of its [[Prototype]] internal slot. +features: [Temporal] +---*/ + +assert.sameValue(Object.isExtensible(Temporal.TimeZone.prototype.getOffsetStringFor), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.TimeZone.prototype.getOffsetStringFor), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.TimeZone.prototype.getOffsetStringFor), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.TimeZone.prototype.getOffsetStringFor.hasOwnProperty("prototype"), + false, "prototype property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/instant-string-limits.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/instant-string-limits.js new file mode 100644 index 0000000000..2d545fe75c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/instant-string-limits.js @@ -0,0 +1,47 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetstringfor +description: String arguments at the limit of the representable range +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const minInstantStrings = [ + "-271821-04-20T00:00Z", + "-271821-04-19T23:00-01:00", + "-271821-04-19T00:00:00.000000001-23:59:59.999999999", +]; +for (const str of minInstantStrings) { + assert.sameValue(instance.getOffsetStringFor(str), "+00:00", `instant string ${str} should be valid`); +} + +const maxInstantStrings = [ + "+275760-09-13T00:00Z", + "+275760-09-13T01:00+01:00", + "+275760-09-13T23:59:59.999999999+23:59:59.999999999", +]; + +for (const str of maxInstantStrings) { + assert.sameValue(instance.getOffsetStringFor(str), "+00:00", `instant string ${str} should be valid`); +} + +const outOfRangeInstantStrings = [ + "-271821-04-19T23:59:59.999999999Z", + "-271821-04-19T23:00-00:59:59.999999999", + "-271821-04-19T00:00:00-23:59:59.999999999", + "-271821-04-19T00:00:00-24:00", + "+275760-09-13T00:00:00.000000001Z", + "+275760-09-13T01:00+00:59:59.999999999", + "+275760-09-14T00:00+23:59:59.999999999", + "+275760-09-14T00:00+24:00", +]; + +for (const str of outOfRangeInstantStrings) { + assert.throws(RangeError, () => instance.getOffsetStringFor(str), `instant string ${str} should not be valid`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/instant-string.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/instant-string.js new file mode 100644 index 0000000000..8dbd5f649f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/instant-string.js @@ -0,0 +1,34 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetstringfor +description: Conversion of ISO date-time strings to Temporal.Instant instances +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +let str = "1970-01-01T00:00"; +assert.throws(RangeError, () => instance.getOffsetStringFor(str), "bare date-time string is not an instant"); +str = "1970-01-01T00:00[UTC]"; +assert.throws(RangeError, () => instance.getOffsetStringFor(str), "date-time + IANA annotation is not an instant"); + +// The following are all valid strings so should not throw: + +const valids = [ + "1970-01-01T00:00Z", + "1970-01-01T00:00+01:00", + "1970-01-01T00:00Z[UTC]", + "1970-01-01T00:00+01:00[UTC]", + "1970-01-01T00:00Z[u-ca=hebrew]", + "1970-01-01T00:00+01:00[u-ca=hebrew]", + "1970-01-01T00:00+01:00[Etc/Ignored][u-ca=hebrew]", +]; +for (const str of valids) { + const result = instance.getOffsetStringFor(str); + assert.sameValue(result, "+00:00"); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/leap-second.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/leap-second.js new file mode 100644 index 0000000000..735e521d72 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/leap-second.js @@ -0,0 +1,21 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetstringfor +description: Leap second is a valid ISO string for Instant +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const arg = "2016-12-31T23:59:60Z"; +const result = instance.getOffsetStringFor(arg); +assert.sameValue( + result, + "+00:00", + "leap second is a valid ISO string for Instant" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/length.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/length.js new file mode 100644 index 0000000000..55dbee108e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/length.js @@ -0,0 +1,28 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetstringfor +description: Temporal.TimeZone.prototype.getOffsetStringFor.length is 1 +info: | + 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: [Temporal] +---*/ + +verifyProperty(Temporal.TimeZone.prototype.getOffsetStringFor, "length", { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/name.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/name.js new file mode 100644 index 0000000000..2fe5a8f446 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/name.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetstringfor +description: Temporal.TimeZone.prototype.getOffsetStringFor.name is "getOffsetStringFor". +info: | + 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: [Temporal] +---*/ + +verifyProperty(Temporal.TimeZone.prototype.getOffsetStringFor, "name", { + value: "getOffsetStringFor", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/not-a-constructor.js new file mode 100644 index 0000000000..cac868796a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/not-a-constructor.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetstringfor +description: > + Temporal.TimeZone.prototype.getOffsetStringFor does not implement [[Construct]], is not new-able +info: | + Built-in function objects that are not identified as constructors do not implement the + [[Construct]] internal method unless otherwise specified in the description of a particular + function. +includes: [isConstructor.js] +features: [Reflect.construct, Temporal] +---*/ + +assert.throws(TypeError, () => { + new Temporal.TimeZone.prototype.getOffsetStringFor(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.TimeZone.prototype.getOffsetStringFor), false, + "isConstructor(Temporal.TimeZone.prototype.getOffsetStringFor)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/prop-desc.js new file mode 100644 index 0000000000..4e2508ea04 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/prop-desc.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetstringfor +description: The "getOffsetStringFor" property of Temporal.TimeZone.prototype +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.TimeZone.prototype.getOffsetStringFor, + "function", + "`typeof TimeZone.prototype.getOffsetStringFor` is `function`" +); + +verifyProperty(Temporal.TimeZone.prototype, "getOffsetStringFor", { + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/shell.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/shell.js new file mode 100644 index 0000000000..eda1477282 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/shell.js @@ -0,0 +1,24 @@ +// GENERATED, DO NOT EDIT +// file: isConstructor.js +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: | + Test if a given function is a constructor function. +defines: [isConstructor] +features: [Reflect.construct] +---*/ + +function isConstructor(f) { + if (typeof f !== "function") { + throw new Test262Error("isConstructor invoked with a non-function value"); + } + + try { + Reflect.construct(function(){}, [], f); + } catch (e) { + return false; + } + return true; +} diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/timezone-getoffsetnanosecondsfor-non-integer.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/timezone-getoffsetnanosecondsfor-non-integer.js new file mode 100644 index 0000000000..dfd196a6ae --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/timezone-getoffsetnanosecondsfor-non-integer.js @@ -0,0 +1,18 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetstringfor +description: RangeError thrown if time zone reports an offset that is not an integer number of nanoseconds +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +[3600_000_000_000.5, NaN, -Infinity, Infinity].forEach((wrongOffset) => { + const timeZone = TemporalHelpers.specificOffsetTimeZone(wrongOffset); + const instant = new Temporal.Instant(1_000_000_000_987_654_321n); + assert.throws(RangeError, () => timeZone.getOffsetStringFor(instant)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/timezone-getoffsetnanosecondsfor-not-callable.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/timezone-getoffsetnanosecondsfor-not-callable.js new file mode 100644 index 0000000000..68cfdb2053 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/timezone-getoffsetnanosecondsfor-not-callable.js @@ -0,0 +1,22 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetstringfor +description: TypeError thrown if timeZone.getOffsetNanosecondsFor is not callable +features: [BigInt, Symbol, Temporal, arrow-function] +---*/ + +[undefined, null, true, Math.PI, 'string', Symbol('sym'), 42n, {}].forEach((notCallable) => { + const timeZone = new Temporal.TimeZone("UTC"); + const instant = new Temporal.Instant(1_000_000_000_987_654_321n); + timeZone.getOffsetNanosecondsFor = notCallable; + assert.throws( + TypeError, + () => timeZone.getOffsetStringFor(instant), + `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/timezone-getoffsetnanosecondsfor-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/timezone-getoffsetnanosecondsfor-out-of-range.js new file mode 100644 index 0000000000..bfc4719164 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/timezone-getoffsetnanosecondsfor-out-of-range.js @@ -0,0 +1,18 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetstringfor +description: RangeError thrown if time zone reports an offset that is out of range +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +[-86400_000_000_000, 86400_000_000_000].forEach((wrongOffset) => { + const timeZone = TemporalHelpers.specificOffsetTimeZone(wrongOffset); + const instant = new Temporal.Instant(1_000_000_000_987_654_321n); + assert.throws(RangeError, () => timeZone.getOffsetStringFor(instant)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/timezone-getoffsetnanosecondsfor-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/timezone-getoffsetnanosecondsfor-wrong-type.js new file mode 100644 index 0000000000..85e92e530f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/timezone-getoffsetnanosecondsfor-wrong-type.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetstringfor +description: TypeError thrown if time zone reports an offset that is not a Number +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +[ + undefined, + null, + true, + "+01:00", + Symbol(), + 3600_000_000_000n, + {}, + { valueOf() { return 3600_000_000_000; } }, +].forEach((wrongOffset) => { + const timeZone = TemporalHelpers.specificOffsetTimeZone(wrongOffset); + const instant = new Temporal.Instant(1_000_000_000_987_654_321n); + assert.throws(TypeError, () => timeZone.getOffsetStringFor(instant)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/year-zero.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/year-zero.js new file mode 100644 index 0000000000..79dd07eec5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/year-zero.js @@ -0,0 +1,25 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetstringfor +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-03-30T00:45Z", + "-000000-03-30T01:45+01:00", + "-000000-03-30T01:45:00+00:00[UTC]", +]; +const instance = new Temporal.TimeZone("UTC"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.getOffsetStringFor(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-negative-epochnanoseconds.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-negative-epochnanoseconds.js new file mode 100644 index 0000000000..4c3ab883a5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-negative-epochnanoseconds.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: A pre-epoch value is handled correctly by the modulo operation in GetISOPartsFromEpoch +info: | + sec-temporal-getisopartsfromepoch step 1: + 1. Let _remainderNs_ be the mathematical value whose sign is the sign of _epochNanoseconds_ and whose magnitude is abs(_epochNanoseconds_) modulo 10<sup>6</sup>. + sec-temporal-builtintimezonegetplaindatetimefor step 2: + 2. Let _result_ be ! GetISOPartsFromEpoch(_instant_.[[Nanoseconds]]). +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const instant = new Temporal.Instant(-13849764_999_999_999n); + +// This code path shows up anywhere we convert an exact time, before the Unix +// epoch, with nonzero microseconds or nanoseconds, into a wall time. + +const instance = new Temporal.TimeZone("UTC"); +const result = instance.getPlainDateTimeFor(instant); +TemporalHelpers.assertPlainDateTime(result, 1969, 7, "M07", 24, 16, 50, 35, 0, 0, 1); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-not-absolute-getOffsetNanosecondsFor-override.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-not-absolute-getOffsetNanosecondsFor-override.js new file mode 100644 index 0000000000..961f33be1a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-not-absolute-getOffsetNanosecondsFor-override.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: timeZone.getOffsetNanosecondsFor not called when argument cannot be converted to Temporal.Instant +features: [Temporal] +---*/ + +const timeZone = Temporal.TimeZone.from("UTC"); +let called = false; +timeZone.getOffsetNanosecondsFor = () => called = true; +assert.throws(RangeError, () => timeZone.getPlainDateTimeFor(undefined), "undefined"); +assert.throws(RangeError, () => timeZone.getPlainDateTimeFor(null), "null"); +assert.throws(RangeError, () => timeZone.getPlainDateTimeFor(true), "boolean"); +assert.throws(RangeError, () => timeZone.getPlainDateTimeFor(""), "empty string"); +assert.throws(TypeError, () => timeZone.getPlainDateTimeFor(Symbol()), "Symbol"); +assert.throws(RangeError, () => timeZone.getPlainDateTimeFor(5), "number"); +assert.throws(RangeError, () => timeZone.getPlainDateTimeFor(5n), "bigint"); +assert.throws(RangeError, () => timeZone.getPlainDateTimeFor({}), "plain object"); +assert.sameValue(called, false); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-object-tostring.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-object-tostring.js new file mode 100644 index 0000000000..0e03565ed9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-object-tostring.js @@ -0,0 +1,23 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: Object is converted to a string, then to Temporal.Instant +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const arg = {}; +assert.throws(RangeError, () => instance.getPlainDateTimeFor(arg), "[object Object] is not a valid ISO string"); + +arg.toString = function() { + return "1970-01-01T00:00Z"; +}; +const result = instance.getPlainDateTimeFor(arg); +TemporalHelpers.assertPlainDateTime(result, 1970, 1, "M01", 1, 0, 0, 0, 0, 0, 0, "result of toString is interpreted as ISO string"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-string-calendar-annotation.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-string-calendar-annotation.js new file mode 100644 index 0000000000..067ef05feb --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-string-calendar-annotation.js @@ -0,0 +1,35 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: Various forms of calendar annotation; critical flag has no effect +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const tests = [ + ["1970-01-01T00:00Z[u-ca=iso8601]", "without time zone"], + ["1970-01-01T00:00Z[UTC][u-ca=gregory]", "with time zone"], + ["1970-01-01T00:00Z[!u-ca=hebrew]", "with ! and no time zone"], + ["1970-01-01T00:00Z[UTC][!u-ca=chinese]", "with ! and time zone"], + ["1970-01-01T00:00Z[u-ca=discord]", "annotation is ignored"], + ["1970-01-01T00:00Z[!u-ca=discord]", "annotation with ! is ignored"], + ["1970-01-01T00:00Z[u-ca=iso8601][u-ca=discord]", "two annotations are ignored"], + ["1970-01-01T00:00Z[u-ca=iso8601][!u-ca=discord]", "two annotations are ignored even with !"], +]; + +const instance = new Temporal.TimeZone("UTC"); + +tests.forEach(([arg, description]) => { + const result = instance.getPlainDateTimeFor(arg); + + TemporalHelpers.assertPlainDateTime( + result, + 1970, 1, "M01", 1, 0, 0, 0, 0, 0, 0, + `calendar annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-string-critical-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-string-critical-unknown-annotation.js new file mode 100644 index 0000000000..a992d46c23 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-string-critical-unknown-annotation.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: Unknown annotations with critical flag are rejected +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01T00:00Z[!foo=bar]", + "1970-01-01T00:00Z[UTC][!foo=bar]", + "1970-01-01T00:00Z[u-ca=iso8601][!foo=bar]", + "1970-01-01T00:00Z[UTC][!foo=bar][u-ca=iso8601]", + "1970-01-01T00:00Z[foo=bar][!_foo-bar0=Dont-Ignore-This-99999999999]", +]; +const instance = new Temporal.TimeZone("UTC"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.getPlainDateTimeFor(arg), + `reject unknown annotation with critical flag: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-string-date-with-utc-offset.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-string-date-with-utc-offset.js new file mode 100644 index 0000000000..163f8dff06 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-string-date-with-utc-offset.js @@ -0,0 +1,53 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: UTC offset not valid with format that does not include a time +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const validStrings = [ + "1970-01-01T00Z", + "1970-01-01T00Z[UTC]", + "1970-01-01T00Z[!UTC]", + "1970-01-01T00Z[Europe/Vienna]", + "1970-01-01T00+00:00", + "1970-01-01T00+00:00[UTC]", + "1970-01-01T00+00:00[!UTC]", + "1969-12-31T16-08:00[America/Vancouver]", +]; + +for (const arg of validStrings) { + const result = instance.getPlainDateTimeFor(arg); + + TemporalHelpers.assertPlainDateTime( + result, + 1970, 1, "M01", 1, 0, 0, 0, 0, 0, 0, + `"${arg}" is a valid UTC offset with time for Instant` + ); +} + +const invalidStrings = [ + "2022-09-15Z", + "2022-09-15Z[UTC]", + "2022-09-15Z[Europe/Vienna]", + "2022-09-15+00:00", + "2022-09-15+00:00[UTC]", + "2022-09-15-02:30", + "2022-09-15-02:30[America/St_Johns]", +]; + +for (const arg of invalidStrings) { + assert.throws( + RangeError, + () => instance.getPlainDateTimeFor(arg), + `"${arg}" UTC offset without time is not valid for Instant` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-string-invalid.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-string-invalid.js new file mode 100644 index 0000000000..97282bed90 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-string-invalid.js @@ -0,0 +1,69 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: > + RangeError thrown if an invalid ISO string (or syntactically valid ISO string + that is not supported) is used as an Instant +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + // invalid ISO strings: + "", + "invalid iso8601", + "2020-01-00T00:00Z", + "2020-01-32T00:00Z", + "2020-02-30T00:00Z", + "2021-02-29T00:00Z", + "2020-00-01T00:00Z", + "2020-13-01T00:00Z", + "2020-01-01TZ", + "2020-01-01T25:00:00Z", + "2020-01-01T01:60:00Z", + "2020-01-01T01:60:61Z", + "2020-01-01T00:00Zjunk", + "2020-01-01T00:00:00Zjunk", + "2020-01-01T00:00:00.000000000Zjunk", + "2020-01-01T00:00:00+00:00junk", + "2020-01-01T00:00:00+00:00[UTC]junk", + "2020-01-01T00:00:00+00:00[UTC][u-ca=iso8601]junk", + "02020-01-01T00:00Z", + "2020-001-01T00:00Z", + "2020-01-001T00:00Z", + "2020-01-01T001Z", + "2020-01-01T01:001Z", + "2020-01-01T01:01:001Z", + // valid, but forms not supported in Temporal: + "2020-W01-1T00:00Z", + "2020-001T00:00Z", + "+0002020-01-01T00:00Z", + // may be valid in other contexts, but insufficient information for Instant: + "2020-01", + "+002020-01", + "01-01", + "2020-W01", + "P1Y", + "-P12Y", + "2020-01-01", + "2020-01-01T00", + "2020-01-01T00:00", + "2020-01-01T00:00:00", + "2020-01-01T00:00:00.000000000", + // valid, but outside the supported range: + "-999999-01-01T00:00Z", + "+999999-01-01T00:00Z", +]; + +const instance = new Temporal.TimeZone("UTC"); +for (const arg of invalidStrings) { + assert.throws( + RangeError, + () => instance.getPlainDateTimeFor(arg), + `"${arg}" should not be a valid ISO string for an Instant` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-string-multiple-time-zone.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-string-multiple-time-zone.js new file mode 100644 index 0000000000..c09995f484 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-string-multiple-time-zone.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: More than one time zone annotation is not syntactical +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01T00:00Z[UTC][UTC]", + "1970-01-01T00:00Z[!UTC][UTC]", + "1970-01-01T00:00Z[UTC][!UTC]", + "1970-01-01T00:00Z[UTC][u-ca=iso8601][UTC]", + "1970-01-01T00:00Z[UTC][foo=bar][UTC]", +]; +const instance = new Temporal.TimeZone("UTC"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.getPlainDateTimeFor(arg), + `reject more than one time zone annotation: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-string-time-separators.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-string-time-separators.js new file mode 100644 index 0000000000..db5a6a0d38 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-string-time-separators.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: Time separator in string argument can vary +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const tests = [ + ["1970-01-01T00:00Z", "uppercase T"], + ["1970-01-01t00:00Z", "lowercase T"], + ["1970-01-01 00:00Z", "space between date and time"], +]; + +const instance = new Temporal.TimeZone("UTC"); + +tests.forEach(([arg, description]) => { + const result = instance.getPlainDateTimeFor(arg); + + TemporalHelpers.assertPlainDateTime( + result, + 1970, 1, "M01", 1, 0, 0, 0, 0, 0, 0, + `variant time separators (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-string-time-zone-annotation.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-string-time-zone-annotation.js new file mode 100644 index 0000000000..d8df435235 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-string-time-zone-annotation.js @@ -0,0 +1,35 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: Various forms of time zone annotation; critical flag has no effect +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const tests = [ + ["1970-01-01T00:00Z[Asia/Kolkata]", "named, with Z"], + ["1970-01-01T00:00Z[!Europe/Vienna]", "named, with Z and !"], + ["1970-01-01T00:00Z[+00:00]", "numeric, with Z"], + ["1970-01-01T00:00Z[!-02:30]", "numeric, with Z and !"], + ["1970-01-01T00:00+00:00[UTC]", "named, with offset"], + ["1970-01-01T00:00+00:00[!Africa/Abidjan]", "named, with offset and !"], + ["1970-01-01T00:00+00:00[-08:00]", "numeric, with offset"], + ["1970-01-01T00:00+00:00[!+01:00]", "numeric, with offset and !"], +]; + +const instance = new Temporal.TimeZone("UTC"); + +tests.forEach(([arg, description]) => { + const result = instance.getPlainDateTimeFor(arg); + + TemporalHelpers.assertPlainDateTime( + result, + 1970, 1, "M01", 1, 0, 0, 0, 0, 0, 0, + `time zone annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-string-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-string-unknown-annotation.js new file mode 100644 index 0000000000..296c52e093 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-string-unknown-annotation.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: Various forms of unknown annotation +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const tests = [ + ["1970-01-01T00:00Z[foo=bar]", "alone"], + ["1970-01-01T00:00Z[UTC][foo=bar]", "with time zone"], + ["1970-01-01T00:00Z[u-ca=iso8601][foo=bar]", "with calendar"], + ["1970-01-01T00:00Z[UTC][foo=bar][u-ca=iso8601]", "with time zone and calendar"], + ["1970-01-01T00:00Z[foo=bar][_foo-bar0=Ignore-This-999999999999]", "with another unknown annotation"], +]; + +const instance = new Temporal.TimeZone("UTC"); + +tests.forEach(([arg, description]) => { + const result = instance.getPlainDateTimeFor(arg); + + TemporalHelpers.assertPlainDateTime( + result, + 1970, 1, "M01", 1, 0, 0, 0, 0, 0, 0, + `unknown annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-wrong-type.js new file mode 100644 index 0000000000..8cc8552b6d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-wrong-type.js @@ -0,0 +1,40 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: > + Appropriate error thrown when argument cannot be converted to a valid string + for Instant +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], + [{}, "plain object"], + [Temporal.Instant, "Temporal.Instant, object"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.getPlainDateTimeFor(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [Temporal.Instant.prototype, "Temporal.Instant.prototype, object"], // fails brand check in toString() +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.getPlainDateTimeFor(arg), `${description} does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-zoneddatetime.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-zoneddatetime.js new file mode 100644 index 0000000000..983a8edf2b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-zoneddatetime.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: Fast path for converting Temporal.ZonedDateTime to Temporal.Instant +info: | + sec-temporal.timezone.prototype.getplaindatetimefor step 2: + 2. Set _instant_ to ? ToTemporalInstant(_instant_). + sec-temporal-totemporalinstant step 1.b: + b. If _item_ has an [[InitializedTemporalZonedDateTime]] internal slot, then + i. Return ! CreateTemporalInstant(_item_.[[Nanoseconds]]). +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +TemporalHelpers.checkToTemporalInstantFastPath((datetime) => { + const timeZone = Temporal.TimeZone.from("UTC"); + const result = timeZone.getPlainDateTimeFor(datetime); + TemporalHelpers.assertPlainDateTime(result, 2001, 9, "M09", 9, 1, 46, 40, 987, 654, 321); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/balance-negative-time-units.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/balance-negative-time-units.js new file mode 100644 index 0000000000..f623639af0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/balance-negative-time-units.js @@ -0,0 +1,42 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: Negative time fields are balanced upwards +info: | + sec-temporal-balancetime steps 3–14: + 3. Set _microsecond_ to _microsecond_ + floor(_nanosecond_ / 1000). + 4. Set _nanosecond_ to _nanosecond_ modulo 1000. + 5. Set _millisecond_ to _millisecond_ + floor(_microsecond_ / 1000). + 6. Set _microsecond_ to _microsecond_ modulo 1000. + 7. Set _second_ to _second_ + floor(_millisecond_ / 1000). + 8. Set _millisecond_ to _millisecond_ modulo 1000. + 9. Set _minute_ to _minute_ + floor(_second_ / 60). + 10. Set _second_ to _second_ modulo 60. + 11. Set _hour_ to _hour_ + floor(_minute_ / 60). + 12. Set _minute_ to _minute_ modulo 60. + 13. Let _days_ be floor(_hour_ / 24). + 14. Set _hour_ to _hour_ modulo 24. + sec-temporal-balanceisodatetime step 1: + 1. Let _balancedTime_ be ? BalanceTime(_hour_, _minute_, _second_, _millisecond_, _microsecond_, _nanosecond_). + sec-temporal-builtintimezonegetplaindatetimefor step 3: + 3. Set _result_ to ? BalanceISODateTime(_result_.[[Year]], _result_.[[Month]], _result_.[[Day]], _result_.[[Hour]], _result_.[[Minute]], _result_.[[Second]], _result_.[[Millisecond]], _result_.[[Microsecond]], _result_.[[Nanosecond]] + _offsetNanoseconds_). + sec-get-temporal.timezone.prototype.getplaindatetimefor step 4: + 4. Return ? BuiltinTimeZoneGetPlainDateTimeFor(_timeZone_, _instant_, _calendar_). +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +// This code path is encountered if the time zone offset is negative and its +// absolute value in nanoseconds is greater than the nanosecond field of the +// exact time's epoch parts +const tz = new Temporal.TimeZone("-00:00:00.000000002"); +const instant = new Temporal.Instant(1001n); + +const pdt = tz.getPlainDateTimeFor(instant); + +TemporalHelpers.assertPlainDateTime(pdt, 1970, 1, "M01", 1, 0, 0, 0, 0, 0, 999); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/branding.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/branding.js new file mode 100644 index 0000000000..fc13d54f30 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/branding.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const getPlainDateTimeFor = Temporal.TimeZone.prototype.getPlainDateTimeFor; + +assert.sameValue(typeof getPlainDateTimeFor, "function"); + +const args = [new Temporal.Instant(0n)]; + +assert.throws(TypeError, () => getPlainDateTimeFor.apply(undefined, args), "undefined"); +assert.throws(TypeError, () => getPlainDateTimeFor.apply(null, args), "null"); +assert.throws(TypeError, () => getPlainDateTimeFor.apply(true, args), "true"); +assert.throws(TypeError, () => getPlainDateTimeFor.apply("", args), "empty string"); +assert.throws(TypeError, () => getPlainDateTimeFor.apply(Symbol(), args), "symbol"); +assert.throws(TypeError, () => getPlainDateTimeFor.apply(1, args), "1"); +assert.throws(TypeError, () => getPlainDateTimeFor.apply({}, args), "plain object"); +assert.throws(TypeError, () => getPlainDateTimeFor.apply(Temporal.TimeZone, args), "Temporal.TimeZone"); +assert.throws(TypeError, () => getPlainDateTimeFor.apply(Temporal.TimeZone.prototype, args), "Temporal.TimeZone.prototype"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/browser.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/builtin.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/builtin.js new file mode 100644 index 0000000000..6a474266aa --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/builtin.js @@ -0,0 +1,36 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: > + Tests that Temporal.TimeZone.prototype.getPlainDateTimeFor + meets the requirements for built-in objects defined by the + introduction of chapter 17 of the ECMAScript Language Specification. +info: | + Built-in functions that are not constructors do not have a "prototype" property unless + otherwise specified in the description of a particular function. + + Unless specified otherwise, a built-in object that is callable as a function is a built-in + function object with the characteristics described in 10.3. Unless specified otherwise, the + [[Extensible]] internal slot of a built-in object initially has the value true. + + Unless otherwise specified every built-in function and every built-in constructor has the + Function prototype object [...] as the value of its [[Prototype]] internal slot. +features: [Temporal] +---*/ + +assert.sameValue(Object.isExtensible(Temporal.TimeZone.prototype.getPlainDateTimeFor), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.TimeZone.prototype.getPlainDateTimeFor), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.TimeZone.prototype.getPlainDateTimeFor), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.TimeZone.prototype.getPlainDateTimeFor.hasOwnProperty("prototype"), + false, "prototype property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-case-insensitive.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-case-insensitive.js new file mode 100644 index 0000000000..55643b04ee --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-case-insensitive.js @@ -0,0 +1,17 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: Calendar names are case-insensitive +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const arg = "iSo8601"; +const result = instance.getPlainDateTimeFor(new Temporal.Instant(0n), arg); +assert.sameValue(result.calendar.id, "iso8601", "Calendar is case-insensitive"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-instance-does-not-get-calendar-property.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-instance-does-not-get-calendar-property.js new file mode 100644 index 0000000000..816c876781 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-instance-does-not-get-calendar-property.js @@ -0,0 +1,25 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: > + A Temporal.Calendar instance passed to getPlainDateTimeFor() does not have its + 'calendar' property observably checked +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const arg = new Temporal.Calendar("iso8601"); +Object.defineProperty(arg, "calendar", { + get() { + throw new Test262Error("calendar.calendar should not be accessed"); + }, +}); + +instance.getPlainDateTimeFor(new Temporal.Instant(0n), arg); +instance.getPlainDateTimeFor(new Temporal.Instant(0n), { calendar: arg }); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-number.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-number.js new file mode 100644 index 0000000000..fd265b0a18 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-number.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: A number is converted to a string, then to Temporal.Calendar +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const arg = 19761118; + +const result = instance.getPlainDateTimeFor(new Temporal.Instant(0n), arg); +assert.sameValue(result.calendar.id, "iso8601", "19761118 is a valid ISO string for Calendar"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.getPlainDateTimeFor(new Temporal.Instant(0n), arg), + `Number ${arg} does not convert to a valid ISO string for Calendar` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-string-leap-second.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-string-leap-second.js new file mode 100644 index 0000000000..407906e0e1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-string-leap-second.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: Leap second is a valid ISO string for Calendar +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.getPlainDateTimeFor(new Temporal.Instant(0n), arg); +assert.sameValue( + result1.calendar.id, + "iso8601", + "leap second is a valid ISO string for Calendar" +); + +arg = { calendar: "2016-12-31T23:59:60" }; +const result2 = instance.getPlainDateTimeFor(new Temporal.Instant(0n), arg); +assert.sameValue( + result2.calendar.id, + "iso8601", + "leap second is a valid ISO string for Calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-string.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-string.js new file mode 100644 index 0000000000..d266d72d9c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-string.js @@ -0,0 +1,18 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: A calendar ID is valid input for Calendar +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const arg = "iso8601"; + +const result = instance.getPlainDateTimeFor(new Temporal.Instant(0n), arg); +assert.sameValue(result.calendar.id, "iso8601", `Calendar created from string "${arg}"`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-temporal-object.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-temporal-object.js new file mode 100644 index 0000000000..f3b1d8033c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-temporal-object.js @@ -0,0 +1,43 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots +info: | + sec-temporal-totemporalcalendar step 1.b: + b. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then + i. Return _temporalCalendarLike_.[[Calendar]]. +includes: [compareArray.js] +features: [Temporal] +---*/ + +const plainDate = new Temporal.PlainDate(2000, 5, 2); +const plainDateTime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); +const plainTime = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); +const plainMonthDay = new Temporal.PlainMonthDay(5, 2); +const plainYearMonth = new Temporal.PlainYearMonth(2000, 5); +const zonedDateTime = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); + +[plainDate, plainDateTime, plainTime, plainMonthDay, plainYearMonth, zonedDateTime].forEach((arg) => { + const actual = []; + const expected = []; + + const calendar = arg.getISOFields().calendar; + + Object.defineProperty(arg, "calendar", { + get() { + actual.push("get calendar"); + return calendar; + }, + }); + + const instance = new Temporal.TimeZone("UTC"); + const result = instance.getPlainDateTimeFor(new Temporal.Instant(0n), arg); + assert.sameValue(result.calendar, calendar, "Temporal object coerced to calendar"); + + assert.compareArray(actual, expected, "calendar getter not called"); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-undefined.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-undefined.js new file mode 100644 index 0000000000..38eae262e9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-undefined.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: Calendar argument defaults to the built-in ISO 8601 calendar +features: [Temporal] +---*/ + +const instant = Temporal.Instant.from("1975-02-02T14:25:36.123456789Z"); +const timeZone = Temporal.TimeZone.from("UTC"); + +Object.defineProperty(Temporal.Calendar, "from", { + get() { + throw new Test262Error("Should not call Calendar.from"); + }, +}); + +const result1 = timeZone.getPlainDateTimeFor(instant); +assert.sameValue(result1.calendar.toString(), "iso8601"); + +const result2 = timeZone.getPlainDateTimeFor(instant, undefined); +assert.sameValue(result2.calendar.toString(), "iso8601"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-wrong-type.js new file mode 100644 index 0000000000..285acda192 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-wrong-type.js @@ -0,0 +1,38 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for Calendar +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], + [new Temporal.TimeZone("UTC"), "time zone instance"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.getPlainDateTimeFor(new Temporal.Instant(0n), arg), `${description} does not convert to a valid ISO string`); + assert.throws(RangeError, () => instance.getPlainDateTimeFor(new Temporal.Instant(0n), { calendar: arg }), `${description} does not convert to a valid ISO string (in property bag)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.getPlainDateTimeFor(new Temporal.Instant(0n), arg), `${description} is not a valid object and does not convert to a string`); + assert.throws(TypeError, () => instance.getPlainDateTimeFor(new Temporal.Instant(0n), { calendar: arg }), `${description} is not a valid object and does not convert to a string (in property bag)`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/custom-timezone.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/custom-timezone.js new file mode 100644 index 0000000000..e53343cc6f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/custom-timezone.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: getOffsetNanosecondsFor is called by getPlainDateTimeFor +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const actual = []; +const expected = [ + "get getOffsetNanosecondsFor", + "call timeZone.getOffsetNanosecondsFor", +]; + +const instant = Temporal.Instant.from("1975-02-02T14:25:36.123456789Z"); +const timeZone = new Temporal.TimeZone("UTC"); +TemporalHelpers.observeProperty(actual, timeZone, "getOffsetNanosecondsFor", function (instantArg) { + actual.push("call timeZone.getOffsetNanosecondsFor"); + assert.sameValue(instantArg, instant); + return 9876543210123; +}); + +const result = timeZone.getPlainDateTimeFor(instant); +TemporalHelpers.assertPlainDateTime(result, 1975, 2, "M02", 2, 17, 10, 12, 666, 666, 912); +assert.compareArray(actual, expected); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/instant-string-limits.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/instant-string-limits.js new file mode 100644 index 0000000000..853e517d6b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/instant-string-limits.js @@ -0,0 +1,48 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: String arguments at the limit of the representable range +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const minInstantStrings = [ + "-271821-04-20T00:00Z", + "-271821-04-19T23:00-01:00", + "-271821-04-19T00:00:00.000000001-23:59:59.999999999", +]; +for (const str of minInstantStrings) { + TemporalHelpers.assertPlainDateTime(instance.getPlainDateTimeFor(str), -271821, 4, "M04", 20, 0, 0, 0, 0, 0, 0, `instant string ${str} should be valid`); +} + +const maxInstantStrings = [ + "+275760-09-13T00:00Z", + "+275760-09-13T01:00+01:00", + "+275760-09-13T23:59:59.999999999+23:59:59.999999999", +]; + +for (const str of maxInstantStrings) { + TemporalHelpers.assertPlainDateTime(instance.getPlainDateTimeFor(str), 275760, 9, "M09", 13, 0, 0, 0, 0, 0, 0, `instant string ${str} should be valid`); +} + +const outOfRangeInstantStrings = [ + "-271821-04-19T23:59:59.999999999Z", + "-271821-04-19T23:00-00:59:59.999999999", + "-271821-04-19T00:00:00-23:59:59.999999999", + "-271821-04-19T00:00:00-24:00", + "+275760-09-13T00:00:00.000000001Z", + "+275760-09-13T01:00+00:59:59.999999999", + "+275760-09-14T00:00+23:59:59.999999999", + "+275760-09-14T00:00+24:00", +]; + +for (const str of outOfRangeInstantStrings) { + assert.throws(RangeError, () => instance.getPlainDateTimeFor(str), `instant string ${str} should not be valid`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/instant-string-multiple-offsets.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/instant-string-multiple-offsets.js new file mode 100644 index 0000000000..2e6d22b434 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/instant-string-multiple-offsets.js @@ -0,0 +1,18 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: Instant strings with UTC offset fractional part are not confused with time fractional part +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); +const str = "1970-01-01T00:02:00.000000000+00:02[+00:01:30.987654321]"; + +const result = instance.getPlainDateTimeFor(str); +TemporalHelpers.assertPlainDateTime(result, 1970, 1, "M01", 1, 0, 0, 0, 0, 0, 0, "UTC offset determined from offset part of string"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/instant-string-sub-minute-offset.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/instant-string-sub-minute-offset.js new file mode 100644 index 0000000000..c74ea96f9c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/instant-string-sub-minute-offset.js @@ -0,0 +1,18 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: Temporal.Instant string with sub-minute offset +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const str = "1970-01-01T00:19:32.37+00:19:32.37"; +const result = instance.getPlainDateTimeFor(str); +TemporalHelpers.assertPlainDateTime(result, 1970, 1, "M01", 1, 0, 0, 0, 0, 0, 0, "if present, sub-minute offset is accepted exactly"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/instant-string.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/instant-string.js new file mode 100644 index 0000000000..5d3223579d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/instant-string.js @@ -0,0 +1,47 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: Conversion of ISO date-time strings to Temporal.Instant instances +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +let str = "1970-01-01T00:00"; +assert.throws(RangeError, () => instance.getPlainDateTimeFor(str), "bare date-time string is not an instant"); +str = "1970-01-01T00:00[UTC]"; +assert.throws(RangeError, () => instance.getPlainDateTimeFor(str), "date-time + IANA annotation is not an instant"); + +str = "1970-01-01T00:00Z"; +const result1 = instance.getPlainDateTimeFor(str); +TemporalHelpers.assertPlainDateTime(result1, 1970, 1, "M01", 1, 0, 0, 0, 0, 0, 0, "date-time + Z preserves exact time"); + +str = "1970-01-01T00:00+01:00"; +const result2 = instance.getPlainDateTimeFor(str); +TemporalHelpers.assertPlainDateTime(result2, 1969, 12, "M12", 31, 23, 0, 0, 0, 0, 0, "date-time + offset preserves exact time with offset"); + +str = "1970-01-01T00:00Z[Etc/Ignored]"; +const result3 = instance.getPlainDateTimeFor(str); +TemporalHelpers.assertPlainDateTime(result3, 1970, 1, "M01", 1, 0, 0, 0, 0, 0, 0, "date-time + Z + IANA annotation ignores the IANA annotation"); + +str = "1970-01-01T00:00+01:00[Etc/Ignored]"; +const result4 = instance.getPlainDateTimeFor(str); +TemporalHelpers.assertPlainDateTime(result4, 1969, 12, "M12", 31, 23, 0, 0, 0, 0, 0, "date-time + offset + IANA annotation ignores the IANA annotation"); + +str = "1970-01-01T00:00Z[u-ca=hebrew]"; +const result6 = instance.getPlainDateTimeFor(str); +TemporalHelpers.assertPlainDateTime(result6, 1970, 1, "M01", 1, 0, 0, 0, 0, 0, 0, "date-time + Z + Calendar ignores the Calendar"); + +str = "1970-01-01T00:00+01:00[u-ca=hebrew]"; +const result5 = instance.getPlainDateTimeFor(str); +TemporalHelpers.assertPlainDateTime(result5, 1969, 12, "M12", 31, 23, 0, 0, 0, 0, 0, "date-time + offset + Calendar ignores the Calendar"); + +str = "1970-01-01T00:00+01:00[Etc/Ignored][u-ca=hebrew]"; +const result7 = instance.getPlainDateTimeFor(str); +TemporalHelpers.assertPlainDateTime(result7, 1969, 12, "M12", 31, 23, 0, 0, 0, 0, 0, "date-time + offset + IANA annotation + Calendar ignores the Calendar and IANA annotation"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/leap-second.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/leap-second.js new file mode 100644 index 0000000000..0f23b5b15b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/leap-second.js @@ -0,0 +1,22 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: Leap second is a valid ISO string for Instant +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const arg = "2016-12-31T23:59:60Z"; +const result = instance.getPlainDateTimeFor(arg); +TemporalHelpers.assertPlainDateTime( + result, + 2016, 12, "M12", 31, 23, 59, 59, 0, 0, 0, + "leap second is a valid ISO string for Instant" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/length.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/length.js new file mode 100644 index 0000000000..7f2a83d61d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/length.js @@ -0,0 +1,28 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: Temporal.TimeZone.prototype.getPlainDateTimeFor.length is 1 +info: | + 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: [Temporal] +---*/ + +verifyProperty(Temporal.TimeZone.prototype.getPlainDateTimeFor, "length", { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/limits.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/limits.js new file mode 100644 index 0000000000..11962466fb --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/limits.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.getplaindatetimefor +description: Checking limits of representable PlainDateTime +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const min = new Temporal.Instant(-8_640_000_000_000_000_000_000n); +const offsetMin = new Temporal.TimeZone("-23:59"); +const max = new Temporal.Instant(8_640_000_000_000_000_000_000n); +const offsetMax = new Temporal.TimeZone("+23:59"); + +TemporalHelpers.assertPlainDateTime( + offsetMin.getPlainDateTimeFor(min, "iso8601"), + -271821, 4, "M04", 19, 0, 1, 0, 0, 0, 0, + "converting from Instant (negative case)" +); + +TemporalHelpers.assertPlainDateTime( + offsetMax.getPlainDateTimeFor(max, "iso8601"), + 275760, 9, "M09", 13, 23, 59, 0, 0, 0, 0, + "converting from Instant (positive case)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/name.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/name.js new file mode 100644 index 0000000000..517769b7b7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/name.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: Temporal.TimeZone.prototype.getPlainDateTimeFor.name is "getPlainDateTimeFor". +info: | + 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: [Temporal] +---*/ + +verifyProperty(Temporal.TimeZone.prototype.getPlainDateTimeFor, "name", { + value: "getPlainDateTimeFor", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/not-a-constructor.js new file mode 100644 index 0000000000..2cd2575120 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/not-a-constructor.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: > + Temporal.TimeZone.prototype.getPlainDateTimeFor does not implement [[Construct]], is not new-able +info: | + Built-in function objects that are not identified as constructors do not implement the + [[Construct]] internal method unless otherwise specified in the description of a particular + function. +includes: [isConstructor.js] +features: [Reflect.construct, Temporal] +---*/ + +assert.throws(TypeError, () => { + new Temporal.TimeZone.prototype.getPlainDateTimeFor(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.TimeZone.prototype.getPlainDateTimeFor), false, + "isConstructor(Temporal.TimeZone.prototype.getPlainDateTimeFor)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/pre-epoch.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/pre-epoch.js new file mode 100644 index 0000000000..082d6c8728 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/pre-epoch.js @@ -0,0 +1,18 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: Test of basic functionality for an exact time earlier than the Unix epoch +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instant = Temporal.Instant.from("1969-07-16T13:32:01.234567891Z"); +assert.sameValue(instant.toString(), "1969-07-16T13:32:01.234567891Z"); +const timeZone = Temporal.TimeZone.from("-04:00"); +const dateTime = timeZone.getPlainDateTimeFor(instant); +TemporalHelpers.assertPlainDateTime(dateTime, 1969, 7, "M07", 16, 9, 32, 1, 234, 567, 891); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/prop-desc.js new file mode 100644 index 0000000000..c45fdc7974 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/prop-desc.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: The "getPlainDateTimeFor" property of Temporal.TimeZone.prototype +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.TimeZone.prototype.getPlainDateTimeFor, + "function", + "`typeof TimeZone.prototype.getPlainDateTimeFor` is `function`" +); + +verifyProperty(Temporal.TimeZone.prototype, "getPlainDateTimeFor", { + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/shell.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/shell.js new file mode 100644 index 0000000000..eda1477282 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/shell.js @@ -0,0 +1,24 @@ +// GENERATED, DO NOT EDIT +// file: isConstructor.js +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: | + Test if a given function is a constructor function. +defines: [isConstructor] +features: [Reflect.construct] +---*/ + +function isConstructor(f) { + if (typeof f !== "function") { + throw new Test262Error("isConstructor invoked with a non-function value"); + } + + try { + Reflect.construct(function(){}, [], f); + } catch (e) { + return false; + } + return true; +} diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/timezone-getoffsetnanosecondsfor-non-integer.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/timezone-getoffsetnanosecondsfor-non-integer.js new file mode 100644 index 0000000000..e5855c737b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/timezone-getoffsetnanosecondsfor-non-integer.js @@ -0,0 +1,18 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: RangeError thrown if time zone reports an offset that is not an integer number of nanoseconds +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +[3600_000_000_000.5, NaN, -Infinity, Infinity].forEach((wrongOffset) => { + const timeZone = TemporalHelpers.specificOffsetTimeZone(wrongOffset); + const instant = new Temporal.Instant(1_000_000_000_987_654_321n); + assert.throws(RangeError, () => timeZone.getPlainDateTimeFor(instant)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/timezone-getoffsetnanosecondsfor-not-callable.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/timezone-getoffsetnanosecondsfor-not-callable.js new file mode 100644 index 0000000000..da4a7aaefa --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/timezone-getoffsetnanosecondsfor-not-callable.js @@ -0,0 +1,22 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: TypeError thrown if timeZone.getOffsetNanosecondsFor is not callable +features: [BigInt, Symbol, Temporal, arrow-function] +---*/ + +[undefined, null, true, Math.PI, 'string', Symbol('sym'), 42n, {}].forEach((notCallable) => { + const timeZone = new Temporal.TimeZone("UTC"); + const instant = new Temporal.Instant(1_000_000_000_987_654_321n); + timeZone.getOffsetNanosecondsFor = notCallable; + assert.throws( + TypeError, + () => timeZone.getPlainDateTimeFor(instant), + `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/timezone-getoffsetnanosecondsfor-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/timezone-getoffsetnanosecondsfor-out-of-range.js new file mode 100644 index 0000000000..26bfd1667c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/timezone-getoffsetnanosecondsfor-out-of-range.js @@ -0,0 +1,18 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: RangeError thrown if time zone reports an offset that is out of range +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +[-86400_000_000_000, 86400_000_000_000].forEach((wrongOffset) => { + const timeZone = TemporalHelpers.specificOffsetTimeZone(wrongOffset); + const instant = new Temporal.Instant(1_000_000_000_987_654_321n); + assert.throws(RangeError, () => timeZone.getPlainDateTimeFor(instant)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/timezone-getoffsetnanosecondsfor-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/timezone-getoffsetnanosecondsfor-wrong-type.js new file mode 100644 index 0000000000..59a3ddca1c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/timezone-getoffsetnanosecondsfor-wrong-type.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: TypeError thrown if time zone reports an offset that is not a Number +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +[ + undefined, + null, + true, + "+01:00", + Symbol(), + 3600_000_000_000n, + {}, + { valueOf() { return 3600_000_000_000; } }, +].forEach((wrongOffset) => { + const timeZone = TemporalHelpers.specificOffsetTimeZone(wrongOffset); + const instant = new Temporal.Instant(1_000_000_000_987_654_321n); + assert.throws(TypeError, () => timeZone.getPlainDateTimeFor(instant)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/year-zero.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/year-zero.js new file mode 100644 index 0000000000..eeb5165699 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/year-zero.js @@ -0,0 +1,25 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-03-30T00:45Z", + "-000000-03-30T01:45+01:00", + "-000000-03-30T01:45:00+00:00[UTC]", +]; +const instance = new Temporal.TimeZone("UTC"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.getPlainDateTimeFor(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-not-datetime.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-not-datetime.js new file mode 100644 index 0000000000..d96f7dbb68 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-not-datetime.js @@ -0,0 +1,21 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: Appropriate error thrown when argument cannot be converted to Temporal.PlainDateTime +features: [Temporal] +---*/ + +const timeZone = Temporal.TimeZone.from("UTC"); +assert.throws(RangeError, () => timeZone.getPossibleInstantsFor(undefined), "undefined"); +assert.throws(RangeError, () => timeZone.getPossibleInstantsFor(null), "null"); +assert.throws(RangeError, () => timeZone.getPossibleInstantsFor(true), "boolean"); +assert.throws(RangeError, () => timeZone.getPossibleInstantsFor(""), "empty string"); +assert.throws(TypeError, () => timeZone.getPossibleInstantsFor(Symbol()), "Symbol"); +assert.throws(RangeError, () => timeZone.getPossibleInstantsFor(5), "number"); +assert.throws(RangeError, () => timeZone.getPossibleInstantsFor(5n), "bigint"); +assert.throws(TypeError, () => timeZone.getPossibleInstantsFor({}), "plain object"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-number.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-number.js new file mode 100644 index 0000000000..127355c8ec --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-number.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: A number is converted to a string, then to Temporal.PlainDateTime +includes: [compareArray.js] +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +let arg = 19761118; + +const result = instance.getPossibleInstantsFor(arg); +assert.compareArray(result.map(i => i.epochNanoseconds), [217_123_200_000_000_000n], "19761118 is a valid ISO string for PlainDateTime"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.getPossibleInstantsFor(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDateTime` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-plaindate.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-plaindate.js new file mode 100644 index 0000000000..3f88e83773 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-plaindate.js @@ -0,0 +1,25 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.until +description: Fast path for converting Temporal.PlainDate to Temporal.PlainDateTime by reading internal slots +info: | + sec-temporal.timezone.prototype.getpossibleinstantsfor step 3: + 3. Set _dateTime_ to ? ToTemporalDateTime(_dateTime_). + sec-temporal-totemporaldatetime step 2.b: + b. If _item_ has an [[InitializedTemporalDate]] internal slot, then + i. Return ? CreateTemporalDateTime(_item_.[[ISOYear]], _item_.[[ISOMonth]], _item_.[[ISODay]], 0, 0, 0, 0, 0, 0, _item_.[[Calendar]]). +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +TemporalHelpers.checkToTemporalPlainDateTimeFastPath((date) => { + const timezone = new Temporal.TimeZone("UTC"); + const result = timezone.getPossibleInstantsFor(date); + assert.sameValue(result.length, 1, "one possible instant"); + assert.sameValue(result[0].epochNanoseconds, 957_225_600_000_000_000n, "epochNanoseconds result"); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-case-insensitive.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-case-insensitive.js new file mode 100644 index 0000000000..1e9768089e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-case-insensitive.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: The calendar name is case-insensitive +includes: [compareArray.js] +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const calendar = "IsO8601"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.getPossibleInstantsFor(arg); +assert.compareArray(result1.map(i => i.epochNanoseconds), [217_123_200_000_000_000n], "Calendar is case-insensitive"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.getPossibleInstantsFor(arg); +assert.compareArray(result2.map(i => i.epochNanoseconds), [217_123_200_000_000_000n], "Calendar is case-insensitive (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-instance-does-not-get-calendar-property.js new file mode 100644 index 0000000000..f4f1c788b8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-instance-does-not-get-calendar-property.js @@ -0,0 +1,28 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: > + A Temporal.Calendar instance passed to getPossibleInstantsFor() in a property bag does + not have its 'calendar' property observably checked +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const calendar = new Temporal.Calendar("iso8601"); +Object.defineProperty(calendar, "calendar", { + get() { + throw new Test262Error("calendar.calendar should not be accessed"); + }, +}); + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +instance.getPossibleInstantsFor(arg); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +instance.getPossibleInstantsFor(arg); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-leap-second.js new file mode 100644 index 0000000000..c34b4d7241 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: Leap second is a valid ISO string for a calendar in a property bag +includes: [compareArray.js] +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.getPossibleInstantsFor(arg); +assert.compareArray( + result1.map(i => i.epochNanoseconds), + [217_123_200_000_000_000n], + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.getPossibleInstantsFor(arg); +assert.compareArray( + result2.map(i => i.epochNanoseconds), + [217_123_200_000_000_000n], + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-number.js new file mode 100644 index 0000000000..ff14e3423e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-number.js @@ -0,0 +1,45 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: A number as calendar in a property bag is converted to a string, then to a calendar +includes: [compareArray.js] +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.getPossibleInstantsFor(arg); +assert.compareArray(result1.map(i => i.epochNanoseconds), [217_123_200_000_000_000n], "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.getPossibleInstantsFor(arg); +assert.compareArray(result2.map(i => i.epochNanoseconds), [217_123_200_000_000_000n], "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + assert.throws( + RangeError, + () => instance.getPossibleInstantsFor(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.getPossibleInstantsFor(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-string.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-string.js new file mode 100644 index 0000000000..81ed33da0c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-string.js @@ -0,0 +1,20 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: A calendar ID is valid input for Calendar +includes: [compareArray.js] +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const calendar = "iso8601"; + +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.getPossibleInstantsFor(arg); +assert.compareArray(result.map(i => i.epochNanoseconds), [217_123_200_000_000_000n], `Calendar created from string "${calendar}"`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 0000000000..6c04c84a89 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.TimeZone("UTC"); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.getPossibleInstantsFor(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.getPossibleInstantsFor(arg), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.getPossibleInstantsFor(arg), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.getPossibleInstantsFor(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.getPossibleInstantsFor(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-year-zero.js new file mode 100644 index 0000000000..a5a83193e4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.TimeZone("UTC"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.getPossibleInstantsFor(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-string-calendar-annotation.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-string-calendar-annotation.js new file mode 100644 index 0000000000..bc12f8f929 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-string-calendar-annotation.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: Various forms of calendar annotation; critical flag has no effect +features: [Temporal] +includes: [compareArray.js] +---*/ + +const tests = [ + ["1976-11-18T15:23[u-ca=iso8601]", "without time zone"], + ["1976-11-18T15:23[UTC][u-ca=iso8601]", "with time zone"], + ["1976-11-18T15:23[!u-ca=iso8601]", "with ! and no time zone"], + ["1976-11-18T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], + ["1976-11-18T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], + ["1976-11-18T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], +]; + +const instance = new Temporal.TimeZone("UTC"); + +tests.forEach(([arg, description]) => { + const result = instance.getPossibleInstantsFor(arg); + + assert.compareArray( + result.map(i => i.epochNanoseconds), + [217_178_580_000_000_000n], + `calendar annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-string-critical-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-string-critical-unknown-annotation.js new file mode 100644 index 0000000000..5142c688c6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-string-critical-unknown-annotation.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: Unknown annotations with critical flag are rejected +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01T00:00[!foo=bar]", + "1970-01-01T00:00[UTC][!foo=bar]", + "1970-01-01T00:00[u-ca=iso8601][!foo=bar]", + "1970-01-01T00:00[UTC][!foo=bar][u-ca=iso8601]", + "1970-01-01T00:00[foo=bar][!_foo-bar0=Dont-Ignore-This-99999999999]", +]; +const instance = new Temporal.TimeZone("UTC"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.getPossibleInstantsFor(arg), + `reject unknown annotation with critical flag: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-string-date-with-utc-offset.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-string-date-with-utc-offset.js new file mode 100644 index 0000000000..66d9f9d2d4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-string-date-with-utc-offset.js @@ -0,0 +1,49 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: UTC offset not valid with format that does not include a time +features: [Temporal] +includes: [compareArray.js] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const validStrings = [ + "1976-11-18T15:23+00:00", + "1976-11-18T15:23+00:00[UTC]", + "1976-11-18T15:23+00:00[!UTC]", + "1976-11-18T15:23-02:30[America/St_Johns]", +]; + +for (const arg of validStrings) { + const result = instance.getPossibleInstantsFor(arg); + + assert.compareArray( + result.map(i => i.epochNanoseconds), + [217_178_580_000_000_000n], + `"${arg}" is a valid UTC offset with time for PlainDateTime` + ); +} + +const invalidStrings = [ + "2022-09-15Z", + "2022-09-15Z[UTC]", + "2022-09-15Z[Europe/Vienna]", + "2022-09-15+00:00", + "2022-09-15+00:00[UTC]", + "2022-09-15-02:30", + "2022-09-15-02:30[America/St_Johns]", +]; + +for (const arg of invalidStrings) { + assert.throws( + RangeError, + () => instance.getPossibleInstantsFor(arg), + `"${arg}" UTC offset without time is not valid for PlainDateTime` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-string-multiple-time-zone.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-string-multiple-time-zone.js new file mode 100644 index 0000000000..08ff28831d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-string-multiple-time-zone.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: More than one time zone annotation is not syntactical +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01T00:00[UTC][UTC]", + "1970-01-01T00:00[!UTC][UTC]", + "1970-01-01T00:00[UTC][!UTC]", + "1970-01-01T00:00[UTC][u-ca=iso8601][UTC]", + "1970-01-01T00:00[UTC][foo=bar][UTC]", +]; +const instance = new Temporal.TimeZone("UTC"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.getPossibleInstantsFor(arg), + `reject more than one time zone annotation: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-string-time-separators.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-string-time-separators.js new file mode 100644 index 0000000000..d13ffd5770 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-string-time-separators.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: Time separator in string argument can vary +features: [Temporal] +includes: [compareArray.js] +---*/ + +const tests = [ + ["1976-11-18T15:23", "uppercase T"], + ["1976-11-18t15:23", "lowercase T"], + ["1976-11-18 15:23", "space between date and time"], +]; + +const instance = new Temporal.TimeZone("UTC"); + +tests.forEach(([arg, description]) => { + const result = instance.getPossibleInstantsFor(arg); + + assert.compareArray( + result.map(i => i.epochNanoseconds), + [217_178_580_000_000_000n], + `variant time separators (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-string-time-zone-annotation.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-string-time-zone-annotation.js new file mode 100644 index 0000000000..7fb4cd8cfc --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-string-time-zone-annotation.js @@ -0,0 +1,35 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: Various forms of time zone annotation; critical flag has no effect +features: [Temporal] +includes: [compareArray.js] +---*/ + +const tests = [ + ["1976-11-18T15:23[Asia/Kolkata]", "named, with no offset"], + ["1976-11-18T15:23[!Europe/Vienna]", "named, with ! and no offset"], + ["1976-11-18T15:23[+00:00]", "numeric, with no offset"], + ["1976-11-18T15:23[!-02:30]", "numeric, with ! and no offset"], + ["1976-11-18T15:23+00:00[UTC]", "named, with offset"], + ["1976-11-18T15:23+00:00[!Africa/Abidjan]", "named, with offset and !"], + ["1976-11-18T15:23+00:00[+01:00]", "numeric, with offset"], + ["1976-11-18T15:23+00:00[!-08:00]", "numeric, with offset and !"], +]; + +const instance = new Temporal.TimeZone("UTC"); + +tests.forEach(([arg, description]) => { + const result = instance.getPossibleInstantsFor(arg); + + assert.compareArray( + result.map(i => i.epochNanoseconds), + [217_178_580_000_000_000n], + `time zone annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-string-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-string-unknown-annotation.js new file mode 100644 index 0000000000..a528851731 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-string-unknown-annotation.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: Various forms of unknown annotation +features: [Temporal] +includes: [compareArray.js] +---*/ + +const tests = [ + ["1976-11-18T15:23[foo=bar]", "alone"], + ["1976-11-18T15:23[UTC][foo=bar]", "with time zone"], + ["1976-11-18T15:23[u-ca=iso8601][foo=bar]", "with calendar"], + ["1976-11-18T15:23[UTC][foo=bar][u-ca=iso8601]", "with time zone and calendar"], + ["1976-11-18T15:23[foo=bar][_foo-bar0=Ignore-This-999999999999]", "with another unknown annotation"], +]; + +const instance = new Temporal.TimeZone("UTC"); + +tests.forEach(([arg, description]) => { + const result = instance.getPossibleInstantsFor(arg); + + assert.compareArray( + result.map(i => i.epochNanoseconds), + [217_178_580_000_000_000n], + `unknown annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-string-with-utc-designator.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-string-with-utc-designator.js new file mode 100644 index 0000000000..653e64f9d0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-string-with-utc-designator.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: RangeError thrown if a string with UTC designator is used as a PlainDateTime +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "2019-10-01T09:00:00Z", + "2019-10-01T09:00:00Z[UTC]", +]; +const instance = new Temporal.TimeZone("UTC"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.getPossibleInstantsFor(arg), + "String with UTC designator should not be valid as a PlainDateTime" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-wrong-type.js new file mode 100644 index 0000000000..5fa12600a9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDateTime +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.getPossibleInstantsFor(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDateTime, "Temporal.PlainDateTime, object"], + [Temporal.PlainDateTime.prototype, "Temporal.PlainDateTime.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.getPossibleInstantsFor(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-zoneddatetime-balance-negative-time-units.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-zoneddatetime-balance-negative-time-units.js new file mode 100644 index 0000000000..b66e0db9d7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-zoneddatetime-balance-negative-time-units.js @@ -0,0 +1,47 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: Negative time fields are balanced upwards if the argument is given as ZonedDateTime +info: | + sec-temporal-balancetime steps 3–14: + 3. Set _microsecond_ to _microsecond_ + floor(_nanosecond_ / 1000). + 4. Set _nanosecond_ to _nanosecond_ modulo 1000. + 5. Set _millisecond_ to _millisecond_ + floor(_microsecond_ / 1000). + 6. Set _microsecond_ to _microsecond_ modulo 1000. + 7. Set _second_ to _second_ + floor(_millisecond_ / 1000). + 8. Set _millisecond_ to _millisecond_ modulo 1000. + 9. Set _minute_ to _minute_ + floor(_second_ / 60). + 10. Set _second_ to _second_ modulo 60. + 11. Set _hour_ to _hour_ + floor(_minute_ / 60). + 12. Set _minute_ to _minute_ modulo 60. + 13. Let _days_ be floor(_hour_ / 24). + 14. Set _hour_ to _hour_ modulo 24. + sec-temporal-balanceisodatetime step 1: + 1. Let _balancedTime_ be ? BalanceTime(_hour_, _minute_, _second_, _millisecond_, _microsecond_, _nanosecond_). + sec-temporal-builtintimezonegetplaindatetimefor step 3: + 3. Set _result_ to ? BalanceISODateTime(_result_.[[Year]], _result_.[[Month]], _result_.[[Day]], _result_.[[Hour]], _result_.[[Minute]], _result_.[[Second]], _result_.[[Millisecond]], _result_.[[Microsecond]], _result_.[[Nanosecond]] + _offsetNanoseconds_). + sec-temporal-totemporaldatetime step 3.b: + b. If _item_ has an [[InitializedTemporalZonedDateTime]] internal slot, then + ... + ii. 1. Return ? BuiltinTimeZoneGetPlainDateTimeFor(_item_.[[TimeZone]], _instant_, _item_.[[Calendar]]). + sec-temporal.timezone.prototype.getpossibleinstantsfor step 3: + 3. Set _dateTime_ ? ToTemporalDateTime(_dateTime_). +features: [Temporal] +---*/ + +// This code path is encountered if the time zone offset is negative and its +// absolute value in nanoseconds is greater than the nanosecond field of the +// exact time's epoch parts +const tz = new Temporal.TimeZone("-00:00:00.000000002"); +const datetime = new Temporal.ZonedDateTime(3661_001_001_001n, tz); + +const conversionTimeZone = new Temporal.TimeZone("UTC"); // should not be used to interpret the argument +const instants = conversionTimeZone.getPossibleInstantsFor(datetime); + +assert.sameValue(instants.length, 1); +assert.sameValue(instants[0].epochNanoseconds, 3661_001_000_999n); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-zoneddatetime-negative-epochnanoseconds.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-zoneddatetime-negative-epochnanoseconds.js new file mode 100644 index 0000000000..e9c3c669e3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-zoneddatetime-negative-epochnanoseconds.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: A pre-epoch value is handled correctly by the modulo operation in GetISOPartsFromEpoch +info: | + sec-temporal-getisopartsfromepoch step 1: + 1. Let _remainderNs_ be the mathematical value whose sign is the sign of _epochNanoseconds_ and whose magnitude is abs(_epochNanoseconds_) modulo 10<sup>6</sup>. + sec-temporal-builtintimezonegetplaindatetimefor step 2: + 2. Let _result_ be ! GetISOPartsFromEpoch(_instant_.[[Nanoseconds]]). +features: [Temporal] +includes: [compareArray.js] +---*/ + +const datetime = new Temporal.ZonedDateTime(-13849764_999_999_999n, "UTC"); + +// This code path shows up anywhere we convert an exact time, before the Unix +// epoch, with nonzero microseconds or nanoseconds, into a wall time. + +const instance = new Temporal.TimeZone("UTC"); +const result = instance.getPossibleInstantsFor(datetime); +assert.compareArray(result.map((i) => i.epochNanoseconds), [-13849764_999_999_999n]); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js new file mode 100644 index 0000000000..ad8c07520b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js @@ -0,0 +1,19 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: RangeError thrown if time zone reports an offset that is not an integer number of nanoseconds +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +[3600_000_000_000.5, NaN, -Infinity, Infinity].forEach((wrongOffset) => { + const timeZone = TemporalHelpers.specificOffsetTimeZone(wrongOffset); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + const builtinTimeZone = new Temporal.TimeZone("UTC"); + assert.throws(RangeError, () => builtinTimeZone.getPossibleInstantsFor(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js new file mode 100644 index 0000000000..117c847d3f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js @@ -0,0 +1,23 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: TypeError thrown if timeZone.getOffsetNanosecondsFor is not callable +features: [BigInt, Symbol, Temporal, arrow-function] +---*/ + +[undefined, null, true, Math.PI, 'string', Symbol('sym'), 42n, {}].forEach((notCallable) => { + const timeZone = new Temporal.TimeZone("UTC"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + const builtinTimeZone = new Temporal.TimeZone("UTC"); + timeZone.getOffsetNanosecondsFor = notCallable; + assert.throws( + TypeError, + () => builtinTimeZone.getPossibleInstantsFor(datetime), + `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js new file mode 100644 index 0000000000..bbbc0e200f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js @@ -0,0 +1,19 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: RangeError thrown if time zone reports an offset that is out of range +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +[-86400_000_000_000, 86400_000_000_000].forEach((wrongOffset) => { + const timeZone = TemporalHelpers.specificOffsetTimeZone(wrongOffset); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + const builtinTimeZone = new Temporal.TimeZone("UTC"); + assert.throws(RangeError, () => builtinTimeZone.getPossibleInstantsFor(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js new file mode 100644 index 0000000000..de875bf464 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js @@ -0,0 +1,28 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: TypeError thrown if time zone reports an offset that is not a Number +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +[ + undefined, + null, + true, + "+01:00", + Symbol(), + 3600_000_000_000n, + {}, + { valueOf() { return 3600_000_000_000; } }, +].forEach((wrongOffset) => { + const timeZone = TemporalHelpers.specificOffsetTimeZone(wrongOffset); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + const builtinTimeZone = new Temporal.TimeZone("UTC"); + assert.throws(TypeError, () => builtinTimeZone.getPossibleInstantsFor(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/branding.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/branding.js new file mode 100644 index 0000000000..6253371f92 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/branding.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const getPossibleInstantsFor = Temporal.TimeZone.prototype.getPossibleInstantsFor; + +assert.sameValue(typeof getPossibleInstantsFor, "function"); + +const args = [new Temporal.PlainDateTime(2022, 6, 22)]; + +assert.throws(TypeError, () => getPossibleInstantsFor.apply(undefined, args), "undefined"); +assert.throws(TypeError, () => getPossibleInstantsFor.apply(null, args), "null"); +assert.throws(TypeError, () => getPossibleInstantsFor.apply(true, args), "true"); +assert.throws(TypeError, () => getPossibleInstantsFor.apply("", args), "empty string"); +assert.throws(TypeError, () => getPossibleInstantsFor.apply(Symbol(), args), "symbol"); +assert.throws(TypeError, () => getPossibleInstantsFor.apply(1, args), "1"); +assert.throws(TypeError, () => getPossibleInstantsFor.apply({}, args), "plain object"); +assert.throws(TypeError, () => getPossibleInstantsFor.apply(Temporal.TimeZone, args), "Temporal.TimeZone"); +assert.throws(TypeError, () => getPossibleInstantsFor.apply(Temporal.TimeZone.prototype, args), "Temporal.TimeZone.prototype"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/browser.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/builtin.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/builtin.js new file mode 100644 index 0000000000..7a73b60149 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/builtin.js @@ -0,0 +1,36 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: > + Tests that Temporal.TimeZone.prototype.getPossibleInstantsFor + meets the requirements for built-in objects defined by the + introduction of chapter 17 of the ECMAScript Language Specification. +info: | + Built-in functions that are not constructors do not have a "prototype" property unless + otherwise specified in the description of a particular function. + + Unless specified otherwise, a built-in object that is callable as a function is a built-in + function object with the characteristics described in 10.3. Unless specified otherwise, the + [[Extensible]] internal slot of a built-in object initially has the value true. + + Unless otherwise specified every built-in function and every built-in constructor has the + Function prototype object [...] as the value of its [[Prototype]] internal slot. +features: [Temporal] +---*/ + +assert.sameValue(Object.isExtensible(Temporal.TimeZone.prototype.getPossibleInstantsFor), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.TimeZone.prototype.getPossibleInstantsFor), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.TimeZone.prototype.getPossibleInstantsFor), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.TimeZone.prototype.getPossibleInstantsFor.hasOwnProperty("prototype"), + false, "prototype property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/calendar-datefromfields-called-with-null-prototype-fields.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/calendar-datefromfields-called-with-null-prototype-fields.js new file mode 100644 index 0000000000..85ed0f6428 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/calendar-datefromfields-called-with-null-prototype-fields.js @@ -0,0 +1,19 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: > + Calendar.dateFromFields method is called with a null-prototype fields object +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = TemporalHelpers.calendarCheckFieldsPrototypePollution(); +const instance = new Temporal.TimeZone("UTC"); +const arg = { year: 2000, month: 5, day: 2, calendar }; +instance.getPossibleInstantsFor(arg); +assert.sameValue(calendar.dateFromFieldsCallCount, 1, "dateFromFields should be called on the property bag's calendar"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/calendar-fields-iterable.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/calendar-fields-iterable.js new file mode 100644 index 0000000000..161d017d97 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/calendar-fields-iterable.js @@ -0,0 +1,40 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: Verify the result of calendar.fields() is treated correctly. +info: | + sec-temporal.timezone.prototype.getpossibleinstantsfor step 3: + 3. Set _dateTime_ to ? ToTemporalDateTime(_dateTime_). + sec-temporal-totemporaldatetime step 2.c: + c. Let _fieldNames_ be ? CalendarFields(_calendar_, « *"day"*, *"hour"*, *"microsecond"*, *"millisecond"*, *"minute"*, *"month"*, *"monthCode"*, *"nanosecond"*, *"second"*, *"year"* »). + sec-temporal-calendarfields step 4: + 4. Let _result_ be ? IterableToList(_fieldsArray_). +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + "day", + "hour", + "microsecond", + "millisecond", + "minute", + "month", + "monthCode", + "nanosecond", + "second", + "year", +]; + +const calendar = TemporalHelpers.calendarFieldsIterable(); +const timeZone = new Temporal.TimeZone("UTC"); +timeZone.getPossibleInstantsFor({ year: 2000, month: 5, day: 2, calendar }); + +assert.sameValue(calendar.fieldsCallCount, 1, "fields() method called once"); +assert.compareArray(calendar.fieldsCalledWith[0], expected, "fields() method called with correct args"); +assert(calendar.iteratorExhausted[0], "iterated through the whole iterable"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/calendar-temporal-object.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/calendar-temporal-object.js new file mode 100644 index 0000000000..c7a1be4174 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/calendar-temporal-object.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots +info: | + sec-temporal.timezone.prototype.getpossibleinstantsfor step 3: + 3. Set _dateTime_ to ? ToTemporalDateTime(_dateTime_). + sec-temporal-totemporaldatetime step 2.c: + c. Let _calendar_ be ? GetTemporalCalendarWithISODefault(_item_). + sec-temporal-gettemporalcalendarwithisodefault step 2: + 2. Return ? ToTemporalCalendarWithISODefault(_calendar_). + sec-temporal-totemporalcalendarwithisodefault step 2: + 3. Return ? ToTemporalCalendar(_temporalCalendarLike_). + sec-temporal-totemporalcalendar step 1.a: + a. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then + i. Return _temporalCalendarLike_.[[Calendar]]. +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +TemporalHelpers.checkToTemporalCalendarFastPath((temporalObject) => { + const timeZone = new Temporal.TimeZone("UTC"); + timeZone.getPossibleInstantsFor({ year: 2000, month: 5, day: 2, calendar: temporalObject }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/fixed-offset-near-date-time-limits.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/fixed-offset-near-date-time-limits.js new file mode 100644 index 0000000000..42aad62feb --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/fixed-offset-near-date-time-limits.js @@ -0,0 +1,57 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: > + Call getPossibleInstantsFor with values near the date/time limit and a fixed offset. +features: [Temporal, exponentiation] +---*/ + +const oneHour = 1n * 60n * 60n * 1000n**3n; + +const minDt = new Temporal.PlainDateTime(-271821, 4, 19, 1, 0, 0, 0, 0, 0); +const minValidDt = new Temporal.PlainDateTime(-271821, 4, 20, 0, 0, 0, 0, 0, 0); +const maxDt = new Temporal.PlainDateTime(275760, 9, 13, 0, 0, 0, 0, 0, 0); + +let zero = new Temporal.TimeZone("+00"); +let plusOne = new Temporal.TimeZone("+01"); +let minusOne = new Temporal.TimeZone("-01"); + +// Try the minimum date-time. +assert.throws(RangeError, () => zero.getPossibleInstantsFor(minDt)); +assert.throws(RangeError, () => plusOne.getPossibleInstantsFor(minDt)); +assert.throws(RangeError, () => minusOne.getPossibleInstantsFor(minDt)); + +// Try the minimum valid date-time. +{ + let r = zero.getPossibleInstantsFor(minValidDt); + assert.sameValue(r.length, 1); + assert.sameValue(r[0].epochNanoseconds, -86_40000_00000_00000_00000n); +} + +{ + let r = minusOne.getPossibleInstantsFor(minValidDt); + assert.sameValue(r.length, 1); + assert.sameValue(r[0].epochNanoseconds, -86_40000_00000_00000_00000n + oneHour); +} + +assert.throws(RangeError, () => plusOne.getPossibleInstantsFor(minValidDt)); + +// Try the maximum valid date-time. +{ + let r = zero.getPossibleInstantsFor(maxDt); + assert.sameValue(r.length, 1); + assert.sameValue(r[0].epochNanoseconds, 86_40000_00000_00000_00000n); +} + +{ + let r = plusOne.getPossibleInstantsFor(maxDt); + assert.sameValue(r.length, 1); + assert.sameValue(r[0].epochNanoseconds, 86_40000_00000_00000_00000n - oneHour); +} + +assert.throws(RangeError, () => minusOne.getPossibleInstantsFor(maxDt)); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/infinity-throws-rangeerror.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/infinity-throws-rangeerror.js new file mode 100644 index 0000000000..8af5905d3e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/infinity-throws-rangeerror.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Throws if any value in the property bag is Infinity or -Infinity +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); +const base = { year: 2000, month: 5, day: 2, hour: 15, minute: 30, second: 45, millisecond: 987, microsecond: 654, nanosecond: 321 }; + +[Infinity, -Infinity].forEach((inf) => { + ["year", "month", "day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond"].forEach((prop) => { + assert.throws(RangeError, () => instance.getPossibleInstantsFor({ ...base, [prop]: inf }), `${prop} property cannot be ${inf}`); + + const calls = []; + const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop); + assert.throws(RangeError, () => instance.getPossibleInstantsFor({ ...base, [prop]: obj })); + assert.compareArray(calls, [`get ${prop}.valueOf`, `call ${prop}.valueOf`], "it fails after fetching the primitive value"); + }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/leap-second.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/leap-second.js new file mode 100644 index 0000000000..91ed9f0abe --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/leap-second.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: Leap second is a valid ISO string for PlainDateTime +includes: [compareArray.js] +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.getPossibleInstantsFor(arg); +assert.compareArray( + result1.map(i => i.epochNanoseconds), + [1_483_228_799_000_000_000n], + "leap second is a valid ISO string for PlainDateTime" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.getPossibleInstantsFor(arg); +assert.compareArray( + result2.map(i => i.epochNanoseconds), + [1_483_228_799_000_000_000n], + "second: 60 is ignored in property bag for PlainDateTime" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/length.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/length.js new file mode 100644 index 0000000000..a207968dc5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/length.js @@ -0,0 +1,28 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: Temporal.TimeZone.prototype.getPossibleInstantsFor.length is 1 +info: | + 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: [Temporal] +---*/ + +verifyProperty(Temporal.TimeZone.prototype.getPossibleInstantsFor, "length", { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/name.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/name.js new file mode 100644 index 0000000000..0e46a24462 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/name.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: Temporal.TimeZone.prototype.getPossibleInstantsFor.name is "getPossibleInstantsFor". +info: | + 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: [Temporal] +---*/ + +verifyProperty(Temporal.TimeZone.prototype.getPossibleInstantsFor, "name", { + value: "getPossibleInstantsFor", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/not-a-constructor.js new file mode 100644 index 0000000000..13eb622abb --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/not-a-constructor.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: > + Temporal.TimeZone.prototype.getPossibleInstantsFor does not implement [[Construct]], is not new-able +info: | + Built-in function objects that are not identified as constructors do not implement the + [[Construct]] internal method unless otherwise specified in the description of a particular + function. +includes: [isConstructor.js] +features: [Reflect.construct, Temporal] +---*/ + +assert.throws(TypeError, () => { + new Temporal.TimeZone.prototype.getPossibleInstantsFor(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.TimeZone.prototype.getPossibleInstantsFor), false, + "isConstructor(Temporal.TimeZone.prototype.getPossibleInstantsFor)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/prop-desc.js new file mode 100644 index 0000000000..7807b3d11e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/prop-desc.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: The "getPossibleInstantsFor" property of Temporal.TimeZone.prototype +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.TimeZone.prototype.getPossibleInstantsFor, + "function", + "`typeof TimeZone.prototype.getPossibleInstantsFor` is `function`" +); + +verifyProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", { + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/read-time-fields-before-datefromfields.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/read-time-fields-before-datefromfields.js new file mode 100644 index 0000000000..d594463cfe --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/read-time-fields-before-datefromfields.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: The time fields are read from the object before being passed to dateFromFields(). +info: | + sec-temporal.timezone.prototype.getpossibleinstantsfor step 3: + 3. Set _dateTime_ to ? ToTemporalDateTime(_dateTime_). + sec-temporal-totemporaldatetime step 2.e: + e. Let _result_ be ? InterpretTemporalDateTimeFields(_calendar_, _fields_, _options_). + sec-temporal-interprettemporaldatetimefields steps 1–2: + 1. Let _timeResult_ be ? ToTemporalTimeRecord(_fields_). + 2. Let _temporalDate_ be ? DateFromFields(_calendar_, _fields_, _options_). +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const timezone = new Temporal.TimeZone("UTC"); +const calendar = TemporalHelpers.calendarMakeInfinityTime(); +const result = timezone.getPossibleInstantsFor({ year: 1970, month: 1, day: 1, calendar }); + +assert.sameValue(result.length, 1, "result array length"); +assert.sameValue(result[0].epochNanoseconds, 0n, "epochNanoseconds result"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/shell.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/shell.js new file mode 100644 index 0000000000..eda1477282 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/shell.js @@ -0,0 +1,24 @@ +// GENERATED, DO NOT EDIT +// file: isConstructor.js +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: | + Test if a given function is a constructor function. +defines: [isConstructor] +features: [Reflect.construct] +---*/ + +function isConstructor(f) { + if (typeof f !== "function") { + throw new Test262Error("isConstructor invoked with a non-function value"); + } + + try { + Reflect.construct(function(){}, [], f); + } catch (e) { + return false; + } + return true; +} diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/year-zero.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/year-zero.js new file mode 100644 index 0000000000..6917495e05 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/year-zero.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-12-07", + "-000000-12-07T03:24:30", + "-000000-12-07T03:24:30+01:00", + "-000000-12-07T03:24:30+00:00[UTC]", +]; +const instance = new Temporal.TimeZone("UTC"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.getPossibleInstantsFor(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/argument-string-calendar-annotation.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/argument-string-calendar-annotation.js new file mode 100644 index 0000000000..07a88fa42a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/argument-string-calendar-annotation.js @@ -0,0 +1,34 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getprevioustransition +description: Various forms of calendar annotation; critical flag has no effect +features: [Temporal] +---*/ + +const tests = [ + ["1970-01-01T00:00Z[u-ca=iso8601]", "without time zone"], + ["1970-01-01T00:00Z[UTC][u-ca=gregory]", "with time zone"], + ["1970-01-01T00:00Z[!u-ca=hebrew]", "with ! and no time zone"], + ["1970-01-01T00:00Z[UTC][!u-ca=chinese]", "with ! and time zone"], + ["1970-01-01T00:00Z[u-ca=discord]", "annotation is ignored"], + ["1970-01-01T00:00Z[!u-ca=discord]", "annotation with ! is ignored"], + ["1970-01-01T00:00Z[u-ca=iso8601][u-ca=discord]", "two annotations are ignored"], + ["1970-01-01T00:00Z[u-ca=iso8601][!u-ca=discord]", "two annotations are ignored even with !"], +]; + +const instance = new Temporal.TimeZone("UTC"); + +tests.forEach(([arg, description]) => { + const result = instance.getPreviousTransition(arg); + + assert.sameValue( + result, + null, + `calendar annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/argument-string-critical-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/argument-string-critical-unknown-annotation.js new file mode 100644 index 0000000000..0fc6b709c0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/argument-string-critical-unknown-annotation.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getprevioustransition +description: Unknown annotations with critical flag are rejected +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01T00:00Z[!foo=bar]", + "1970-01-01T00:00Z[UTC][!foo=bar]", + "1970-01-01T00:00Z[u-ca=iso8601][!foo=bar]", + "1970-01-01T00:00Z[UTC][!foo=bar][u-ca=iso8601]", + "1970-01-01T00:00Z[foo=bar][!_foo-bar0=Dont-Ignore-This-99999999999]", +]; +const instance = new Temporal.TimeZone("UTC"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.getPreviousTransition(arg), + `reject unknown annotation with critical flag: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/argument-string-date-with-utc-offset.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/argument-string-date-with-utc-offset.js new file mode 100644 index 0000000000..9f3b466ba5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/argument-string-date-with-utc-offset.js @@ -0,0 +1,52 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getprevioustransition +description: UTC offset not valid with format that does not include a time +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const validStrings = [ + "1970-01-01T00Z", + "1970-01-01T00Z[UTC]", + "1970-01-01T00Z[!UTC]", + "1970-01-01T00Z[Europe/Vienna]", + "1970-01-01T00+00:00", + "1970-01-01T00+00:00[UTC]", + "1970-01-01T00+00:00[!UTC]", + "1969-12-31T16-08:00[America/Vancouver]", +]; + +for (const arg of validStrings) { + const result = instance.getPreviousTransition(arg); + + assert.sameValue( + result, + null, + `"${arg}" is a valid UTC offset with time for Instant` + ); +} + +const invalidStrings = [ + "2022-09-15Z", + "2022-09-15Z[UTC]", + "2022-09-15Z[Europe/Vienna]", + "2022-09-15+00:00", + "2022-09-15+00:00[UTC]", + "2022-09-15-02:30", + "2022-09-15-02:30[America/St_Johns]", +]; + +for (const arg of invalidStrings) { + assert.throws( + RangeError, + () => instance.getPreviousTransition(arg), + `"${arg}" UTC offset without time is not valid for Instant` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/argument-string-invalid.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/argument-string-invalid.js new file mode 100644 index 0000000000..027a1e6086 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/argument-string-invalid.js @@ -0,0 +1,69 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getprevioustransition +description: > + RangeError thrown if an invalid ISO string (or syntactically valid ISO string + that is not supported) is used as an Instant +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + // invalid ISO strings: + "", + "invalid iso8601", + "2020-01-00T00:00Z", + "2020-01-32T00:00Z", + "2020-02-30T00:00Z", + "2021-02-29T00:00Z", + "2020-00-01T00:00Z", + "2020-13-01T00:00Z", + "2020-01-01TZ", + "2020-01-01T25:00:00Z", + "2020-01-01T01:60:00Z", + "2020-01-01T01:60:61Z", + "2020-01-01T00:00Zjunk", + "2020-01-01T00:00:00Zjunk", + "2020-01-01T00:00:00.000000000Zjunk", + "2020-01-01T00:00:00+00:00junk", + "2020-01-01T00:00:00+00:00[UTC]junk", + "2020-01-01T00:00:00+00:00[UTC][u-ca=iso8601]junk", + "02020-01-01T00:00Z", + "2020-001-01T00:00Z", + "2020-01-001T00:00Z", + "2020-01-01T001Z", + "2020-01-01T01:001Z", + "2020-01-01T01:01:001Z", + // valid, but forms not supported in Temporal: + "2020-W01-1T00:00Z", + "2020-001T00:00Z", + "+0002020-01-01T00:00Z", + // may be valid in other contexts, but insufficient information for Instant: + "2020-01", + "+002020-01", + "01-01", + "2020-W01", + "P1Y", + "-P12Y", + "2020-01-01", + "2020-01-01T00", + "2020-01-01T00:00", + "2020-01-01T00:00:00", + "2020-01-01T00:00:00.000000000", + // valid, but outside the supported range: + "-999999-01-01T00:00Z", + "+999999-01-01T00:00Z", +]; + +const instance = new Temporal.TimeZone("UTC"); +for (const arg of invalidStrings) { + assert.throws( + RangeError, + () => instance.getPreviousTransition(arg), + `"${arg}" should not be a valid ISO string for an Instant` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/argument-string-multiple-time-zone.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/argument-string-multiple-time-zone.js new file mode 100644 index 0000000000..90d26f25fd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/argument-string-multiple-time-zone.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getprevioustransition +description: More than one time zone annotation is not syntactical +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01T00:00Z[UTC][UTC]", + "1970-01-01T00:00Z[!UTC][UTC]", + "1970-01-01T00:00Z[UTC][!UTC]", + "1970-01-01T00:00Z[UTC][u-ca=iso8601][UTC]", + "1970-01-01T00:00Z[UTC][foo=bar][UTC]", +]; +const instance = new Temporal.TimeZone("UTC"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.getPreviousTransition(arg), + `reject more than one time zone annotation: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/argument-string-time-separators.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/argument-string-time-separators.js new file mode 100644 index 0000000000..4200b2dfd6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/argument-string-time-separators.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getprevioustransition +description: Time separator in string argument can vary +features: [Temporal] +---*/ + +const tests = [ + ["1970-01-01T00:00Z", "uppercase T"], + ["1970-01-01t00:00Z", "lowercase T"], + ["1970-01-01 00:00Z", "space between date and time"], +]; + +const instance = new Temporal.TimeZone("UTC"); + +tests.forEach(([arg, description]) => { + const result = instance.getPreviousTransition(arg); + + assert.sameValue( + result, + null, + `variant time separators (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/argument-string-time-zone-annotation.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/argument-string-time-zone-annotation.js new file mode 100644 index 0000000000..f00d2f6845 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/argument-string-time-zone-annotation.js @@ -0,0 +1,34 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getprevioustransition +description: Various forms of time zone annotation; critical flag has no effect +features: [Temporal] +---*/ + +const tests = [ + ["1970-01-01T00:00Z[Asia/Kolkata]", "named, with Z"], + ["1970-01-01T00:00Z[!Europe/Vienna]", "named, with Z and !"], + ["1970-01-01T00:00Z[+00:00]", "numeric, with Z"], + ["1970-01-01T00:00Z[!-02:30]", "numeric, with Z and !"], + ["1970-01-01T00:00+00:00[UTC]", "named, with offset"], + ["1970-01-01T00:00+00:00[!Africa/Abidjan]", "named, with offset and !"], + ["1970-01-01T00:00+00:00[-08:00]", "numeric, with offset"], + ["1970-01-01T00:00+00:00[!+01:00]", "numeric, with offset and !"], +]; + +const instance = new Temporal.TimeZone("UTC"); + +tests.forEach(([arg, description]) => { + const result = instance.getPreviousTransition(arg); + + assert.sameValue( + result, + null, + `time zone annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/argument-string-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/argument-string-unknown-annotation.js new file mode 100644 index 0000000000..055edf071a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/argument-string-unknown-annotation.js @@ -0,0 +1,31 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getprevioustransition +description: Various forms of unknown annotation +features: [Temporal] +---*/ + +const tests = [ + ["1970-01-01T00:00Z[foo=bar]", "alone"], + ["1970-01-01T00:00Z[UTC][foo=bar]", "with time zone"], + ["1970-01-01T00:00Z[u-ca=iso8601][foo=bar]", "with calendar"], + ["1970-01-01T00:00Z[UTC][foo=bar][u-ca=iso8601]", "with time zone and calendar"], + ["1970-01-01T00:00Z[foo=bar][_foo-bar0=Ignore-This-999999999999]", "with another unknown annotation"], +]; + +const instance = new Temporal.TimeZone("UTC"); + +tests.forEach(([arg, description]) => { + const result = instance.getPreviousTransition(arg); + + assert.sameValue( + result, + null, + `unknown annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/argument-wrong-type.js new file mode 100644 index 0000000000..053ab505bd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/argument-wrong-type.js @@ -0,0 +1,40 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getprevioustransition +description: > + Appropriate error thrown when argument cannot be converted to a valid string + for Instant +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], + [{}, "plain object"], + [Temporal.Instant, "Temporal.Instant, object"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.getPreviousTransition(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [Temporal.Instant.prototype, "Temporal.Instant.prototype, object"], // fails brand check in toString() +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.getPreviousTransition(arg), `${description} does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/argument-zoneddatetime.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/argument-zoneddatetime.js new file mode 100644 index 0000000000..0be016a1a9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/argument-zoneddatetime.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getprevioustransition +description: Fast path for converting Temporal.ZonedDateTime to Temporal.Instant +info: | + sec-temporal.timezone.prototype.getprevioustransition step 3: + 3. Set _startingPoint_ to ? ToTemporalInstant(_startingPoint_). + sec-temporal-totemporalinstant step 1.b: + b. If _item_ has an [[InitializedTemporalZonedDateTime]] internal slot, then + i. Return ! CreateTemporalInstant(_item_.[[Nanoseconds]]). +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +TemporalHelpers.checkToTemporalInstantFastPath((datetime) => { + const timeZone = Temporal.TimeZone.from("UTC"); + const result = timeZone.getPreviousTransition(datetime); + assert.sameValue(result, null, "transition result"); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/branding.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/branding.js new file mode 100644 index 0000000000..fdab6397a2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/branding.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getprevioustransition +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const getPreviousTransition = Temporal.TimeZone.prototype.getPreviousTransition; + +assert.sameValue(typeof getPreviousTransition, "function"); + +const args = [new Temporal.Instant(0n)]; + +assert.throws(TypeError, () => getPreviousTransition.apply(undefined, args), "undefined"); +assert.throws(TypeError, () => getPreviousTransition.apply(null, args), "null"); +assert.throws(TypeError, () => getPreviousTransition.apply(true, args), "true"); +assert.throws(TypeError, () => getPreviousTransition.apply("", args), "empty string"); +assert.throws(TypeError, () => getPreviousTransition.apply(Symbol(), args), "symbol"); +assert.throws(TypeError, () => getPreviousTransition.apply(1, args), "1"); +assert.throws(TypeError, () => getPreviousTransition.apply({}, args), "plain object"); +assert.throws(TypeError, () => getPreviousTransition.apply(Temporal.TimeZone, args), "Temporal.TimeZone"); +assert.throws(TypeError, () => getPreviousTransition.apply(Temporal.TimeZone.prototype, args), "Temporal.TimeZone.prototype"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/browser.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/builtin.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/builtin.js new file mode 100644 index 0000000000..28dd0fbfc1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/builtin.js @@ -0,0 +1,36 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getprevioustransition +description: > + Tests that Temporal.TimeZone.prototype.getPreviousTransition + meets the requirements for built-in objects defined by the + introduction of chapter 17 of the ECMAScript Language Specification. +info: | + Built-in functions that are not constructors do not have a "prototype" property unless + otherwise specified in the description of a particular function. + + Unless specified otherwise, a built-in object that is callable as a function is a built-in + function object with the characteristics described in 10.3. Unless specified otherwise, the + [[Extensible]] internal slot of a built-in object initially has the value true. + + Unless otherwise specified every built-in function and every built-in constructor has the + Function prototype object [...] as the value of its [[Prototype]] internal slot. +features: [Temporal] +---*/ + +assert.sameValue(Object.isExtensible(Temporal.TimeZone.prototype.getPreviousTransition), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.TimeZone.prototype.getPreviousTransition), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.TimeZone.prototype.getPreviousTransition), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.TimeZone.prototype.getPreviousTransition.hasOwnProperty("prototype"), + false, "prototype property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/instant-string-limits.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/instant-string-limits.js new file mode 100644 index 0000000000..1d525db983 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/instant-string-limits.js @@ -0,0 +1,47 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getprevioustransition +description: String arguments at the limit of the representable range +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const minInstantStrings = [ + "-271821-04-20T00:00Z", + "-271821-04-19T23:00-01:00", + "-271821-04-19T00:00:00.000000001-23:59:59.999999999", +]; +for (const str of minInstantStrings) { + assert.sameValue(instance.getPreviousTransition(str), null, `instant string ${str} should be valid`); +} + +const maxInstantStrings = [ + "+275760-09-13T00:00Z", + "+275760-09-13T01:00+01:00", + "+275760-09-13T23:59:59.999999999+23:59:59.999999999", +]; + +for (const str of maxInstantStrings) { + assert.sameValue(instance.getPreviousTransition(str), null, `instant string ${str} should be valid`); +} + +const outOfRangeInstantStrings = [ + "-271821-04-19T23:59:59.999999999Z", + "-271821-04-19T23:00-00:59:59.999999999", + "-271821-04-19T00:00:00-23:59:59.999999999", + "-271821-04-19T00:00:00-24:00", + "+275760-09-13T00:00:00.000000001Z", + "+275760-09-13T01:00+00:59:59.999999999", + "+275760-09-14T00:00+23:59:59.999999999", + "+275760-09-14T00:00+24:00", +]; + +for (const str of outOfRangeInstantStrings) { + assert.throws(RangeError, () => instance.getPreviousTransition(str), `instant string ${str} should not be valid`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/instant-string.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/instant-string.js new file mode 100644 index 0000000000..2332ae6f75 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/instant-string.js @@ -0,0 +1,34 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getprevioustransition +description: Conversion of ISO date-time strings to Temporal.Instant instances +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +let str = "1970-01-01T00:00"; +assert.throws(RangeError, () => instance.getPreviousTransition(str), "bare date-time string is not an instant"); +str = "1970-01-01T00:00[UTC]"; +assert.throws(RangeError, () => instance.getPreviousTransition(str), "date-time + IANA annotation is not an instant"); + +// The following are all valid strings so should not throw: + +const valids = [ + "1970-01-01T00:00Z", + "1970-01-01T00:00+01:00", + "1970-01-01T00:00Z[UTC]", + "1970-01-01T00:00+01:00[UTC]", + "1970-01-01T00:00Z[u-ca=hebrew]", + "1970-01-01T00:00+01:00[u-ca=hebrew]", + "1970-01-01T00:00+01:00[Etc/Ignored][u-ca=hebrew]", +]; +for (const str of valids) { + const result = instance.getPreviousTransition(str); + assert.sameValue(result, null); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/leap-second.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/leap-second.js new file mode 100644 index 0000000000..8dfb639ffa --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/leap-second.js @@ -0,0 +1,21 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getprevioustransition +description: Leap second is a valid ISO string for Instant +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const arg = "2016-12-31T23:59:60Z"; +const result = instance.getPreviousTransition(arg); +assert.sameValue( + result, + null, + "leap second is a valid ISO string for Instant" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/length.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/length.js new file mode 100644 index 0000000000..37a5b93e73 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/length.js @@ -0,0 +1,28 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getprevioustransition +description: Temporal.TimeZone.prototype.getPreviousTransition.length is 1 +info: | + 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: [Temporal] +---*/ + +verifyProperty(Temporal.TimeZone.prototype.getPreviousTransition, "length", { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/name.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/name.js new file mode 100644 index 0000000000..637ae20484 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/name.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getprevioustransition +description: Temporal.TimeZone.prototype.getPreviousTransition.name is "getPreviousTransition". +info: | + 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: [Temporal] +---*/ + +verifyProperty(Temporal.TimeZone.prototype.getPreviousTransition, "name", { + value: "getPreviousTransition", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/not-a-constructor.js new file mode 100644 index 0000000000..ec424e01ef --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/not-a-constructor.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getprevioustransition +description: > + Temporal.TimeZone.prototype.getPreviousTransition does not implement [[Construct]], is not new-able +info: | + Built-in function objects that are not identified as constructors do not implement the + [[Construct]] internal method unless otherwise specified in the description of a particular + function. +includes: [isConstructor.js] +features: [Reflect.construct, Temporal] +---*/ + +assert.throws(TypeError, () => { + new Temporal.TimeZone.prototype.getPreviousTransition(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.TimeZone.prototype.getPreviousTransition), false, + "isConstructor(Temporal.TimeZone.prototype.getPreviousTransition)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/prop-desc.js new file mode 100644 index 0000000000..01d4f38f8d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/prop-desc.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getprevioustransition +description: The "getPreviousTransition" property of Temporal.TimeZone.prototype +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.TimeZone.prototype.getPreviousTransition, + "function", + "`typeof TimeZone.prototype.getPreviousTransition` is `function`" +); + +verifyProperty(Temporal.TimeZone.prototype, "getPreviousTransition", { + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/shell.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/shell.js new file mode 100644 index 0000000000..eda1477282 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/shell.js @@ -0,0 +1,24 @@ +// GENERATED, DO NOT EDIT +// file: isConstructor.js +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: | + Test if a given function is a constructor function. +defines: [isConstructor] +features: [Reflect.construct] +---*/ + +function isConstructor(f) { + if (typeof f !== "function") { + throw new Test262Error("isConstructor invoked with a non-function value"); + } + + try { + Reflect.construct(function(){}, [], f); + } catch (e) { + return false; + } + return true; +} diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/year-zero.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/year-zero.js new file mode 100644 index 0000000000..38dc0015a2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/year-zero.js @@ -0,0 +1,25 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getprevioustransition +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-03-30T00:45Z", + "-000000-03-30T01:45+01:00", + "-000000-03-30T01:45:00+00:00[UTC]", +]; +const instance = new Temporal.TimeZone("UTC"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.getPreviousTransition(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/id/branding.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/id/branding.js new file mode 100644 index 0000000000..4e7a026cab --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/id/branding.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-get-temporal.timezone.prototype.id +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const descriptor = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "id"); +const id = descriptor.get; + +assert.sameValue(typeof id, "function"); + +assert.throws(TypeError, () => id.call(undefined), "undefined"); +assert.throws(TypeError, () => id.call(null), "null"); +assert.throws(TypeError, () => id.call(true), "true"); +assert.throws(TypeError, () => id.call(""), "empty string"); +assert.throws(TypeError, () => id.call(Symbol()), "symbol"); +assert.throws(TypeError, () => id.call(1), "1"); +assert.throws(TypeError, () => id.call({}), "plain object"); +assert.throws(TypeError, () => id.call(Temporal.TimeZone), "Temporal.TimeZone"); +assert.throws(TypeError, () => id.call(Temporal.TimeZone.prototype), "Temporal.TimeZone.prototype"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/id/browser.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/id/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/id/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/id/custom-timezone.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/id/custom-timezone.js new file mode 100644 index 0000000000..cd3b1c1bfe --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/id/custom-timezone.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-get-temporal.timezone.prototype.id +description: Getter does not call toString(), returns the ID from internal slot +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const actual = []; +const expected = []; + +const timeZone = new Temporal.TimeZone("UTC"); +TemporalHelpers.observeProperty(actual, timeZone, Symbol.toPrimitive, undefined); +TemporalHelpers.observeProperty(actual, timeZone, "toString", function () { + actual.push("call timeZone.toString"); + return "time zone"; +}); + +const result = timeZone.id; +assert.compareArray(actual, expected); +assert.sameValue(result, "UTC"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/id/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/id/prop-desc.js new file mode 100644 index 0000000000..95694a0470 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/id/prop-desc.js @@ -0,0 +1,17 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-get-temporal.timezone.prototype.id +description: The "id" property of Temporal.TimeZone.prototype +features: [Temporal] +---*/ + +const descriptor = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "id"); +assert.sameValue(typeof descriptor.get, "function"); +assert.sameValue(descriptor.set, undefined); +assert.sameValue(descriptor.enumerable, false); +assert.sameValue(descriptor.configurable, true); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/id/shell.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/id/shell.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/id/shell.js diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/prop-desc.js new file mode 100644 index 0000000000..5caf215a07 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/prop-desc.js @@ -0,0 +1,21 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal-timezone-prototype +description: The "prototype" property of Temporal.TimeZone +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue(typeof Temporal.TimeZone.prototype, "object"); +assert.notSameValue(Temporal.TimeZone.prototype, null); + +verifyProperty(Temporal.TimeZone, "prototype", { + writable: false, + enumerable: false, + configurable: false, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/shell.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/shell.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/shell.js diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toJSON/branding.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toJSON/branding.js new file mode 100644 index 0000000000..55f3468d1a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toJSON/branding.js @@ -0,0 +1,25 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.tojson +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const toJSON = Temporal.TimeZone.prototype.toJSON; + +assert.sameValue(typeof toJSON, "function"); + +assert.throws(TypeError, () => toJSON.call(undefined), "undefined"); +assert.throws(TypeError, () => toJSON.call(null), "null"); +assert.throws(TypeError, () => toJSON.call(true), "true"); +assert.throws(TypeError, () => toJSON.call(""), "empty string"); +assert.throws(TypeError, () => toJSON.call(Symbol()), "symbol"); +assert.throws(TypeError, () => toJSON.call(1), "1"); +assert.throws(TypeError, () => toJSON.call({}), "plain object"); +assert.throws(TypeError, () => toJSON.call(Temporal.TimeZone), "Temporal.TimeZone"); +assert.throws(TypeError, () => toJSON.call(Temporal.TimeZone.prototype), "Temporal.TimeZone.prototype"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toJSON/browser.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toJSON/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toJSON/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toJSON/builtin.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toJSON/builtin.js new file mode 100644 index 0000000000..c16a991198 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toJSON/builtin.js @@ -0,0 +1,36 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.tojson +description: > + Tests that Temporal.TimeZone.prototype.toJSON + meets the requirements for built-in objects defined by the + introduction of chapter 17 of the ECMAScript Language Specification. +info: | + Built-in functions that are not constructors do not have a "prototype" property unless + otherwise specified in the description of a particular function. + + Unless specified otherwise, a built-in object that is callable as a function is a built-in + function object with the characteristics described in 10.3. Unless specified otherwise, the + [[Extensible]] internal slot of a built-in object initially has the value true. + + Unless otherwise specified every built-in function and every built-in constructor has the + Function prototype object [...] as the value of its [[Prototype]] internal slot. +features: [Temporal] +---*/ + +assert.sameValue(Object.isExtensible(Temporal.TimeZone.prototype.toJSON), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.TimeZone.prototype.toJSON), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.TimeZone.prototype.toJSON), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.TimeZone.prototype.toJSON.hasOwnProperty("prototype"), + false, "prototype property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toJSON/length.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toJSON/length.js new file mode 100644 index 0000000000..7d4793a807 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toJSON/length.js @@ -0,0 +1,28 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.tojson +description: Temporal.TimeZone.prototype.toJSON.length is 0 +info: | + 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: [Temporal] +---*/ + +verifyProperty(Temporal.TimeZone.prototype.toJSON, "length", { + value: 0, + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toJSON/name.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toJSON/name.js new file mode 100644 index 0000000000..8149ad2179 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toJSON/name.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.tojson +description: Temporal.TimeZone.prototype.toJSON.name is "toJSON". +info: | + 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: [Temporal] +---*/ + +verifyProperty(Temporal.TimeZone.prototype.toJSON, "name", { + value: "toJSON", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toJSON/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toJSON/not-a-constructor.js new file mode 100644 index 0000000000..be0d115a19 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toJSON/not-a-constructor.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.tojson +description: > + Temporal.TimeZone.prototype.toJSON does not implement [[Construct]], is not new-able +info: | + Built-in function objects that are not identified as constructors do not implement the + [[Construct]] internal method unless otherwise specified in the description of a particular + function. +includes: [isConstructor.js] +features: [Reflect.construct, Temporal] +---*/ + +assert.throws(TypeError, () => { + new Temporal.TimeZone.prototype.toJSON(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.TimeZone.prototype.toJSON), false, + "isConstructor(Temporal.TimeZone.prototype.toJSON)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toJSON/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toJSON/prop-desc.js new file mode 100644 index 0000000000..13ef61b296 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toJSON/prop-desc.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.tojson +description: The "toJSON" property of Temporal.TimeZone.prototype +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.TimeZone.prototype.toJSON, + "function", + "`typeof TimeZone.prototype.toJSON` is `function`" +); + +verifyProperty(Temporal.TimeZone.prototype, "toJSON", { + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toJSON/shell.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toJSON/shell.js new file mode 100644 index 0000000000..eda1477282 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toJSON/shell.js @@ -0,0 +1,24 @@ +// GENERATED, DO NOT EDIT +// file: isConstructor.js +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: | + Test if a given function is a constructor function. +defines: [isConstructor] +features: [Reflect.construct] +---*/ + +function isConstructor(f) { + if (typeof f !== "function") { + throw new Test262Error("isConstructor invoked with a non-function value"); + } + + try { + Reflect.construct(function(){}, [], f); + } catch (e) { + return false; + } + return true; +} diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toJSON/tostring-call.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toJSON/tostring-call.js new file mode 100644 index 0000000000..b55e076709 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toJSON/tostring-call.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.tojson +description: toJSON() calls toString() and returns its value +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const actual = []; +const expected = [ + 'get [Symbol.toPrimitive]', + 'get toString', + 'call timeZone.toString', +]; + +const timeZone = new Temporal.TimeZone("UTC"); +TemporalHelpers.observeProperty(actual, timeZone, Symbol.toPrimitive, undefined); +TemporalHelpers.observeProperty(actual, timeZone, "toString", function () { + actual.push("call timeZone.toString"); + return "Etc/TAI"; +}); + +const result = timeZone.toJSON(); +assert.sameValue(result, 'Etc/TAI', 'toString'); +assert.compareArray(actual, expected); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toJSON/tostring-undefined-custom.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toJSON/tostring-undefined-custom.js new file mode 100644 index 0000000000..d8a47e6018 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toJSON/tostring-undefined-custom.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.tojson +description: TypeError thrown when toString property not present +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const actual = []; +const expected = [ + 'get [Symbol.toPrimitive]', + 'get toString', + 'get valueOf', +]; + +const timeZone = new Temporal.TimeZone("UTC"); +TemporalHelpers.observeProperty(actual, timeZone, Symbol.toPrimitive, undefined); +TemporalHelpers.observeProperty(actual, timeZone, "toString", undefined); +TemporalHelpers.observeProperty(actual, timeZone, "valueOf", Object.prototype.valueOf); + +assert.throws(TypeError, () => timeZone.toJSON()); +assert.compareArray(actual, expected); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toJSON/tostring-undefined.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toJSON/tostring-undefined.js new file mode 100644 index 0000000000..1a8f80be98 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toJSON/tostring-undefined.js @@ -0,0 +1,16 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.tojson +description: TypeError thrown when toString property not present +features: [Temporal] +---*/ + +const tz = Temporal.TimeZone.from('UTC'); +tz.toString = undefined; + +assert.throws(TypeError, () => tz.toJSON()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toString/branding.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toString/branding.js new file mode 100644 index 0000000000..946916aea5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toString/branding.js @@ -0,0 +1,25 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.tostring +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const toString = Temporal.TimeZone.prototype.toString; + +assert.sameValue(typeof toString, "function"); + +assert.throws(TypeError, () => toString.call(undefined), "undefined"); +assert.throws(TypeError, () => toString.call(null), "null"); +assert.throws(TypeError, () => toString.call(true), "true"); +assert.throws(TypeError, () => toString.call(""), "empty string"); +assert.throws(TypeError, () => toString.call(Symbol()), "symbol"); +assert.throws(TypeError, () => toString.call(1), "1"); +assert.throws(TypeError, () => toString.call({}), "plain object"); +assert.throws(TypeError, () => toString.call(Temporal.TimeZone), "Temporal.TimeZone"); +assert.throws(TypeError, () => toString.call(Temporal.TimeZone.prototype), "Temporal.TimeZone.prototype"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toString/browser.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toString/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toString/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toString/builtin.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toString/builtin.js new file mode 100644 index 0000000000..272decf5f2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toString/builtin.js @@ -0,0 +1,36 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.tostring +description: > + Tests that Temporal.TimeZone.prototype.toString + meets the requirements for built-in objects defined by the + introduction of chapter 17 of the ECMAScript Language Specification. +info: | + Built-in functions that are not constructors do not have a "prototype" property unless + otherwise specified in the description of a particular function. + + Unless specified otherwise, a built-in object that is callable as a function is a built-in + function object with the characteristics described in 10.3. Unless specified otherwise, the + [[Extensible]] internal slot of a built-in object initially has the value true. + + Unless otherwise specified every built-in function and every built-in constructor has the + Function prototype object [...] as the value of its [[Prototype]] internal slot. +features: [Temporal] +---*/ + +assert.sameValue(Object.isExtensible(Temporal.TimeZone.prototype.toString), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.TimeZone.prototype.toString), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.TimeZone.prototype.toString), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.TimeZone.prototype.toString.hasOwnProperty("prototype"), + false, "prototype property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toString/length.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toString/length.js new file mode 100644 index 0000000000..367b49732e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toString/length.js @@ -0,0 +1,28 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.tostring +description: Temporal.TimeZone.prototype.toString.length is 0 +info: | + 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: [Temporal] +---*/ + +verifyProperty(Temporal.TimeZone.prototype.toString, "length", { + value: 0, + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toString/name.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toString/name.js new file mode 100644 index 0000000000..35e4154ae1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toString/name.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.tostring +description: Temporal.TimeZone.prototype.toString.name is "toString". +info: | + 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: [Temporal] +---*/ + +verifyProperty(Temporal.TimeZone.prototype.toString, "name", { + value: "toString", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toString/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toString/not-a-constructor.js new file mode 100644 index 0000000000..0eba8d4a57 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toString/not-a-constructor.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.tostring +description: > + Temporal.TimeZone.prototype.toString does not implement [[Construct]], is not new-able +info: | + Built-in function objects that are not identified as constructors do not implement the + [[Construct]] internal method unless otherwise specified in the description of a particular + function. +includes: [isConstructor.js] +features: [Reflect.construct, Temporal] +---*/ + +assert.throws(TypeError, () => { + new Temporal.TimeZone.prototype.toString(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.TimeZone.prototype.toString), false, + "isConstructor(Temporal.TimeZone.prototype.toString)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toString/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toString/prop-desc.js new file mode 100644 index 0000000000..388c4688fc --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toString/prop-desc.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.tostring +description: The "toString" property of Temporal.TimeZone.prototype +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.TimeZone.prototype.toString, + "function", + "`typeof TimeZone.prototype.toString` is `function`" +); + +verifyProperty(Temporal.TimeZone.prototype, "toString", { + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toString/shell.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toString/shell.js new file mode 100644 index 0000000000..eda1477282 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toString/shell.js @@ -0,0 +1,24 @@ +// GENERATED, DO NOT EDIT +// file: isConstructor.js +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: | + Test if a given function is a constructor function. +defines: [isConstructor] +features: [Reflect.construct] +---*/ + +function isConstructor(f) { + if (typeof f !== "function") { + throw new Test262Error("isConstructor invoked with a non-function value"); + } + + try { + Reflect.construct(function(){}, [], f); + } catch (e) { + return false; + } + return true; +} diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toStringTag/browser.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toStringTag/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toStringTag/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toStringTag/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toStringTag/prop-desc.js new file mode 100644 index 0000000000..9af77e9072 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toStringTag/prop-desc.js @@ -0,0 +1,19 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype-@@tostringtag +description: The @@toStringTag property of Temporal.TimeZone +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +verifyProperty(Temporal.TimeZone.prototype, Symbol.toStringTag, { + value: "Temporal.TimeZone", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toStringTag/shell.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toStringTag/shell.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toStringTag/shell.js diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/shell.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/shell.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/shell.js diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/subclass.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/subclass.js new file mode 100644 index 0000000000..c02f9c1745 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/subclass.js @@ -0,0 +1,20 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone +description: Test for Temporal.TimeZone subclassing. +features: [Temporal] +---*/ + +class CustomTimeZone extends Temporal.TimeZone { +} + +const instance = new CustomTimeZone("UTC"); +assert.sameValue(instance.toString(), "UTC"); +assert.sameValue(Object.getPrototypeOf(instance), CustomTimeZone.prototype, "Instance of CustomTimeZone"); +assert(instance instanceof CustomTimeZone, "Instance of CustomTimeZone"); +assert(instance instanceof Temporal.TimeZone, "Instance of Temporal.TimeZone"); + +reportCompare(0, 0); |