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/Calendar | |
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/Calendar')
844 files changed, 25591 insertions, 0 deletions
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/builtin.js new file mode 100644 index 0000000000..d0617956a3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/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.calendar +description: Tests that Temporal.Calendar 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.Calendar), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.Calendar), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.Calendar), + Function.prototype, "prototype"); + +assert.sameValue(typeof Temporal.Calendar.prototype, + "object", "prototype property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/constructor.js new file mode 100644 index 0000000000..b5c7964278 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/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.calendar +description: Temporal.Calendar constructor cannot be called as a function +info: | + 1. If NewTarget is undefined, throw a TypeError exception. +features: [Temporal] +---*/ + +assert.throws(TypeError, () => Temporal.Calendar("iso8601")); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/from/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/from/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/from/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/builtin.js new file mode 100644 index 0000000000..d469728569 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/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.calendar.from +description: Tests that Temporal.Calendar.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.Calendar.from), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.from), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.from), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.Calendar.from.hasOwnProperty("prototype"), + false, "prototype property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-case-insensitive.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-case-insensitive.js new file mode 100644 index 0000000000..16911307aa --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-case-insensitive.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.calendar.from +description: Calendar names are case-insensitive +features: [Temporal] +---*/ + +const arg = "iSo8601"; + +const result = Temporal.Calendar.from(arg); +assert.sameValue(result.id, "iso8601", "Calendar is case-insensitive"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-instance-does-not-get-calendar-property.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-instance-does-not-get-calendar-property.js new file mode 100644 index 0000000000..9e0a4b5e07 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-instance-does-not-get-calendar-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.calendar.from +description: > + A Temporal.Calendar instance passed to from() does not have its + 'calendar' property observably checked +features: [Temporal] +---*/ + +const arg = new Temporal.Calendar("iso8601"); +Object.defineProperty(arg, "calendar", { + get() { + throw new Test262Error("calendar.calendar should not be accessed"); + }, +}); + +Temporal.Calendar.from(arg); +Temporal.Calendar.from({ calendar: arg }); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-number.js new file mode 100644 index 0000000000..6067e42295 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-number.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.calendar.from +description: A number is converted to a string, then to Temporal.Calendar +features: [Temporal] +---*/ + +const arg = 19761118; + +const result = Temporal.Calendar.from(arg); +assert.sameValue(result.id, "iso8601", "19761118 is a valid ISO string for Calendar"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => Temporal.Calendar.from(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/Calendar/from/calendar-object-invalid.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-object-invalid.js new file mode 100644 index 0000000000..f22e9726e5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-object-invalid.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.calendar.from +description: Converting objects to Temporal.Calendar +features: [Temporal] +---*/ + +assert.throws(RangeError, () => Temporal.Calendar.from({ calendar: "local" })); +assert.throws(RangeError, () => Temporal.Calendar.from({ calendar: { calendar: "iso8601" } })); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-object-operations.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-object-operations.js new file mode 100644 index 0000000000..74e7eb2ec4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-object-operations.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.calendar.from +description: Converting objects to Temporal.Calendar +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + "has outer.calendar", + "get outer.calendar", + "has inner.calendar", + "get inner.toString", + "call inner.toString", +]; +const actual = []; +const calendar = TemporalHelpers.propertyBagObserver(actual, { + calendar: new Proxy(TemporalHelpers.toPrimitiveObserver(actual, "iso8601", "inner"), { + has(t, p) { + actual.push(`has inner.${p}`); + return true; + }, + get(t, p) { + return t[p]; + }, + }), +}, "outer"); +const result = Temporal.Calendar.from(calendar); +assert.sameValue(result.id, "iso8601"); +assert.compareArray(actual, expected); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-object.js new file mode 100644 index 0000000000..c27e952acd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-object.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.calendar.from +description: Converting objects to Temporal.Calendar +features: [Temporal] +---*/ + +const cal = new Temporal.Calendar("iso8601"); +const calFromObject = Temporal.Calendar.from({ calendar: cal }); +assert(calFromObject instanceof Temporal.Calendar); +assert.sameValue(calFromObject.id, "iso8601"); + +const calFromString = Temporal.Calendar.from({ calendar: "iso8601" }); +assert(calFromString instanceof Temporal.Calendar); +assert.sameValue(calFromString.id, "iso8601"); + +const custom = { id: "custom-calendar" }; +assert.sameValue(Temporal.Calendar.from({ calendar: custom }), custom); +assert.sameValue(Temporal.Calendar.from(custom), custom); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-string-builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-string-builtin.js new file mode 100644 index 0000000000..7a8f6e0381 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-string-builtin.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.calendar.from +description: Calendar.from should support iso8601. +features: [Temporal] +---*/ + +const tests = [ + "iso8601", + "1994-11-05T08:15:30-05:00", +]; + +for (const item of tests) { + const calendar = Temporal.Calendar.from(item); + assert(calendar instanceof Temporal.Calendar); + assert.sameValue(calendar.id, "iso8601"); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-string-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-string-leap-second.js new file mode 100644 index 0000000000..da5f1a2f20 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-string-leap-second.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.calendar.from +description: Leap second is a valid ISO string for Calendar +features: [Temporal] +---*/ + +let arg = "2016-12-31T23:59:60"; +const result1 = Temporal.Calendar.from(arg); +assert.sameValue( + result1.id, + "iso8601", + "leap second is a valid ISO string for Calendar" +); + +arg = { calendar: "2016-12-31T23:59:60" }; +const result2 = Temporal.Calendar.from(arg); +assert.sameValue( + result2.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/Calendar/from/calendar-string-not-builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-string-not-builtin.js new file mode 100644 index 0000000000..5c51349524 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-string-not-builtin.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.calendar.from +description: from() throws if the argument is not a built-in calendar name. +features: [Temporal] +---*/ + +const tests = [ + "local", + "iso-8601", + "[u-ca=iso8601]", + "invalid-calendar", +]; + +for (const item of tests) { + assert.throws(RangeError, () => Temporal.Calendar.from(item)); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-string.js new file mode 100644 index 0000000000..367e32ae99 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-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.calendar.from +description: A calendar ID is valid input for Calendar +features: [Temporal] +---*/ + +const arg = "iso8601"; + +const result = Temporal.Calendar.from(arg); +assert.sameValue(result.id, "iso8601", `Calendar created from string "${arg}"`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-temporal-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-temporal-object.js new file mode 100644 index 0000000000..baba22dc53 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-temporal-object.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.calendar.from +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 result = Temporal.Calendar.from(arg); + assert.sameValue(result, 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/Calendar/from/calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-wrong-type.js new file mode 100644 index 0000000000..625d4058fe --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-wrong-type.js @@ -0,0 +1,36 @@ +// |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.calendar.from +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for Calendar +features: [BigInt, Symbol, Temporal] +---*/ + +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, () => Temporal.Calendar.from(arg), `${description} does not convert to a valid ISO string`); + assert.throws(RangeError, () => Temporal.Calendar.from({ 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, () => Temporal.Calendar.from(arg), `${description} is not a valid object and does not convert to a string`); + assert.throws(TypeError, () => Temporal.Calendar.from({ 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/Calendar/from/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/length.js new file mode 100644 index 0000000000..8188e06b70 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/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.calendar.from +description: Temporal.Calendar.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.Calendar.from, "length", { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/from/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/name.js new file mode 100644 index 0000000000..8b985c5d98 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/from/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.calendar.from +description: Temporal.Calendar.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.Calendar.from, "name", { + value: "from", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/from/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/not-a-constructor.js new file mode 100644 index 0000000000..486af14494 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/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.calendar.from +description: Temporal.Calendar.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.Calendar.from(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.Calendar.from), false, + "isConstructor(Temporal.Calendar.from)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/from/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/prop-desc.js new file mode 100644 index 0000000000..2b624f4251 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/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.calendar.from +description: The "from" property of Temporal.Calendar +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.Calendar.from, + "function", + "`typeof Calendar.from` is `function`" +); + +verifyProperty(Temporal.Calendar, "from", { + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/from/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/shell.js new file mode 100644 index 0000000000..eda1477282 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/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/Calendar/from/subclassing-ignored.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/subclassing-ignored.js new file mode 100644 index 0000000000..8166ac7da1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/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.calendar.from +description: The receiver is never called when calling from() +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +TemporalHelpers.checkSubclassingIgnoredStatic( + Temporal.Calendar, + "from", + ["iso8601"], + (result) => { + assert.sameValue(result.id, "iso8601", "id property of result"); + assert.sameValue(result.toString(), "iso8601", "toString() of result"); + }, +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/length.js new file mode 100644 index 0000000000..e8d3e8e41a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/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.calendar +description: Temporal.Calendar.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.Calendar, "length", { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/missing-arguments.js b/js/src/tests/test262/built-ins/Temporal/Calendar/missing-arguments.js new file mode 100644 index 0000000000..f9afe5f7d2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/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.calendar +description: RangeError thrown when constructor invoked with no argument +features: [Temporal] +---*/ + +assert.throws(RangeError, () => new Temporal.Calendar()); +assert.throws(RangeError, () => new Temporal.Calendar(undefined)); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/name.js new file mode 100644 index 0000000000..7ceb715093 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/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.calendar +description: Temporal.Calendar.name is "Calendar" +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.Calendar, "name", { + value: "Calendar", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prop-desc.js new file mode 100644 index 0000000000..73e036f1cc --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/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.calendar +description: The "Calendar" property of Temporal +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.Calendar, + "function", + "`typeof Calendar` is `function`" +); + +verifyProperty(Temporal, "Calendar", { + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/constructor.js new file mode 100644 index 0000000000..41d0830ce8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/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.calendar.prototype.constructor +description: Test for Temporal.Calendar.prototype.constructor. +info: The initial value of Temporal.Calendar.prototype.constructor is %Temporal.Calendar%. +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +verifyProperty(Temporal.Calendar.prototype, "constructor", { + value: Temporal.Calendar, + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-days.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-days.js new file mode 100644 index 0000000000..854e8bc120 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-days.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dateadd +description: Temporal.Calendar.prototype.dateAdd add duration with days and calculate correctly.. +info: | + 8. Let result be ? AddISODate(date.[[ISOYear]], date.[[ISOMonth]], date.[[ISODay]], duration.[[Years]], duration.[[Months]], duration.[[Weeks]], duration.[[Days]], overflow). +features: [Temporal] +includes: [temporalHelpers.js] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +let p10d = new Temporal.Duration(0,0,0,10); + +TemporalHelpers.assertPlainDate( + cal.dateAdd("2021-07-16", p10d), 2021, 7, "M07", 26, + "add 10 days and result into the same month"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2021-07-26", p10d), 2021, 8, "M08", 5, + "add 10 days and result into next month"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2021-12-26", p10d), 2022, 1, "M01", 5, + "add 10 days and result into next year"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2020-02-26", p10d), 2020, 3, "M03", 7, + "add 10 days from a leap year in Feb and result into March"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2021-02-26", p10d), 2021, 3, "M03", 8, + "add 10 days from a non leap year in Feb and result into March"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2020-02-19", p10d), 2020, 2, "M02", 29, + "add 10 days from a leap year in Feb 19 and result into Feb 29"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2021-02-19", p10d), 2021, 3, "M03", 1, + "add 10 days from a non leap year in Feb 19 and result into March 1"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-months-weeks.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-months-weeks.js new file mode 100644 index 0000000000..278ea1a1ba --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-months-weeks.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dateadd +description: Temporal.Calendar.prototype.dateAdd add duration with months and weeks and calculate correctly. +info: | + 8. Let result be ? AddISODate(date.[[ISOYear]], date.[[ISOMonth]], date.[[ISODay]], duration.[[Years]], duration.[[Months]], duration.[[Weeks]], duration.[[Days]], overflow). +features: [Temporal] +includes: [temporalHelpers.js] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +let p2m3w = new Temporal.Duration(0,2,3); + +TemporalHelpers.assertPlainDate( + cal.dateAdd("2020-02-29", p2m3w), 2020, 5, "M05", 20, + "add two months 3 weeks from Feb 29 of a leap year"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2020-02-28", p2m3w), 2020, 5, "M05", 19, + "add two months 3 weeks from Feb 28 of a leap year"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2021-02-28", p2m3w), 2021, 5, "M05", 19, + "add two months 3 weeks from Feb 28 of a non leap year"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2020-12-28", p2m3w), 2021, 3, "M03", 21, + "add two months 3 weeks from end of year to non leap year"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2019-12-28", p2m3w), 2020, 3, "M03", 20, + "add two months 3 weeks from end of year to leap year"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2019-10-28", p2m3w), 2020, 1, "M01", 18, + "add two months 3 weeks and cause roll into a new year"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2019-10-31", p2m3w), 2020, 1, "M01", 21, + "add two months 3 weeks and cause roll into a new year"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-months.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-months.js new file mode 100644 index 0000000000..76a349aeba --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-months.js @@ -0,0 +1,36 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dateadd +description: Temporal.Calendar.prototype.dateAdd add duration with months and calculate correctly +info: | + 8. Let result be ? AddISODate(date.[[ISOYear]], date.[[ISOMonth]], date.[[ISODay]], duration.[[Years]], duration.[[Months]], duration.[[Weeks]], duration.[[Days]], overflow). +features: [Temporal] +includes: [temporalHelpers.js] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +let p5m = new Temporal.Duration(0, 5); + +TemporalHelpers.assertPlainDate( + cal.dateAdd("2021-07-16", p5m), 2021, 12, "M12", 16, + "add five months and result in the same year"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2021-08-16", p5m), 2022, 1, "M01", 16, + "add five months and result in the next year"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2021-10-31", p5m), 2022, 3, "M03", 31, + "add five months and result in the next year in end of month"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2019-10-01", p5m), 2020, 3, "M03", 1, + "add five months and result in the next year in end of month on leap year"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2021-09-30", p5m), 2022, 2, "M02", 28, + "add five months and result in the nexdt year and constrain to Feb 28"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2019-09-30", p5m), 2020, 2, "M02", 29, + "add five months and result in the nexdt year and constrain to Feb 29 on leap year"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-weeks-days.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-weeks-days.js new file mode 100644 index 0000000000..da1fe195c1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-weeks-days.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dateadd +description: Temporal.Calendar.prototype.dateAdd add duration with weeks and days and calculate correctly. +info: | + 8. Let result be ? AddISODate(date.[[ISOYear]], date.[[ISOMonth]], date.[[ISODay]], duration.[[Years]], duration.[[Months]], duration.[[Weeks]], duration.[[Days]], overflow). +features: [Temporal] +includes: [temporalHelpers.js] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +let p2w3d = new Temporal.Duration(0,0,2,3); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2020-02-29", p2w3d), 2020, 3, "M03", 17, + "add 2 weeks and 3 days (17 days) from Feb 29 in a leap year and cause rolling into March"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2021-02-28", p2w3d), 2021, 3, "M03", 17, + "add 2 weeks and 3 days (17 days) from Feb and cause rolling into March in a non leap year"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2020-02-28", p2w3d), 2020, 3, "M03", 16, + "add 2 weeks and 3 days (17 days) from Feb and cause rolling into March in a leap year"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2020-12-28", p2w3d), 2021, 1, "M01", 14, + "add 2 weeks and 3 days (17 days) and cause rolling into a new year"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-weeks.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-weeks.js new file mode 100644 index 0000000000..ab510c9542 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-weeks.js @@ -0,0 +1,66 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dateadd +description: Temporal.Calendar.prototype.dateAdd add duration with weeks and calculate correctly. +info: | + 8. Let result be ? AddISODate(date.[[ISOYear]], date.[[ISOMonth]], date.[[ISODay]], duration.[[Years]], duration.[[Months]], duration.[[Weeks]], duration.[[Days]], overflow). +features: [Temporal] +includes: [temporalHelpers.js] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +let p1w = new Temporal.Duration(0,0,1); +let p6w = new Temporal.Duration(0,0,6); + +TemporalHelpers.assertPlainDate( + cal.dateAdd("2021-02-19", p1w), 2021, 2, "M02", 26, + "add one week in Feb"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2021-02-27", p1w), 2021, 3, "M03", 6, + "add one week in Feb and result in March"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2020-02-27", p1w), 2020, 3, "M03", 5, + "add one week in Feb and result in March in a leap year"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2021-12-24", p1w), 2021, 12, "M12", 31, + "add one week and result in the last day of a year"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2021-12-25", p1w), 2022, 1, "M01", 1, + "add one week and result in the first day of next year"); + +TemporalHelpers.assertPlainDate( + cal.dateAdd("2021-01-27", p1w), 2021, 2, "M02", 3, + "add one week and result in next month from a month with 31 days"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2021-06-27", p1w), 2021, 7, "M07", 4, + "add one week and result in next month from a month with 30 days"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2021-07-27", p1w), 2021, 8, "M08", 3, + "add one week and result in next month from a month with 31 days"); + +TemporalHelpers.assertPlainDate( + cal.dateAdd("2021-02-19", p6w), 2021, 4, "M04", 2, + "add six weeks and result in next month from Feb in a non leap year"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2020-02-19", p6w), 2020, 4, "M04", 1, + "add six weeks and result in next month from Feb in a leap year"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2021-12-24", p6w), 2022, 2, "M02", 4, + "add six weeks and result in the next year"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2021-01-27", p6w), 2021, 3, "M03", 10, + "add six weeks and result in the same year"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2020-01-27", p6w), 2020, 3, "M03", 9, + "add six weeks and result in the same year"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2021-06-27", p6w), 2021, 8, "M08", 8, + "add six weeks and result in the same year crossing month of 30 and 31 days"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2021-07-27", p6w), 2021, 9, "M09", 7, + "add six weeks and result in the same year crossing month of 31 and 31 days"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-years-months-days.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-years-months-days.js new file mode 100644 index 0000000000..f8a003d461 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-years-months-days.js @@ -0,0 +1,48 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dateadd +description: Temporal.Calendar.prototype.dateAdd add duration with years, months and days and calculate correctly. +info: | + 8. Let result be ? AddISODate(date.[[ISOYear]], date.[[ISOMonth]], date.[[ISODay]], duration.[[Years]], duration.[[Months]], duration.[[Weeks]], duration.[[Days]], overflow). +features: [Temporal] +includes: [temporalHelpers.js] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +let p1y2m4d = new Temporal.Duration(1,2,0,4); + +TemporalHelpers.assertPlainDate( + cal.dateAdd("2021-07-16", p1y2m4d), 2022, 9, "M09", 20, + "add one year two months and 4 days"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2021-02-27", p1y2m4d), 2022, 5, "M05", 1, + "add one year two months and 4 days and roll into new month from a month of 30 days"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2021-01-28", p1y2m4d), 2022, 4, "M04", 1, + "add one year two months and 4 days and roll into new month from a month of 31 days"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2021-02-26", p1y2m4d), 2022, 4, "M04", 30, + "add one year two months and 4 days which roll from March to April in a non leap year"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2023-02-26", p1y2m4d), 2024, 4, "M04", 30, + "add one year two months and 4 days which roll from March to April in a leap year"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2021-12-30", p1y2m4d), 2023, 3, "M03", 4, + "add one year two months and 4 days which roll month into new year and roll day into March in non leap year"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2022-12-30", p1y2m4d), 2024, 3, "M03", 4, + "add one year two months and 4 days which roll month into new year and roll day into March in leap year"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2022-12-29", p1y2m4d), 2024, 3, "M03", 4, + "add one year two months and 4 days which roll month into new year and roll day into March in leap year"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2021-07-30", p1y2m4d), 2022, 10, "M10", 4, + "add one year two months and 4 days which roll into a new month from a month with 30 days"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2021-06-30", p1y2m4d), 2022, 9, "M09", 3, + "add one year two months and 4 days which roll into a new month from a month with 31 days"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-years-months.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-years-months.js new file mode 100644 index 0000000000..bf67a3e3bc --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-years-months.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dateadd +description: Temporal.Calendar.prototype.dateAdd add duration with years and months and calculate correctly. +info: | + 8. Let result be ? AddISODate(date.[[ISOYear]], date.[[ISOMonth]], date.[[ISODay]], duration.[[Years]], duration.[[Months]], duration.[[Weeks]], duration.[[Days]], overflow). +features: [Temporal] +includes: [temporalHelpers.js] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +let p1y2m = new Temporal.Duration(1,2); + +TemporalHelpers.assertPlainDate( + cal.dateAdd("2021-07-16", p1y2m), 2022, 9, "M09", 16, + "add one year and 2 months"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2021-11-30", p1y2m), 2023, 1, "M01", 30, + "add one year and 2 months roll into a new year"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2021-12-31", p1y2m), 2023, 2, "M02", 28, + "add one year and 2 months roll into a new year and constrain in Feb 28 of a non leap year"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2022-12-31", p1y2m), 2024, 2, "M02", 29, + "add one year and 2 months roll into a new year and constrain in Feb 29 of a leap year"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-years-weeks.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-years-weeks.js new file mode 100644 index 0000000000..d47730ca1b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-years-weeks.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dateadd +description: Temporal.Calendar.prototype.dateAdd add duration with years and weeks and calculate correctly. +info: | + 8. Let result be ? AddISODate(date.[[ISOYear]], date.[[ISOMonth]], date.[[ISODay]], duration.[[Years]], duration.[[Months]], duration.[[Weeks]], duration.[[Days]], overflow). +features: [Temporal] +includes: [temporalHelpers.js] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +let p1y2w = new Temporal.Duration(1,0,2); + +TemporalHelpers.assertPlainDate( + cal.dateAdd("2020-02-28", p1y2w), 2021, 3, "M03", 14, + "add 1 year and 2 weeks to Feb 28 and cause roll into March in a non leap year"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2020-02-29", p1y2w), 2021, 3, "M03", 14, + "add 1 year and 2 weeks to Feb 29 and cause roll into March in a non leap year"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2019-02-28", p1y2w), 2020, 3, "M03", 13, + "add 1 year and 2 weeks to Feb 28 and cause roll into March in a leap year"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2021-02-28", p1y2w), 2022, 3, "M03", 14, + "add 1 year and 2 weeks to Feb 28 and cause roll into March in a non leap year"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2020-12-28", p1y2w), 2022, 1, "M01", 11, + "add 1 year and 2 weeks and cause roll into a new year"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-years.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-years.js new file mode 100644 index 0000000000..5f34a0c213 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-years.js @@ -0,0 +1,28 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dateadd +description: Temporal.Calendar.prototype.dateAdd add duration with years only calculate correctly. +info: | + 8. Let result be ? AddISODate(date.[[ISOYear]], date.[[ISOMonth]], date.[[ISODay]], duration.[[Years]], duration.[[Months]], duration.[[Weeks]], duration.[[Days]], overflow). +features: [Temporal] +includes: [temporalHelpers.js] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +let p1y = new Temporal.Duration(1); +let p4y = new Temporal.Duration(4); + +TemporalHelpers.assertPlainDate( + cal.dateAdd("2020-02-29", p1y), 2021, 2, "M02", 28, + "add one year on Feb 29"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2020-02-29", p4y), 2024, 2, "M02", 29, + "add four years on Feb 29"); +TemporalHelpers.assertPlainDate( + cal.dateAdd("2021-07-16", p1y), 2022, 7, "M07", 16, + "add one year on other date"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-calendar-datefromfields-called-with-null-prototype-fields.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-calendar-datefromfields-called-with-null-prototype-fields.js new file mode 100644 index 0000000000..27f0c1e248 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-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.calendar.prototype.dateadd +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.Calendar("iso8601"); +const arg = { year: 2000, month: 5, day: 2, calendar }; +instance.dateAdd(arg, new Temporal.Duration()); +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/Calendar/prototype/dateAdd/argument-duration-years-and-months-number-max-value.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-duration-years-and-months-number-max-value.js new file mode 100644 index 0000000000..5c2c6c9968 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-duration-years-and-months-number-max-value.js @@ -0,0 +1,36 @@ +// |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.calendar.prototype.dateadd +description: > + Call BalanceISOYearMonth with Number.MAX_VALUE and -Number.MAX_VALUE for years/months. +info: | + Temporal.Calendar.prototype.dateAdd ( date, duration [ , options ] ) + + ... + 9. Let result be ? AddISODate(date.[[ISOYear]], date.[[ISOMonth]], date.[[ISODay]], + duration.[[Years]], duration.[[Months]], duration.[[Weeks]], balanceResult.[[Days]], + overflow). + 10. Return ? CreateTemporalDate(result.[[Year]], result.[[Month]], result.[[Day]], calendar). + + AddISODate ( year, month, day, years, months, weeks, days, overflow ) + + ... + 3. Let intermediate be ! BalanceISOYearMonth(year + years, month + months). + ... + +features: [Temporal] +---*/ + +var cal = new Temporal.Calendar("iso8601"); +var date = new Temporal.PlainDate(1970, 1, 1); + +var maxValue = new Temporal.Duration(Number.MAX_VALUE, Number.MAX_VALUE); +var minValue = new Temporal.Duration(-Number.MAX_VALUE, -Number.MAX_VALUE); + +assert.throws(RangeError, () => cal.dateAdd(date, maxValue), "years/months is +Number.MAX_VALUE"); +assert.throws(RangeError, () => cal.dateAdd(date, minValue), "years/months is -Number.MAX_VALUE"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-leap-second.js new file mode 100644 index 0000000000..7fca2be0ea --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-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.calendar.prototype.dateadd +description: Leap second is a valid ISO string for PlainDate +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.dateAdd(arg, new Temporal.Duration()); +TemporalHelpers.assertPlainDate( + result1, + 2016, 12, "M12", 31, + "leap second is a valid ISO string for PlainDate" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.dateAdd(arg, new Temporal.Duration()); +TemporalHelpers.assertPlainDate( + result2, + 2016, 12, "M12", 31, + "second: 60 is ignored in property bag for PlainDate" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-number.js new file mode 100644 index 0000000000..4e397a5704 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/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.calendar.prototype.dateadd +description: A number is converted to a string, then to Temporal.PlainDate +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const arg = 19761118; + +const result = instance.dateAdd(arg, new Temporal.Duration()); +TemporalHelpers.assertPlainDate(result, 1976, 11, "M11", 18, "19761118 is a valid ISO string for PlainDate"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.dateAdd(arg, new Temporal.Duration()), + `Number ${arg} does not convert to a valid ISO string for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-plaindatetime.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-plaindatetime.js new file mode 100644 index 0000000000..26f3dca6e9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-plaindatetime.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.calendar.prototype.dateadd +description: Fast path for converting Temporal.PlainDateTime to Temporal.PlainDate by reading internal slots +info: | + sec-temporal.calendar.prototype.dateadd step 4: + 4. Set _date_ to ? ToTemporalDate(_date_). + sec-temporal-totemporaldate step 2.b: + b. If _item_ has an [[InitializedTemporalDateTime]] internal slot, then + i. Return ! CreateTemporalDate(_item_.[[ISOYear]], _item_.[[ISOMonth]], _item_.[[ISODay]], _item_.[[Calendar]]). +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +TemporalHelpers.checkPlainDateTimeConversionFastPath((datetime) => { + const calendar = new Temporal.Calendar("iso8601"); + const duration = new Temporal.Duration(0, 1); + const result = calendar.dateAdd(datetime, duration); + TemporalHelpers.assertPlainDate(result, 2000, 6, "M06", 2); + assert.sameValue(result.hour, undefined, "instance of PlainDate returned, not PlainDateTime"); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-case-insensitive.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-case-insensitive.js new file mode 100644 index 0000000000..8f2cd07f92 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/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.calendar.prototype.dateadd +description: The calendar name is case-insensitive +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "IsO8601"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.dateAdd(arg, new Temporal.Duration()); +TemporalHelpers.assertPlainDate(result1, 1976, 11, "M11", 18, "Calendar is case-insensitive"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.dateAdd(arg, new Temporal.Duration()); +TemporalHelpers.assertPlainDate(result2, 1976, 11, "M11", 18, "Calendar is case-insensitive (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-instance-does-not-get-calendar-property.js new file mode 100644 index 0000000000..95a73abc81 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/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.calendar.prototype.dateadd +description: > + A Temporal.Calendar instance passed to dateAdd() in a property bag does + not have its 'calendar' property observably checked +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +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.dateAdd(arg, new Temporal.Duration()); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +instance.dateAdd(arg, new Temporal.Duration()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-leap-second.js new file mode 100644 index 0000000000..61515aa767 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/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.calendar.prototype.dateadd +description: Leap second is a valid ISO string for a calendar in a property bag +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.dateAdd(arg, new Temporal.Duration()); +TemporalHelpers.assertPlainDate( + result1, + 1976, 11, "M11", 18, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.dateAdd(arg, new Temporal.Duration()); +TemporalHelpers.assertPlainDate( + result2, + 1976, 11, "M11", 18, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-number.js new file mode 100644 index 0000000000..8e4a02f921 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/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.calendar.prototype.dateadd +description: A number as calendar in a property bag is converted to a string, then to a calendar +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.dateAdd(arg, new Temporal.Duration()); +TemporalHelpers.assertPlainDate(result1, 1976, 11, "M11", 18, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.dateAdd(arg, new Temporal.Duration()); +TemporalHelpers.assertPlainDate(result2, 1976, 11, "M11", 18, "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.dateAdd(arg, new Temporal.Duration()), + `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.dateAdd(arg, new Temporal.Duration()), + `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/Calendar/prototype/dateAdd/argument-propertybag-calendar-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-string.js new file mode 100644 index 0000000000..173aef0bb6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/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.calendar.prototype.dateadd +description: A calendar ID is valid input for Calendar +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "iso8601"; + +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.dateAdd(arg, new Temporal.Duration()); +TemporalHelpers.assertPlainDate(result, 1976, 11, "M11", 18, `Calendar created from string "${calendar}"`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 0000000000..17503632d5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/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.calendar.prototype.dateadd +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.Calendar("iso8601"); + +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.dateAdd(arg, new Temporal.Duration()), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.dateAdd(arg, new Temporal.Duration()), `${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.dateAdd(arg, new Temporal.Duration()), `${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.dateAdd(arg, new Temporal.Duration()), `${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.dateAdd(arg, new Temporal.Duration()), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-year-zero.js new file mode 100644 index 0000000000..3d69c67990 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/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.calendar.prototype.dateadd +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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.dateAdd(arg, new Temporal.Duration()), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-calendar-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-calendar-annotation.js new file mode 100644 index 0000000000..5a4709c731 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/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.calendar.prototype.dateadd +description: Various forms of calendar annotation; critical flag has no effect +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const tests = [ + ["2000-05-02[u-ca=iso8601]", "without time or time zone"], + ["2000-05-02[UTC][u-ca=iso8601]", "with time zone and no time"], + ["2000-05-02T15:23[u-ca=iso8601]", "without time zone"], + ["2000-05-02T15:23[UTC][u-ca=iso8601]", "with time zone"], + ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], + ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], + ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], + ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.dateAdd(arg, new Temporal.Duration()); + + TemporalHelpers.assertPlainDate( + result, + 2000, 5, "M05", 2, + `calendar annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-critical-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-critical-unknown-annotation.js new file mode 100644 index 0000000000..5bf8c2c1bb --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-critical-unknown-annotation.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.calendar.prototype.dateadd +description: Unknown annotations with critical flag are rejected +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[!foo=bar]", + "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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.dateAdd(arg, new Temporal.Duration()), + `reject unknown annotation with critical flag: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-date-with-utc-offset.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-date-with-utc-offset.js new file mode 100644 index 0000000000..5494e86541 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/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.calendar.prototype.dateadd +description: UTC offset not valid with format that does not include a time +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const validStrings = [ + "2000-05-02T00+00:00", + "2000-05-02T00+00:00[UTC]", + "2000-05-02T00+00:00[!UTC]", + "2000-05-02T00-02:30[America/St_Johns]", +]; + +for (const arg of validStrings) { + const result = instance.dateAdd(arg, new Temporal.Duration()); + + TemporalHelpers.assertPlainDate( + result, + 2000, 5, "M05", 2, + `"${arg}" is a valid UTC offset with time for PlainDate` + ); +} + +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.dateAdd(arg, new Temporal.Duration()), + `"${arg}" UTC offset without time is not valid for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-invalid.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-invalid.js new file mode 100644 index 0000000000..45608a1958 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-invalid.js @@ -0,0 +1,64 @@ +// |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.calendar.prototype.dateadd +description: > + RangeError thrown if an invalid ISO string (or syntactically valid ISO string + that is not supported) is used as a PlainDate +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + // invalid ISO strings: + "", + "invalid iso8601", + "2020-01-00", + "2020-01-32", + "2020-02-30", + "2021-02-29", + "2020-00-01", + "2020-13-01", + "2020-01-01T", + "2020-01-01T25:00:00", + "2020-01-01T01:60:00", + "2020-01-01T01:60:61", + "2020-01-01junk", + "2020-01-01T00:00:00junk", + "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-01", + "2020-001-01", + "2020-01-001", + "2020-01-01T001", + "2020-01-01T01:001", + "2020-01-01T01:01:001", + // valid, but forms not supported in Temporal: + "2020-W01-1", + "2020-001", + "+0002020-01-01", + // valid, but this calendar must not exist: + "2020-01-01[u-ca=notexist]", + // may be valid in other contexts, but insufficient information for PlainDate: + "2020-01", + "+002020-01", + "01-01", + "2020-W01", + "P1Y", + "-P12Y", + // valid, but outside the supported range: + "-999999-01-01", + "+999999-01-01", +]; +const instance = new Temporal.Calendar("iso8601"); +for (const arg of invalidStrings) { + assert.throws( + RangeError, + () => instance.dateAdd(arg, new Temporal.Duration()), + `"${arg}" should not be a valid ISO string for a PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-multiple-time-zone.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-multiple-time-zone.js new file mode 100644 index 0000000000..d2649f9af6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-multiple-time-zone.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.calendar.prototype.dateadd +description: More than one time zone annotation is not syntactical +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[UTC][UTC]", + "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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.dateAdd(arg, new Temporal.Duration()), + `reject more than one time zone annotation: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-time-separators.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-time-separators.js new file mode 100644 index 0000000000..3f2fe36d5c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/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.calendar.prototype.dateadd +description: Time separator in string argument can vary +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const tests = [ + ["2000-05-02T15:23", "uppercase T"], + ["2000-05-02t15:23", "lowercase T"], + ["2000-05-02 15:23", "space between date and time"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.dateAdd(arg, new Temporal.Duration()); + + TemporalHelpers.assertPlainDate( + result, + 2000, 5, "M05", 2, + `variant time separators (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-time-zone-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-time-zone-annotation.js new file mode 100644 index 0000000000..f83795073d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-time-zone-annotation.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.calendar.prototype.dateadd +description: Various forms of time zone annotation; critical flag has no effect +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const tests = [ + ["2000-05-02[Asia/Kolkata]", "named, with no time"], + ["2000-05-02[!Europe/Vienna]", "named, with ! and no time"], + ["2000-05-02[+00:00]", "numeric, with no time"], + ["2000-05-02[!-02:30]", "numeric, with ! and no time"], + ["2000-05-02T15:23[America/Sao_Paulo]", "named, with no offset"], + ["2000-05-02T15:23[!Asia/Tokyo]", "named, with ! and no offset"], + ["2000-05-02T15:23[-02:30]", "numeric, with no offset"], + ["2000-05-02T15:23[!+00:00]", "numeric, with ! and no offset"], + ["2000-05-02T15:23+00:00[America/New_York]", "named, with offset"], + ["2000-05-02T15:23+00:00[!UTC]", "named, with offset and !"], + ["2000-05-02T15:23+00:00[+01:00]", "numeric, with offset"], + ["2000-05-02T15:23+00:00[!-08:00]", "numeric, with offset and !"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.dateAdd(arg, new Temporal.Duration()); + + TemporalHelpers.assertPlainDate( + result, + 2000, 5, "M05", 2, + `time zone annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-unknown-annotation.js new file mode 100644 index 0000000000..e41220dafb --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-unknown-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.calendar.prototype.dateadd +description: Various forms of unknown annotation +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const tests = [ + ["2000-05-02[foo=bar]", "without time"], + ["2000-05-02T15:23[foo=bar]", "alone"], + ["2000-05-02T15:23[UTC][foo=bar]", "with time zone"], + ["2000-05-02T15:23[u-ca=iso8601][foo=bar]", "with calendar"], + ["2000-05-02T15:23[UTC][foo=bar][u-ca=iso8601]", "with time zone and calendar"], + ["2000-05-02T15:23[foo=bar][_foo-bar0=Ignore-This-999999999999]", "with another unknown annotation"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.dateAdd(arg, new Temporal.Duration()); + + TemporalHelpers.assertPlainDate( + result, + 2000, 5, "M05", 2, + `unknown annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-with-utc-designator.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-with-utc-designator.js new file mode 100644 index 0000000000..4568ed8772 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/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.calendar.prototype.dateadd +description: RangeError thrown if a string with UTC designator is used as a PlainDate +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "2019-10-01T09:00:00Z", + "2019-10-01T09:00:00Z[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.dateAdd(arg, new Temporal.Duration()), + "String with UTC designator should not be valid as a PlainDate" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-wrong-type.js new file mode 100644 index 0000000000..ca26f7a4ee --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/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.calendar.prototype.dateadd +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +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.dateAdd(arg, new Temporal.Duration()), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.dateAdd(arg, new Temporal.Duration()), `${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/Calendar/prototype/dateAdd/argument-zoneddatetime-convert.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-convert.js new file mode 100644 index 0000000000..16e9e0bd73 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-convert.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.calendar.prototype.dateadd +description: An exception from TimeZone#getOffsetNanosecondsFor() is propagated. +features: [Temporal] +---*/ + +class TZ extends Temporal.TimeZone { + constructor() { super("UTC") } + getOffsetNanosecondsFor() { throw new Test262Error() } +} + +const tz = new TZ(); +const arg = new Temporal.ZonedDateTime(0n, tz); +const instance = new Temporal.Calendar("iso8601"); + +assert.throws(Test262Error, () => instance.dateAdd(arg, new Temporal.Duration())); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-slots.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-slots.js new file mode 100644 index 0000000000..6f60798e04 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-slots.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.calendar.prototype.dateadd +description: Getters are not called when converting a ZonedDateTime to a PlainDate. +includes: [compareArray.js] +features: [Temporal] +---*/ + +const actual = []; +const prototypeDescrs = Object.getOwnPropertyDescriptors(Temporal.ZonedDateTime.prototype); +const getters = ["year", "month", "monthCode", "day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond", "calendar"]; + +for (const property of getters) { + Object.defineProperty(Temporal.ZonedDateTime.prototype, property, { + get() { + actual.push(`get ${property}`); + const value = prototypeDescrs[property].get.call(this); + return { + toString() { + actual.push(`toString ${property}`); + return value.toString(); + }, + valueOf() { + actual.push(`valueOf ${property}`); + return value; + }, + }; + }, + }); +} + +const arg = new Temporal.ZonedDateTime(0n, "UTC"); +const instance = new Temporal.Calendar("iso8601"); +instance.dateAdd(arg, new Temporal.Duration()); +assert.compareArray(actual, []); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js new file mode 100644 index 0000000000..fa2b479ed7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js @@ -0,0 +1,20 @@ +// |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.calendar.prototype.dateadd +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 calendar = new Temporal.Calendar("iso8601"); + const duration = new Temporal.Duration(1); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(RangeError, () => calendar.dateAdd(datetime, duration)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js new file mode 100644 index 0000000000..e4fe54c342 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.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.calendar.prototype.dateadd +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 calendar = new Temporal.Calendar("iso8601"); + const duration = new Temporal.Duration(1); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + timeZone.getOffsetNanosecondsFor = notCallable; + assert.throws( + TypeError, + () => calendar.dateAdd(datetime, duration), + `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js new file mode 100644 index 0000000000..179231b426 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js @@ -0,0 +1,20 @@ +// |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.calendar.prototype.dateadd +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 calendar = new Temporal.Calendar("iso8601"); + const duration = new Temporal.Duration(1); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(RangeError, () => calendar.dateAdd(datetime, duration)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js new file mode 100644 index 0000000000..9160e6ccee --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.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.calendar.prototype.dateadd +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 calendar = new Temporal.Calendar("iso8601"); + const duration = new Temporal.Duration(1); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(TypeError, () => calendar.dateAdd(datetime, duration)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/balance-smaller-units.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/balance-smaller-units.js new file mode 100644 index 0000000000..c385b3ffec --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/balance-smaller-units.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.calendar.prototype.dateadd +description: Durations with units smaller than days are balanced before adding +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = new Temporal.Calendar("iso8601"); +const date = new Temporal.PlainDate(2000, 5, 2, calendar); +const duration = new Temporal.Duration(0, 0, 0, 1, 24, 1440, 86400, 86400_000, 86400_000_000, 86400_000_000_000); + +const result = calendar.dateAdd(date, duration); +TemporalHelpers.assertPlainDate(result, 2000, 5, "M05", 9, "units smaller than days are balanced"); + +const resultString = calendar.dateAdd(date, "P1DT24H1440M86400S"); +TemporalHelpers.assertPlainDate(resultString, 2000, 5, "M05", 6, "units smaller than days are balanced"); + +const resultPropBag = calendar.dateAdd(date, { days: 1, hours: 24, minutes: 1440, seconds: 86400, milliseconds: 86400_000, microseconds: 86400_000_000, nanoseconds: 86400_000_000_000 }); +TemporalHelpers.assertPlainDate(resultPropBag, 2000, 5, "M05", 9, "units smaller than days are balanced"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/basic.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/basic.js new file mode 100644 index 0000000000..a14facd181 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/basic.js @@ -0,0 +1,53 @@ +// |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.calendar.prototype.dateadd +description: Basic tests for dateAdd(). +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const iso = Temporal.Calendar.from("iso8601"); +const date = Temporal.PlainDate.from("1994-11-06"); +const positiveDuration = Temporal.Duration.from({ months: 1, weeks: 1 }); +const negativeDuration = Temporal.Duration.from({ months: -1, weeks: -1 }); + +TemporalHelpers.assertPlainDate( + iso.dateAdd(Temporal.PlainDateTime.from("1994-11-06T08:15:30"), positiveDuration, {}), + 1994, 12, "M12", 13, "date: PlainDateTime"); + +TemporalHelpers.assertPlainDate( + iso.dateAdd({ year: 1994, month: 11, day: 6 }, positiveDuration, {}), + 1994, 12, "M12", 13, "date: property bag"); + +TemporalHelpers.assertPlainDate( + iso.dateAdd("1994-11-06", positiveDuration, {}), + 1994, 12, "M12", 13, "date: string"); + +assert.throws(TypeError, () => iso.dateAdd({ month: 11 }, positiveDuration, {}), "date: missing property"); + +TemporalHelpers.assertPlainDate( + iso.dateAdd(date, { months: 1, weeks: 1 }, {}), + 1994, 12, "M12", 13, "duration: property bag"); + +TemporalHelpers.assertPlainDate( + iso.dateAdd(date, "P1M1W", {}), + 1994, 12, "M12", 13, "duration: string"); + +assert.throws(TypeError, () => iso.dateAdd(date, { month: 1 }, {}), "duration: missing property"); + +TemporalHelpers.assertPlainDate( + iso.dateAdd(Temporal.PlainDateTime.from("1994-11-06T08:15:30"), negativeDuration, {}), + 1994, 9, "M09", 29, "date: PlainDateTime, negative duration"); + +TemporalHelpers.assertPlainDate( + iso.dateAdd({ year: 1994, month: 11, day: 6 }, negativeDuration, {}), + 1994, 9, "M09", 29, "date: property bag, negative duration"); + +TemporalHelpers.assertPlainDate( + iso.dateAdd("1994-11-06", negativeDuration, {}), + 1994, 9, "M09", 29, "date: string, negative duration"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/branding.js new file mode 100644 index 0000000000..646e2097aa --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/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.calendar.prototype.dateadd +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const dateAdd = Temporal.Calendar.prototype.dateAdd; + +assert.sameValue(typeof dateAdd, "function"); + +const args = [new Temporal.PlainDate(2000, 1, 1), new Temporal.Duration(1)]; + +assert.throws(TypeError, () => dateAdd.apply(undefined, args), "undefined"); +assert.throws(TypeError, () => dateAdd.apply(null, args), "null"); +assert.throws(TypeError, () => dateAdd.apply(true, args), "true"); +assert.throws(TypeError, () => dateAdd.apply("", args), "empty string"); +assert.throws(TypeError, () => dateAdd.apply(Symbol(), args), "symbol"); +assert.throws(TypeError, () => dateAdd.apply(1, args), "1"); +assert.throws(TypeError, () => dateAdd.apply({}, args), "plain object"); +assert.throws(TypeError, () => dateAdd.apply(Temporal.Calendar, args), "Temporal.Calendar"); +assert.throws(TypeError, () => dateAdd.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/builtin.js new file mode 100644 index 0000000000..c66f673ff7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/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.calendar.prototype.dateadd +description: > + Tests that Temporal.Calendar.prototype.dateAdd + 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.Calendar.prototype.dateAdd), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.dateAdd), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.dateAdd), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.Calendar.prototype.dateAdd.hasOwnProperty("prototype"), + false, "prototype property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/calendar-datefromfields-called-with-options-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/calendar-datefromfields-called-with-options-undefined.js new file mode 100644 index 0000000000..247a945284 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/calendar-datefromfields-called-with-options-undefined.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.calendar.prototype.dateadd +description: > + Calendar.dateFromFields method is called with undefined as the options value + when call originates internally +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = TemporalHelpers.calendarFromFieldsUndefinedOptions(); +calendar.dateAdd({ year: 2000, month: 5, day: 2, calendar }, new Temporal.Duration(1)); +assert.sameValue(calendar.dateFromFieldsCallCount, 1); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/calendar-fields-iterable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/calendar-fields-iterable.js new file mode 100644 index 0000000000..b297cd7bc3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/calendar-fields-iterable.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.calendar.prototype.dateadd +description: Verify the result of calendar.fields() is treated correctly. +info: | + sec-temporal.calendar.prototype.dateadd step 4: + 4. Set _date_ to ? ToTemporalDate(_date_). + sec-temporal-totemporaldate step 2.c: + c. Let _fieldNames_ be ? CalendarFields(_calendar_, « *"day"*, *"month"*, *"monthCode"*, *"year"* »). + sec-temporal-calendarfields step 4: + 4. Let _result_ be ? IterableToListOfType(_fieldsArray_, « String »). +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + "day", + "month", + "monthCode", + "year", +]; + +const duration = new Temporal.Duration(0, 1); +const calendar1 = TemporalHelpers.calendarFieldsIterable(); +const calendar2 = TemporalHelpers.calendarFieldsIterable(); +calendar1.dateAdd({ year: 2000, month: 5, day: 2, calendar: calendar2 }, duration); + +assert.sameValue(calendar1.fieldsCallCount, 0, "fields() method not called"); +assert.sameValue(calendar2.fieldsCallCount, 1, "fields() method called once"); +assert.compareArray(calendar2.fieldsCalledWith[0], expected, "fields() method called with correct args"); +assert(calendar2.iteratorExhausted[0], "iterated through the whole iterable"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/calendar-temporal-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/calendar-temporal-object.js new file mode 100644 index 0000000000..6e5e719a37 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/calendar-temporal-object.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.calendar.prototype.dateadd +description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots +info: | + sec-temporal.calendar.prototype.dateadd step 4: + 4. Set _date_ to ? ToTemporalDate(_date_). + sec-temporal-totemporaldate 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 calendar = new Temporal.Calendar("iso8601"); + const duration = new Temporal.Duration(0, 1); + calendar.dateAdd({ year: 2000, month: 5, day: 2, calendar: temporalObject }, duration); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/date-infinity-throws-rangeerror.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/date-infinity-throws-rangeerror.js new file mode 100644 index 0000000000..e0ba54edfb --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/date-infinity-throws-rangeerror.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. + +/*--- +description: Throws if any value in the property bag is Infinity or -Infinity +esid: sec-temporal.calendar.prototype.dateadd +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); +const duration = new Temporal.Duration(1); +const base = { year: 2000, month: 5, day: 2 }; + +[Infinity, -Infinity].forEach((inf) => { + ["year", "month", "day"].forEach((prop) => { + ["constrain", "reject"].forEach((overflow) => { + assert.throws(RangeError, () => instance.dateAdd({ ...base, [prop]: inf }, duration, { overflow }), `${prop} property cannot be ${inf} (overflow ${overflow}`); + + const calls = []; + const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop); + assert.throws(RangeError, () => instance.dateAdd({ ...base, [prop]: obj }, duration, { overflow })); + 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/Calendar/prototype/dateAdd/duration-argument-string-negative-fractional-units.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/duration-argument-string-negative-fractional-units.js new file mode 100644 index 0000000000..ee5bafa63f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/duration-argument-string-negative-fractional-units.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.calendar.prototype.dateadd +description: Strings with fractional duration units are treated with the correct sign +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = new Temporal.Calendar("iso8601"); +const instance = new Temporal.PlainDate(2000, 5, 2, calendar); + +const resultHours = calendar.dateAdd(instance, "-PT24.567890123H"); +TemporalHelpers.assertPlainDate(resultHours, 2000, 5, "M05", 1, "negative fractional hours"); + +const resultMinutes = calendar.dateAdd(instance, "-PT1440.567890123M"); +TemporalHelpers.assertPlainDate(resultMinutes, 2000, 5, "M05", 1, "negative fractional minutes"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/length.js new file mode 100644 index 0000000000..740d54d9ea --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/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.calendar.prototype.dateadd +description: Temporal.Calendar.prototype.dateAdd.length is 2 +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.Calendar.prototype.dateAdd, "length", { + value: 2, + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/name.js new file mode 100644 index 0000000000..13dfde8302 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/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.calendar.prototype.dateadd +description: Temporal.Calendar.prototype.dateAdd.name is "dateAdd". +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.Calendar.prototype.dateAdd, "name", { + value: "dateAdd", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/not-a-constructor.js new file mode 100644 index 0000000000..772be400ba --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/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.calendar.prototype.dateadd +description: > + Temporal.Calendar.prototype.dateAdd 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.Calendar.prototype.dateAdd(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.Calendar.prototype.dateAdd), false, + "isConstructor(Temporal.Calendar.prototype.dateAdd)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/options-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/options-object.js new file mode 100644 index 0000000000..1f3ea23b54 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/options-object.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.calendar.prototype.dateadd +description: Empty or a function object may be used as options +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const result1 = instance.dateAdd(new Temporal.PlainDate(1976, 11, 18), new Temporal.Duration(1), {}); +TemporalHelpers.assertPlainDate( + result1, 1977, 11, "M11", 18, + "options may be an empty plain object" +); + +const result2 = instance.dateAdd(new Temporal.PlainDate(1976, 11, 18), new Temporal.Duration(1), () => {}); +TemporalHelpers.assertPlainDate( + result2, 1977, 11, "M11", 18, + "options may be a function object" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/options-wrong-type.js new file mode 100644 index 0000000000..f0e3bec30a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/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.calendar.prototype.dateadd +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.Calendar("iso8601"); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.dateAdd(new Temporal.PlainDate(1976, 11, 18), new Temporal.Duration(1), value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/order-of-operations.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/order-of-operations.js new file mode 100644 index 0000000000..a0bfde1cf4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/order-of-operations.js @@ -0,0 +1,101 @@ +// |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.calendar.prototype.dateadd +description: Properties on an object passed to dateAdd() are accessed in the correct order +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + // ToTemporalDate → GetTemporalCalendarWithISODefault + "get date.calendar", + "has date.calendar.calendar", + // ToTemporalDate → CalendarFields + "get date.calendar.fields", + "call date.calendar.fields", + // ToTemporalDate → PrepareTemporalFields + "get date.day", + "get date.day.valueOf", + "call date.day.valueOf", + "get date.month", + "get date.month.valueOf", + "call date.month.valueOf", + "get date.monthCode", + "get date.monthCode.toString", + "call date.monthCode.toString", + "get date.year", + "get date.year.valueOf", + "call date.year.valueOf", + // ToTemporalDate → CalendarDateFromFields + "get date.calendar.dateFromFields", + "call date.calendar.dateFromFields", + // ToTemporalDuration + "get duration.days", + "get duration.days.valueOf", + "call duration.days.valueOf", + "get duration.hours", + "get duration.hours.valueOf", + "call duration.hours.valueOf", + "get duration.microseconds", + "get duration.microseconds.valueOf", + "call duration.microseconds.valueOf", + "get duration.milliseconds", + "get duration.milliseconds.valueOf", + "call duration.milliseconds.valueOf", + "get duration.minutes", + "get duration.minutes.valueOf", + "call duration.minutes.valueOf", + "get duration.months", + "get duration.months.valueOf", + "call duration.months.valueOf", + "get duration.nanoseconds", + "get duration.nanoseconds.valueOf", + "call duration.nanoseconds.valueOf", + "get duration.seconds", + "get duration.seconds.valueOf", + "call duration.seconds.valueOf", + "get duration.weeks", + "get duration.weeks.valueOf", + "call duration.weeks.valueOf", + "get duration.years", + "get duration.years.valueOf", + "call duration.years.valueOf", + // ToTemporalOverflow + "get options.overflow", + "get options.overflow.toString", + "call options.overflow.toString", +]; +const actual = []; + +const instance = new Temporal.Calendar("iso8601"); + +const date = TemporalHelpers.propertyBagObserver(actual, { + year: 2000, + month: 5, + monthCode: "M05", + day: 2, + calendar: TemporalHelpers.calendarObserver(actual, "date.calendar"), +}, "date"); + +const duration = TemporalHelpers.propertyBagObserver(actual, { + years: 1, + months: 2, + weeks: 3, + days: 4, + hours: 5, + minutes: 6, + seconds: 7, + milliseconds: 8, + microseconds: 9, + nanoseconds: 10, +}, "duration"); + +const options = TemporalHelpers.propertyBagObserver(actual, { overflow: "constrain" }, "options"); + +instance.dateAdd(date, duration, options); +assert.compareArray(actual, expected, "order of operations"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/overflow-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/overflow-invalid-string.js new file mode 100644 index 0000000000..d0e1c402d0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/overflow-invalid-string.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.calendar.prototype.dateadd +description: RangeError thrown when overflow 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-totemporaloverflow step 1: + 1. Return ? GetOption(_normalizedOptions_, *"overflow"*, « String », « *"constrain"*, *"reject"* », *"constrain"*). + sec-temporal.calendar.prototype.dateadd step 7: + 7. Let _overflow_ be ? ToTemporalOverflow(_options_). +features: [Temporal, arrow-function] +---*/ + +const calendar = new Temporal.Calendar("iso8601"); +const date = new Temporal.PlainDate(2000, 5, 2, calendar); +const duration = new Temporal.Duration(3, 3, 0, 3); +const badOverflows = ["", "CONSTRAIN", "balance", "other string", "constra\u0131n", "reject\0"]; +for (const overflow of badOverflows) { + assert.throws( + RangeError, + () => calendar.dateAdd(date, duration, { overflow }), + `invalid overflow ("${overflow}")` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/overflow-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/overflow-undefined.js new file mode 100644 index 0000000000..12e0527f7f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/overflow-undefined.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.calendar.prototype.dateadd +description: Fallback value for overflow option +info: | + sec-getoption step 3: + 3. If _value_ is *undefined*, return _fallback_. + sec-temporal-totemporaloverflow step 1: + 1. Return ? GetOption(_normalizedOptions_, *"overflow"*, « String », « *"constrain"*, *"reject"* », *"constrain"*). + sec-temporal.calendar.prototype.dateadd step 7: + 7. Let _overflow_ be ? ToTemporalOverflow(_options_). +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = new Temporal.Calendar("iso8601"); +const date = new Temporal.PlainDate(2000, 5, 31, calendar); +const duration = new Temporal.Duration(3, 1); + +const explicit = calendar.dateAdd(date, duration, { overflow: undefined }); +TemporalHelpers.assertPlainDate(explicit, 2003, 6, "M06", 30, "default overflow is constrain"); +const implicit = calendar.dateAdd(date, duration, {}); +TemporalHelpers.assertPlainDate(implicit, 2003, 6, "M06", 30, "default overflow is constrain"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/overflow-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/overflow-wrong-type.js new file mode 100644 index 0000000000..70768ce7b2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/overflow-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.calendar.prototype.dateadd +description: Type conversions for overflow option +info: | + sec-getoption step 9.a: + a. Set _value_ to ? ToString(_value_). + sec-temporal-totemporaloverflow step 1: + 1. Return ? GetOption(_normalizedOptions_, *"overflow"*, « String », « *"constrain"*, *"reject"* », *"constrain"*). + sec-temporal.calendar.prototype.dateadd step 7: + 7. Let _overflow_ be ? ToTemporalOverflow(_options_). +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = new Temporal.Calendar("iso8601"); +const date = new Temporal.PlainDate(2000, 5, 2, calendar); +const duration = new Temporal.Duration(3, 3, 0, 3); +TemporalHelpers.checkStringOptionWrongType("overflow", "constrain", + (overflow) => calendar.dateAdd(date, duration, { overflow }), + (result, descr) => TemporalHelpers.assertPlainDate(result, 2003, 8, "M08", 5, descr), +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/prop-desc.js new file mode 100644 index 0000000000..069b289a47 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/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.calendar.prototype.dateadd +description: The "dateAdd" property of Temporal.Calendar.prototype +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.Calendar.prototype.dateAdd, + "function", + "`typeof Calendar.prototype.dateAdd` is `function`" +); + +verifyProperty(Temporal.Calendar.prototype, "dateAdd", { + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/shell.js new file mode 100644 index 0000000000..eda1477282 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/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/Calendar/prototype/dateAdd/throw-range-error-from-ToTemporalDate.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/throw-range-error-from-ToTemporalDate.js new file mode 100644 index 0000000000..7c492d5cae --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/throw-range-error-from-ToTemporalDate.js @@ -0,0 +1,19 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dateadd +description: Temporal.Calendar.prototype.dateAdd should throw from ToTemporalDate. +info: | + ... + 4. Set date to ? ToTemporalDate(date). +features: [Temporal, arrow-function] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +assert.throws(RangeError, + () => cal.dateAdd("invalid date string", new Temporal.Duration(1)), + 'cal.dateAdd("invalid date string", new Temporal.Duration(1)) throws a RangeError exception'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/throw-range-error-from-ToTemporalDuration.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/throw-range-error-from-ToTemporalDuration.js new file mode 100644 index 0000000000..ed2e4df80f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/throw-range-error-from-ToTemporalDuration.js @@ -0,0 +1,19 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dateadd +description: Temporal.Calendar.prototype.dateAdd should throw from ToTemporalDuration. +info: | + ... + 5. Set duration to ? ToTemporalDuration(duration). +features: [Temporal, arrow-function] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +assert.throws(RangeError, + () => cal.dateAdd("2020-02-03", "invalid duration string"), + 'cal.dateAdd("2020-02-03", "invalid duration string") throws a RangeError exception'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/throw-type-error-from-GetOptionsObject.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/throw-type-error-from-GetOptionsObject.js new file mode 100644 index 0000000000..5f7821d9eb --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/throw-type-error-from-GetOptionsObject.js @@ -0,0 +1,23 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-temporal.calendar.prototype.dateadd +description: Temporal.Calendar.prototype.dateAdd should throw from GetOptionsObject. +info: | + ... + 6. Set options to ? GetOptionsObject(options). +features: [BigInt, Symbol, Temporal, arrow-function] +---*/ +let cal = new Temporal.Calendar('iso8601'); +let invalidOptionsList = [null, 'invalid option', 234, 23n, Symbol('foo'), true, false, Infinity]; + +invalidOptionsList.forEach(function(invalidOptions) { + assert.throws( + TypeError, + () => cal.dateAdd('2020-02-03', 'P1Y', invalidOptions), + 'cal.dateAdd("2020-02-03", "P1Y", invalidOptions) throws a TypeError exception' + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/year-zero.js new file mode 100644 index 0000000000..ebf9ac31bb --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/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.calendar.prototype.dateadd +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.dateAdd(arg, new Temporal.Duration()), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/branding.js new file mode 100644 index 0000000000..1e9bb1ee55 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/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.calendar.prototype.datefromfields +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const dateFromFields = Temporal.Calendar.prototype.dateFromFields; + +assert.sameValue(typeof dateFromFields, "function"); + +const args = [{ year: 2000, month: 1, day: 1 }]; + +assert.throws(TypeError, () => dateFromFields.apply(undefined, args), "undefined"); +assert.throws(TypeError, () => dateFromFields.apply(null, args), "null"); +assert.throws(TypeError, () => dateFromFields.apply(true, args), "true"); +assert.throws(TypeError, () => dateFromFields.apply("", args), "empty string"); +assert.throws(TypeError, () => dateFromFields.apply(Symbol(), args), "symbol"); +assert.throws(TypeError, () => dateFromFields.apply(1, args), "1"); +assert.throws(TypeError, () => dateFromFields.apply({}, args), "plain object"); +assert.throws(TypeError, () => dateFromFields.apply(Temporal.Calendar, args), "Temporal.Calendar"); +assert.throws(TypeError, () => dateFromFields.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/builtin.js new file mode 100644 index 0000000000..738e7514c1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/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.calendar.prototype.datefromfields +description: > + Tests that Temporal.Calendar.prototype.dateFromFields + 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.Calendar.prototype.dateFromFields), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.dateFromFields), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.dateFromFields), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.Calendar.prototype.dateFromFields.hasOwnProperty("prototype"), + false, "prototype property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/fields-not-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/fields-not-object.js new file mode 100644 index 0000000000..83c1a5101c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/fields-not-object.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.calendar.prototype.datefromfields +description: Throw a TypeError if the fields is not an object +info: | + 4. If Type(_fields_) is not Object, throw a *TypeError* exception. +features: [BigInt, Symbol, Temporal, arrow-function] +---*/ + +const tests = [undefined, null, true, false, "string", Symbol("sym"), Infinity, NaN, Math.PI, 42n]; +const iso = Temporal.Calendar.from("iso8601"); +for (const fields of tests) { + assert.throws( + TypeError, + () => iso.dateFromFields(fields, {}) + `dateFromFields(${typeof fields}) throws a TypeError exception` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/infinity-throws-rangeerror.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/infinity-throws-rangeerror.js new file mode 100644 index 0000000000..25e25c975c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/infinity-throws-rangeerror.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. + +/*--- +description: Throws if any value in the property bag is Infinity or -Infinity +esid: sec-temporal.calendar.prototype.datefromfields +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); +const base = { year: 2000, month: 5, day: 2 }; + +[Infinity, -Infinity].forEach((inf) => { + ["year", "month", "day"].forEach((prop) => { + ["constrain", "reject"].forEach((overflow) => { + assert.throws(RangeError, () => instance.dateFromFields({ ...base, [prop]: inf }, { overflow }), `${prop} property cannot be ${inf} (overflow ${overflow}`); + + const calls = []; + const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop); + assert.throws(RangeError, () => instance.dateFromFields({ ...base, [prop]: obj }, { overflow })); + 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/Calendar/prototype/dateFromFields/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/length.js new file mode 100644 index 0000000000..5673a5497a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/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.calendar.prototype.datefromfields +description: Temporal.Calendar.prototype.dateFromFields.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.Calendar.prototype.dateFromFields, "length", { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/missing-properties.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/missing-properties.js new file mode 100644 index 0000000000..2dad014e42 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/missing-properties.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.calendar.prototype.datefromfields +description: Errors due to missing properties on fields object are thrown in the correct order +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const missingDay = { + get year() { + TemporalHelpers.assertUnreachable("day should be checked first"); + }, + get month() { + TemporalHelpers.assertUnreachable("day should be checked first"); + }, + get monthCode() { + TemporalHelpers.assertUnreachable("day should be checked first"); + }, +}; +assert.throws(TypeError, () => instance.dateFromFields(missingDay), "day should be checked before year and month"); + +let getMonth = false; +let getMonthCode = false; +const missingYearAndMonth = { + day: 1, + get month() { + getMonth = true; + }, + get monthCode() { + getMonthCode = true; + }, +}; +assert.throws(TypeError, () => instance.dateFromFields(missingYearAndMonth), "year should be checked after fetching but before resolving the month"); +assert(getMonth, "year is fetched after month"); +assert(getMonthCode, "year is fetched after monthCode"); + +const missingMonth = { + day: 1, + year: 2000, +}; +assert.throws(TypeError, () => instance.dateFromFields(missingMonth), "month should be resolved last"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/name.js new file mode 100644 index 0000000000..e01fa64920 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/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.calendar.prototype.datefromfields +description: Temporal.Calendar.prototype.dateFromFields.name is "dateFromFields". +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.Calendar.prototype.dateFromFields, "name", { + value: "dateFromFields", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/not-a-constructor.js new file mode 100644 index 0000000000..4534e69625 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/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.calendar.prototype.datefromfields +description: > + Temporal.Calendar.prototype.dateFromFields 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.Calendar.prototype.dateFromFields(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.Calendar.prototype.dateFromFields), false, + "isConstructor(Temporal.Calendar.prototype.dateFromFields)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/one-of-era-erayear-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/one-of-era-erayear-undefined.js new file mode 100644 index 0000000000..0bef3d531e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/one-of-era-erayear-undefined.js @@ -0,0 +1,19 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.datefromfields +description: Does not throw a RangeError if only one of era/eraYear fields is present +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const base = { year: 2000, month: 5, day: 2, era: 'ce' }; +const instance = new Temporal.Calendar('iso8601'); +TemporalHelpers.assertPlainDate(instance.dateFromFields({ ...base }), 2000, 5, 'M05', 2); + +const base2 = { year: 2000, month: 5, day: 2, eraYear: 1 }; +TemporalHelpers.assertPlainDate(instance.dateFromFields({ ...base }), 2000, 5, 'M05', 2); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/options-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/options-object.js new file mode 100644 index 0000000000..1e7929b2c6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/options-object.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.calendar.prototype.datefromfields +description: Empty or a function object may be used as options +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const result1 = instance.dateFromFields({ year: 1976, month: 11, day: 18 }, {}); +TemporalHelpers.assertPlainDate( + result1, 1976, 11, "M11", 18, + "options may be an empty plain object" +); + +const result2 = instance.dateFromFields({ year: 1976, month: 11, day: 18 }, () => {}); +TemporalHelpers.assertPlainDate( + result2, 1976, 11, "M11", 18, + "options may be a function object" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/options-wrong-type.js new file mode 100644 index 0000000000..1595039a4f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/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.calendar.prototype.datefromfields +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.Calendar("iso8601"); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.dateFromFields({ year: 1976, month: 11, day: 18 }, value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/order-of-operations.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/order-of-operations.js new file mode 100644 index 0000000000..93805f5225 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/order-of-operations.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.calendar.prototype.datefromfields +description: Properties on objects passed to dateFromFields() are accessed in the correct order +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + "get fields.day", + "get fields.day.valueOf", + "call fields.day.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.year", + "get fields.year.valueOf", + "call fields.year.valueOf", + "get options.overflow", + "get options.overflow.toString", + "call options.overflow.toString", +]; +const actual = []; + +const instance = new Temporal.Calendar("iso8601"); + +const fields = TemporalHelpers.propertyBagObserver(actual, { + year: 1.7, + month: 1.7, + monthCode: "M01", + day: 1.7, +}, "fields"); + +const options = TemporalHelpers.propertyBagObserver(actual, { + overflow: "reject", +}, "options"); + +const result = instance.dateFromFields(fields, options); +TemporalHelpers.assertPlainDate(result, 1, 1, "M01", 1, "date result"); +assert.sameValue(result.calendar, instance, "calendar result"); +assert.compareArray(actual, expected, "order of operations"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/overflow-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/overflow-invalid-string.js new file mode 100644 index 0000000000..833eb43900 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/overflow-invalid-string.js @@ -0,0 +1,31 @@ +// |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.calendar.prototype.datefromfields +description: RangeError thrown when overflow 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-totemporaloverflow step 1: + 1. Return ? GetOption(_normalizedOptions_, *"overflow"*, « String », « *"constrain"*, *"reject"* », *"constrain"*). + sec-temporal-isodatefromfields step 2: + 2. Let _overflow_ be ? ToTemporalOverflow(_options_). + sec-temporal.calendar.prototype.datefromfields step 6: + 6. Let _result_ be ? ISODateFromFields(_fields_, _options_). +features: [Temporal, arrow-function] +---*/ + +const calendar = new Temporal.Calendar("iso8601"); +const badOverflows = ["", "CONSTRAIN", "balance", "other string", "constra\u0131n", "reject\0"]; +for (const overflow of badOverflows) { + assert.throws( + RangeError, + () => calendar.dateFromFields({ year: 2000, month: 5, day: 2 }, + { overflow }), + `invalid overflow ("${overflow}")` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/overflow-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/overflow-undefined.js new file mode 100644 index 0000000000..eb82e945e5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/overflow-undefined.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.calendar.prototype.datefromfields +description: Fallback value for overflow option +info: | + sec-getoption step 3: + 3. If _value_ is *undefined*, return _fallback_. + sec-temporal-totemporaloverflow step 1: + 1. Return ? GetOption(_normalizedOptions_, *"overflow"*, « String », « *"constrain"*, *"reject"* », *"constrain"*). + sec-temporal-isodatefromfields step 2: + 2. Let _overflow_ be ? ToTemporalOverflow(_options_). + sec-temporal.calendar.prototype.datefromfields step 6: + 6. Let _result_ be ? ISODateFromFields(_fields_, _options_). +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = new Temporal.Calendar("iso8601"); + +const explicit = calendar.dateFromFields({ year: 2000, month: 15, day: 2 }, { overflow: undefined }); +TemporalHelpers.assertPlainDate(explicit, 2000, 12, "M12", 2, "default overflow is constrain"); +const implicit = calendar.dateFromFields({ year: 2000, month: 15, day: 2 }, {}); +TemporalHelpers.assertPlainDate(implicit, 2000, 12, "M12", 2, "default overflow is constrain"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/overflow-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/overflow-wrong-type.js new file mode 100644 index 0000000000..0196a3cbce --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/overflow-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.calendar.prototype.datefromfields +description: Type conversions for overflow option +info: | + sec-getoption step 9.a: + a. Set _value_ to ? ToString(_value_). + sec-temporal-totemporaloverflow step 1: + 1. Return ? GetOption(_normalizedOptions_, *"overflow"*, « String », « *"constrain"*, *"reject"* », *"constrain"*). + sec-temporal-isodatefromfields step 2: + 2. Let _overflow_ be ? ToTemporalOverflow(_options_). + sec-temporal.calendar.prototype.datefromfields step 6: + 6. Let _result_ be ? ISODateFromFields(_fields_, _options_). +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = new Temporal.Calendar("iso8601"); +TemporalHelpers.checkStringOptionWrongType("overflow", "constrain", + (overflow) => calendar.dateFromFields({ year: 2000, month: 5, day: 2 }, { overflow }), + (result, descr) => TemporalHelpers.assertPlainDate(result, 2000, 5, "M05", 2, descr), +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/prop-desc.js new file mode 100644 index 0000000000..3b0e9b803c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/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.calendar.prototype.datefromfields +description: The "dateFromFields" property of Temporal.Calendar.prototype +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.Calendar.prototype.dateFromFields, + "function", + "`typeof Calendar.prototype.dateFromFields` is `function`" +); + +verifyProperty(Temporal.Calendar.prototype, "dateFromFields", { + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/shell.js new file mode 100644 index 0000000000..eda1477282 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/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/Calendar/prototype/dateFromFields/throw-type-error-from-GetOptionsObject.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/throw-type-error-from-GetOptionsObject.js new file mode 100644 index 0000000000..cd6bf22a04 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/throw-type-error-from-GetOptionsObject.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-temporal.calendar.prototype.datefromfields +description: Temporal.Calendar.prototype.dateFromFields should throw TypeError from GetOptionsObject. +info: | + 4. If Type(fields) is not Object, throw a TypeError exception. +features: [BigInt, Symbol, Temporal, arrow-function] +---*/ +let cal = new Temporal.Calendar('iso8601'); + +let fields = { + year: 2021, + month: 7, + day: 20 +}; + +let notObjectList = [null, 'string', Symbol('efg'), true, false, Infinity, NaN, 123, 456n]; + +notObjectList.forEach(function(options) { + assert.throws( + TypeError, + () => cal.dateFromFields(fields, options), + 'cal.dateFromFields(fields, options) throws a TypeError exception' + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/throws-range-error.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/throws-range-error.js new file mode 100644 index 0000000000..1aae50a41e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/throws-range-error.js @@ -0,0 +1,126 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-temporal.calendar.prototype.datefromfields +description: > + Temporal.Calendar.prototype.dateFromFields should throw RangeError for + input not in valid range. +info: | + 1. Let calendar be the this value. + 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]). + 3. Assert: calendar.[[Identifier]] is "iso8601". + 4. If Type(fields) is not Object, throw a TypeError exception. + 5. Set options to ? GetOptionsObject(options). + 6. Let result be ? ISODateFromFields(fields, options). + 7. Return ? CreateTemporalDate(result.[[Year]], result.[[Month]], result.[[Day]], calendar). +features: [Temporal, arrow-function] +---*/ +let cal = new Temporal.Calendar("iso8601") + +assert.throws(RangeError, () => cal.dateFromFields({year: 2021, monthCode: "m1", day: 17}), + 'cal.dateFromFields({year: 2021, monthCode: "m1", day: 17}) throws a RangeError exception'); +assert.throws(RangeError, () => cal.dateFromFields({year: 2021, monthCode: "M1", day: 17}), + 'cal.dateFromFields({year: 2021, monthCode: "M1", day: 17}) throws a RangeError exception'); +assert.throws(RangeError, () => cal.dateFromFields({year: 2021, monthCode: "m01", day: 17}), + 'cal.dateFromFields({year: 2021, monthCode: "m01", day: 17}) throws a RangeError exception'); + +assert.throws(RangeError, () => cal.dateFromFields({year: 2021, month: 12, monthCode: "M11", day: 17}), + 'cal.dateFromFields({year: 2021, month: 12, monthCode: "M11", day: 17}) throws a RangeError exception'); +assert.throws(RangeError, () => cal.dateFromFields({year: 2021, monthCode: "M00", day: 17}), + 'cal.dateFromFields({year: 2021, monthCode: "M00", day: 17}) throws a RangeError exception'); +assert.throws(RangeError, () => cal.dateFromFields({year: 2021, monthCode: "M19", day: 17}), + 'cal.dateFromFields({year: 2021, monthCode: "M19", day: 17}) throws a RangeError exception'); +assert.throws(RangeError, () => cal.dateFromFields({year: 2021, monthCode: "M99", day: 17}), + 'cal.dateFromFields({year: 2021, monthCode: "M99", day: 17}) throws a RangeError exception'); +assert.throws(RangeError, () => cal.dateFromFields({year: 2021, monthCode: "M13", day: 17}), + 'cal.dateFromFields({year: 2021, monthCode: "M13", day: 17}) throws a RangeError exception'); + +assert.throws(RangeError, () => cal.dateFromFields({year: 2021, month: -1, day: 17}), + 'cal.dateFromFields({year: 2021, month: -1, day: 17}) throws a RangeError exception'); +assert.throws(RangeError, () => cal.dateFromFields({year: 2021, month: -Infinity, day: 17}), + 'cal.dateFromFields({year: 2021, month: -Infinity, day: 17}) throws a RangeError exception'); +assert.throws(RangeError, () => cal.dateFromFields({year: 2021, month: 7, day: -17}), + 'cal.dateFromFields({year: 2021, month: 7, day: -17}) throws a RangeError exception'); +assert.throws(RangeError, () => cal.dateFromFields({year: 2021, month: 7, day: -Infinity}), + 'cal.dateFromFields({year: 2021, month: 7, day: -Infinity}) throws a RangeError exception'); + +assert.throws(RangeError, () => cal.dateFromFields({year: 2021, month: 12, day: 0}, {overflow: "reject"}), + 'cal.dateFromFields({year: 2021, month: 12, day: 0}, {overflow: "reject"}) throws a RangeError exception'); +assert.throws(RangeError, () => cal.dateFromFields({year: 2021, month: 12, day: 32}, {overflow: "reject"}), + 'cal.dateFromFields({year: 2021, month: 12, day: 32}, {overflow: "reject"}) throws a RangeError exception'); +assert.throws(RangeError, () => cal.dateFromFields({year: 2021, month: 1, day: 32}, {overflow: "reject"}), + 'cal.dateFromFields({year: 2021, month: 1, day: 32}, {overflow: "reject"}) throws a RangeError exception'); +assert.throws(RangeError, () => cal.dateFromFields({year: 2021, month: 2, day: 29}, {overflow: "reject"}), + 'cal.dateFromFields({year: 2021, month: 2, day: 29}, {overflow: "reject"}) throws a RangeError exception'); +assert.throws(RangeError, () => cal.dateFromFields({year: 2021, month: 6, day: 31}, {overflow: "reject"}), + 'cal.dateFromFields({year: 2021, month: 6, day: 31}, {overflow: "reject"}) throws a RangeError exception'); +assert.throws(RangeError, () => cal.dateFromFields({year: 2021, month: 9, day: 31}, {overflow: "reject"}), + 'cal.dateFromFields({year: 2021, month: 9, day: 31}, {overflow: "reject"}) throws a RangeError exception'); +assert.throws(RangeError, () => cal.dateFromFields({year: 2021, month: 0, day: 5}, {overflow: "reject"}), + 'cal.dateFromFields({year: 2021, month: 0, day: 5}, {overflow: "reject"}) throws a RangeError exception'); +assert.throws(RangeError, () => cal.dateFromFields({year: 2021, month: 13, day: 5}, {overflow: "reject"}), + 'cal.dateFromFields({year: 2021, month: 13, day: 5}, {overflow: "reject"}) throws a RangeError exception'); + +assert.throws(RangeError, () => cal.dateFromFields( + {year: 2021, monthCode: "M12", day: 0}, {overflow: "reject"}), + 'cal.dateFromFields( {year: 2021, monthCode: "M12", day: 0}, {overflow: "reject"}) throws a RangeError exception'); +assert.throws(RangeError, () => cal.dateFromFields( + {year: 2021, monthCode: "M12", day: 32}, {overflow: "reject"}), + 'cal.dateFromFields( {year: 2021, monthCode: "M12", day: 32}, {overflow: "reject"}) throws a RangeError exception'); +assert.throws(RangeError, () => cal.dateFromFields( + {year: 2021, monthCode: "M01", day: 32}, {overflow: "reject"}), + 'cal.dateFromFields( {year: 2021, monthCode: "M01", day: 32}, {overflow: "reject"}) throws a RangeError exception'); +assert.throws(RangeError, () => cal.dateFromFields( + {year: 2021, monthCode: "M02", day: 29}, {overflow: "reject"}), + 'cal.dateFromFields( {year: 2021, monthCode: "M02", day: 29}, {overflow: "reject"}) throws a RangeError exception'); +assert.throws(RangeError, () => cal.dateFromFields( + {year: 2021, monthCode: "M06", day: 31}, {overflow: "reject"}), + 'cal.dateFromFields( {year: 2021, monthCode: "M06", day: 31}, {overflow: "reject"}) throws a RangeError exception'); +assert.throws(RangeError, () => cal.dateFromFields( + {year: 2021, monthCode: "M09", day: 31}, {overflow: "reject"}), + 'cal.dateFromFields( {year: 2021, monthCode: "M09", day: 31}, {overflow: "reject"}) throws a RangeError exception'); +assert.throws(RangeError, () => cal.dateFromFields( + {year: 2021, monthCode: "M00", day: 5}, {overflow: "reject"}), + 'cal.dateFromFields( {year: 2021, monthCode: "M00", day: 5}, {overflow: "reject"}) throws a RangeError exception'); +assert.throws(RangeError, () => cal.dateFromFields( + {year: 2021, monthCode: "M13", day: 5}, {overflow: "reject"}), + 'cal.dateFromFields( {year: 2021, monthCode: "M13", day: 5}, {overflow: "reject"}) throws a RangeError exception'); + +assert.throws(RangeError, () => cal.dateFromFields( + {year: 2021, month: 12, day: 0}), 'cal.dateFromFields( {year: 2021, month: 12, day: 0}) throws a RangeError exception'); +assert.throws(RangeError, () => cal.dateFromFields( + {year: 2021, month: 0, day: 3}), 'cal.dateFromFields( {year: 2021, month: 0, day: 3}) throws a RangeError exception'); + +// Check throw for the second arg +assert.throws(RangeError, () => cal.dateFromFields( + {year: 2021, month: 7, day: 13}, {overflow: "invalid"}), 'cal.dateFromFields( {year: 2021, month: 7, day: 13}, {overflow: "invalid"}) throws a RangeError exception'); + +assert.throws(RangeError, () => cal.dateFromFields( + {year: 2021, month: 1, day: 32}, {overflow: "reject"}), 'cal.dateFromFields( {year: 2021, month: 1, day: 32}, {overflow: "reject"}) throws a RangeError exception'); +assert.throws(RangeError, () => cal.dateFromFields( + {year: 2021, month: 2, day: 29}, {overflow: "reject"}), 'cal.dateFromFields( {year: 2021, month: 2, day: 29}, {overflow: "reject"}) throws a RangeError exception'); +assert.throws(RangeError, () => cal.dateFromFields( + {year: 2021, month: 3, day: 32}, {overflow: "reject"}), 'cal.dateFromFields( {year: 2021, month: 3, day: 32}, {overflow: "reject"}) throws a RangeError exception'); +assert.throws(RangeError, () => cal.dateFromFields( + {year: 2021, month: 4, day: 31}, {overflow: "reject"}), 'cal.dateFromFields( {year: 2021, month: 4, day: 31}, {overflow: "reject"}) throws a RangeError exception'); +assert.throws(RangeError, () => cal.dateFromFields( + {year: 2021, month: 5, day: 32}, {overflow: "reject"}), 'cal.dateFromFields( {year: 2021, month: 5, day: 32}, {overflow: "reject"}) throws a RangeError exception'); +assert.throws(RangeError, () => cal.dateFromFields( + {year: 2021, month: 6, day: 31}, {overflow: "reject"}), 'cal.dateFromFields( {year: 2021, month: 6, day: 31}, {overflow: "reject"}) throws a RangeError exception'); +assert.throws(RangeError, () => cal.dateFromFields( + {year: 2021, month: 7, day: 32}, {overflow: "reject"}), 'cal.dateFromFields( {year: 2021, month: 7, day: 32}, {overflow: "reject"}) throws a RangeError exception'); +assert.throws(RangeError, () => cal.dateFromFields( + {year: 2021, month: 8, day: 32}, {overflow: "reject"}), 'cal.dateFromFields( {year: 2021, month: 8, day: 32}, {overflow: "reject"}) throws a RangeError exception'); +assert.throws(RangeError, () => cal.dateFromFields( + {year: 2021, month: 9, day: 31}, {overflow: "reject"}), 'cal.dateFromFields( {year: 2021, month: 9, day: 31}, {overflow: "reject"}) throws a RangeError exception'); +assert.throws(RangeError, () => cal.dateFromFields( + {year: 2021, month: 10, day: 32}, {overflow: "reject"}), 'cal.dateFromFields( {year: 2021, month: 10, day: 32}, {overflow: "reject"}) throws a RangeError exception'); +assert.throws(RangeError, () => cal.dateFromFields( + {year: 2021, month: 11, day: 31}, {overflow: "reject"}), 'cal.dateFromFields( {year: 2021, month: 11, day: 31}, {overflow: "reject"}) throws a RangeError exception'); +assert.throws(RangeError, () => cal.dateFromFields( + {year: 2021, month: 12, day: 32}, {overflow: "reject"}), 'cal.dateFromFields( {year: 2021, month: 12, day: 32}, {overflow: "reject"}) throws a RangeError exception'); +assert.throws(RangeError, () => cal.dateFromFields( + {year: 2021, month: 13, day: 5}, {overflow: "reject"}), 'cal.dateFromFields( {year: 2021, month: 13, day: 5}, {overflow: "reject"}) throws a RangeError exception'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/throws-type-error.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/throws-type-error.js new file mode 100644 index 0000000000..ca36990835 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/throws-type-error.js @@ -0,0 +1,58 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-temporal.calendar.prototype.datefromfields +description: Temporal.Calendar.prototype.dateFromFields should throw TypeError with wrong type. +info: | + 1. Let calendar be the this value. + 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]). + 3. Assert: calendar.[[Identifier]] is "iso8601". + 4. If Type(fields) is not Object, throw a TypeError exception. + 5. Set options to ? GetOptionsObject(options). + 6. Let result be ? ISODateFromFields(fields, options). + 7. Return ? CreateTemporalDate(result.[[Year]], result.[[Month]], result.[[Day]], calendar). +features: [BigInt, Symbol, Temporal, arrow-function] +---*/ +// Check throw for first arg +let cal = new Temporal.Calendar('iso8601'); +assert.throws(TypeError, () => cal.dateFromFields(), 'cal.dateFromFields() throws a TypeError exception'); + +[undefined, true, false, 123, 456n, Symbol(), 'string'].forEach(function(fields) { + assert.throws( + TypeError, + () => cal.dateFromFields(fields), + 'cal.dateFromFields(fields) throws a TypeError exception' + ); + + assert.throws( + TypeError, + () => cal.dateFromFields(fields, undefined), + 'cal.dateFromFields(fields, undefined) throws a TypeError exception' + ); + + assert.throws(TypeError, () => cal.dateFromFields(fields, { + overflow: 'constrain' + }), 'cal.dateFromFields(fields, {overflow: "constrain"}) throws a TypeError exception'); + + assert.throws(TypeError, () => cal.dateFromFields(fields, { + overflow: 'reject' + }), 'cal.dateFromFields(fields, {overflow: "reject"}) throws a TypeError exception'); +}); + +assert.throws(TypeError, () => cal.dateFromFields({ + month: 1, + day: 17 +}), 'cal.dateFromFields({month: 1, day: 17}) throws a TypeError exception'); + +assert.throws(TypeError, () => cal.dateFromFields({ + year: 2021, + day: 17 +}), 'cal.dateFromFields({year: 2021, day: 17}) throws a TypeError exception'); + +assert.throws(TypeError, () => cal.dateFromFields({ + year: 2021, + month: 12 +}), 'cal.dateFromFields({year: 2021, month: 12}) throws a TypeError exception'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/with-year-month-day-need-constrain.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/with-year-month-day-need-constrain.js new file mode 100644 index 0000000000..71bb9209cf --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/with-year-month-day-need-constrain.js @@ -0,0 +1,90 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-temporal.calendar.prototype.datefromfields +description: Temporal.Calendar.prototype.dateFromFields with year/month/day and need constrain +info: | + 1. Let calendar be the this value. + 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]). + 3. Assert: calendar.[[Identifier]] is "iso8601". + 4. If Type(fields) is not Object, throw a TypeError exception. + 5. Set options to ? GetOptionsObject(options). + 6. Let result be ? ISODateFromFields(fields, options). + 7. Return ? CreateTemporalDate(result.[[Year]], result.[[Month]], result.[[Day]], calendar). +features: [Temporal] +includes: [temporalHelpers.js] +---*/ +let cal = new Temporal.Calendar("iso8601") + +TemporalHelpers.assertPlainDate( + cal.dateFromFields({year: 2021, month: 1, day: 133}), + 2021, 1, "M01", 31, + "year/month/day with day need to be constrained in Jan"); + +TemporalHelpers.assertPlainDate( + cal.dateFromFields({year: 2021, month: 2, day: 133}), + 2021, 2, "M02", 28, + "year/month/day with day need to be constrained in Feb"); + +TemporalHelpers.assertPlainDate( + cal.dateFromFields({year: 2021, month: 3, day: 133}), + 2021, 3, "M03", 31, + "year/month/day with day need to be constrained in March"); + +TemporalHelpers.assertPlainDate( + cal.dateFromFields({year: 2021, month: 4, day: 133}), + 2021, 4, "M04", 30, + "year/month/day with day need to be constrained in April"); + +TemporalHelpers.assertPlainDate( + cal.dateFromFields({year: 2021, month: 5, day: 133}), + 2021, 5, "M05", 31, + "year/month/day with day need to be constrained in May"); + +TemporalHelpers.assertPlainDate( + cal.dateFromFields({year: 2021, month: 6, day: 133}), + 2021, 6, "M06", 30, + "year/month/day with day need to be constrained in Jun"); + +TemporalHelpers.assertPlainDate( + cal.dateFromFields({year: 2021, month: 7, day: 133}), + 2021, 7, "M07", 31, + "year/month/day with day need to be constrained in July"); + +TemporalHelpers.assertPlainDate( + cal.dateFromFields({year: 2021, month: 8, day: 133}), + 2021, 8, "M08", 31, + "year/month/day with day need to be constrained in Aug"); + +TemporalHelpers.assertPlainDate( + cal.dateFromFields({year: 2021, month: 9, day: 133}), + 2021, 9, "M09", 30, + "year/month/day with day need to be constrained in Sept."); + +TemporalHelpers.assertPlainDate( + cal.dateFromFields({year: 2021, month: 10, day: 133}), + 2021, 10, "M10", 31, + "year/month/day with day need to be constrained in Oct."); + +TemporalHelpers.assertPlainDate( + cal.dateFromFields({year: 2021, month: 11, day: 133}), + 2021, 11, "M11", 30, + "year/month/day with day need to be constrained in Nov."); + +TemporalHelpers.assertPlainDate( + cal.dateFromFields({year: 2021, month: 12, day: 133}), + 2021, 12, "M12", 31, + "year/month/day with day need to be constrained in Dec."); + +TemporalHelpers.assertPlainDate( + cal.dateFromFields({year: 2021, month: 13, day: 500}), + 2021, 12, "M12", 31, + "year/month/day with month and day need to be constrained"); + +TemporalHelpers.assertPlainDate( + cal.dateFromFields({year: 2021, month: 999999, day: 500}), + 2021, 12, "M12", 31, + "year/month/day with month and day need to be constrained"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/with-year-month-day.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/with-year-month-day.js new file mode 100644 index 0000000000..3109b1edd8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/with-year-month-day.js @@ -0,0 +1,25 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-temporal.calendar.prototype.datefromfields +description: Temporal.Calendar.prototype.dateFromFields with year/month/day +info: | + 1. Let calendar be the this value. + 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]). + 3. Assert: calendar.[[Identifier]] is "iso8601". + 4. If Type(fields) is not Object, throw a TypeError exception. + 5. Set options to ? GetOptionsObject(options). + 6. Let result be ? ISODateFromFields(fields, options). + 7. Return ? CreateTemporalDate(result.[[Year]], result.[[Month]], result.[[Day]], calendar). +features: [Temporal] +includes: [temporalHelpers.js] +---*/ +let cal = new Temporal.Calendar("iso8601") + +TemporalHelpers.assertPlainDate( + cal.dateFromFields({year: 2021, month: 7, day: 15}), + 2021, 7, "M07", 15, + "year/month/day"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/with-year-monthCode-day-need-constrain.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/with-year-monthCode-day-need-constrain.js new file mode 100644 index 0000000000..3f11886c7f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/with-year-monthCode-day-need-constrain.js @@ -0,0 +1,80 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-temporal.calendar.prototype.datefromfields +description: Temporal.Calendar.prototype.dateFromFields with year, monthCode and day and need constrain +info: | + 1. Let calendar be the this value. + 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]). + 3. Assert: calendar.[[Identifier]] is "iso8601". + 4. If Type(fields) is not Object, throw a TypeError exception. + 5. Set options to ? GetOptionsObject(options). + 6. Let result be ? ISODateFromFields(fields, options). + 7. Return ? CreateTemporalDate(result.[[Year]], result.[[Month]], result.[[Day]], calendar). +features: [Temporal] +includes: [temporalHelpers.js] +---*/ +let cal = new Temporal.Calendar("iso8601") + +TemporalHelpers.assertPlainDate( + cal.dateFromFields({year: 2021, monthCode: "M01", day: 133}), + 2021, 1, "M01", 31, + "year/monthCode/day with day need to be constrained in Jan"); + +TemporalHelpers.assertPlainDate( + cal.dateFromFields({year: 2021, monthCode: "M02", day: 133}), + 2021, 2, "M02", 28, + "year/monthCode/day with day need to be constrained in Feb"); + +TemporalHelpers.assertPlainDate( + cal.dateFromFields({year: 2021, monthCode: "M03", day: 133}), + 2021, 3, "M03", 31, + "year/monthCode/day with day need to be constrained in March"); + +TemporalHelpers.assertPlainDate( + cal.dateFromFields({year: 2021, monthCode: "M04", day: 133}), + 2021, 4, "M04", 30, + "year/monthCode/day with day need to be constrained in April"); + +TemporalHelpers.assertPlainDate( + cal.dateFromFields({year: 2021, monthCode: "M05", day: 133}), + 2021, 5, "M05", 31, + "year/monthCode/day with day need to be constrained in May"); + +TemporalHelpers.assertPlainDate( + cal.dateFromFields({year: 2021, monthCode: "M06", day: 133}), + 2021, 6, "M06", 30, + "year/monthCode/day with day need to be constrained in Jun"); + +TemporalHelpers.assertPlainDate( + cal.dateFromFields({year: 2021, monthCode: "M07", day: 133}), + 2021, 7, "M07", 31, + "year/monthCode/day with day need to be constrained in July"); + +TemporalHelpers.assertPlainDate( + cal.dateFromFields({year: 2021, monthCode: "M08", day: 133}), + 2021, 8, "M08", 31, + "year/monthCode/day with day need to be constrained in Aug"); + +TemporalHelpers.assertPlainDate( + cal.dateFromFields({year: 2021, monthCode: "M09", day: 133}), + 2021, 9, "M09", 30, + "year/monthCode/day with day need to be constrained in Sept."); + +TemporalHelpers.assertPlainDate( + cal.dateFromFields({year: 2021, monthCode: "M10", day: 133}), + 2021, 10, "M10", 31, + "year/monthCode/day with day need to be constrained in Oct."); + +TemporalHelpers.assertPlainDate( + cal.dateFromFields({year: 2021, monthCode: "M11", day: 133}), + 2021, 11, "M11", 30, + "year/monthCode/day with day need to be constrained in Nov."); + +TemporalHelpers.assertPlainDate( + cal.dateFromFields({year: 2021, monthCode: "M12", day: 133}), + 2021, 12, "M12", 31, + "year/monthCode/day with day need to be constrained in Dec."); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/with-year-monthCode-day.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/with-year-monthCode-day.js new file mode 100644 index 0000000000..d02aced783 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/with-year-monthCode-day.js @@ -0,0 +1,25 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-temporal.calendar.prototype.datefromfields +description: Temporal.Calendar.prototype.dateFromFields with year, monthCode and day. +info: | + 1. Let calendar be the this value. + 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]). + 3. Assert: calendar.[[Identifier]] is "iso8601". + 4. If Type(fields) is not Object, throw a TypeError exception. + 5. Set options to ? GetOptionsObject(options). + 6. Let result be ? ISODateFromFields(fields, options). + 7. Return ? CreateTemporalDate(result.[[Year]], result.[[Month]], result.[[Day]], calendar). +features: [Temporal] +includes: [temporalHelpers.js] +---*/ +let cal = new Temporal.Calendar("iso8601") + +TemporalHelpers.assertPlainDate( + cal.dateFromFields({year: 2021, monthCode: "M07", day: 15}), + 2021, 7, "M07", 15, + "year/monthCode/day"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-calendar-datefromfields-called-with-null-prototype-fields.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-calendar-datefromfields-called-with-null-prototype-fields.js new file mode 100644 index 0000000000..dac89baccb --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-calendar-datefromfields-called-with-null-prototype-fields.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.calendar.prototype.dateuntil +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.Calendar("iso8601"); +const arg1 = { year: 2000, month: 5, day: 2, calendar }; +const arg2 = new Temporal.PlainDate(1977, 11, 19); + +instance.dateUntil(arg1, arg2); +assert.sameValue(calendar.dateFromFieldsCallCount, 1, "dateFromFields should be called on the property bag's calendar (first argument)"); + +calendar.dateFromFieldsCallCount = 0; + +instance.dateUntil(arg2, arg1); +assert.sameValue(calendar.dateFromFieldsCallCount, 1, "dateFromFields should be called on the property bag's calendar (second argument)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-infinity-throws-rangeerror.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-infinity-throws-rangeerror.js new file mode 100644 index 0000000000..4ab7d417a3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-infinity-throws-rangeerror.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. + +/*--- +description: Throws if any value in a property bag for either argument is Infinity or -Infinity +esid: sec-temporal.calendar.prototype.dateuntil +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); +const other = new Temporal.PlainDate(2001, 6, 3); +const base = { year: 2000, month: 5, day: 2 }; + +[Infinity, -Infinity].forEach((inf) => { + ["year", "month", "day"].forEach((prop) => { + assert.throws(RangeError, () => instance.dateUntil({ ...base, [prop]: inf }, other), `${prop} property cannot be ${inf}`); + + assert.throws(RangeError, () => instance.dateUntil(other, { ...base, [prop]: inf }), `${prop} property cannot be ${inf}`); + + const calls1 = []; + const obj1 = TemporalHelpers.toPrimitiveObserver(calls1, inf, prop); + assert.throws(RangeError, () => instance.dateUntil({ ...base, [prop]: obj1 }, other)); + assert.compareArray(calls1, [`get ${prop}.valueOf`, `call ${prop}.valueOf`], "it fails after fetching the primitive value"); + + const calls2 = []; + const obj2 = TemporalHelpers.toPrimitiveObserver(calls2, inf, prop); + assert.throws(RangeError, () => instance.dateUntil(other, { ...base, [prop]: obj2 })); + assert.compareArray(calls2, [`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/Calendar/prototype/dateUntil/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-number.js new file mode 100644 index 0000000000..4e7331f861 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-number.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.calendar.prototype.dateuntil +description: A number is converted to a string, then to Temporal.PlainDate +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const arg = 19761118; + +const result1 = instance.dateUntil(arg, new Temporal.PlainDate(1976, 11, 19)); +TemporalHelpers.assertDuration(result1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "19761118 is a valid ISO string for PlainDate (first argument)"); +const result2 = instance.dateUntil(new Temporal.PlainDate(1976, 11, 19), arg); +TemporalHelpers.assertDuration(result2, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "19761118 is a valid ISO string for PlainDate (second argument)"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 18)), + `Number ${arg} does not convert to a valid ISO string for PlainDate (first argument)` + ); + assert.throws( + RangeError, + () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 18), arg), + `Number ${arg} does not convert to a valid ISO string for PlainDate (second argument)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-plaindatetime.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-plaindatetime.js new file mode 100644 index 0000000000..1c2b130d25 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-plaindatetime.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.calendar.prototype.dateuntil +description: Fast path for converting Temporal.PlainDateTime to Temporal.PlainDate by reading internal slots +info: | + sec-temporal.calendar.prototype.dateuntil steps 4–5: + 4. Set _one_ to ? ToTemporalDate(_one_). + 5. Set _two_ to ? ToTemporalDate(_two_). + sec-temporal-totemporaldate step 2.b: + b. If _item_ has an [[InitializedTemporalDateTime]] internal slot, then + i. Return ! CreateTemporalDate(_item_.[[ISOYear]], _item_.[[ISOMonth]], _item_.[[ISODay]], _item_.[[Calendar]]). +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const date = new Temporal.PlainDate(2000, 5, 2); + +TemporalHelpers.checkPlainDateTimeConversionFastPath((datetime) => { + const calendar = new Temporal.Calendar("iso8601"); + const result = calendar.dateUntil(datetime, date); + assert.sameValue(result.total({ unit: "nanoseconds" }), 0, "time part dropped"); +}); + +TemporalHelpers.checkPlainDateTimeConversionFastPath((datetime) => { + const calendar = new Temporal.Calendar("iso8601"); + const result = calendar.dateUntil(date, datetime); + assert.sameValue(result.total({ unit: "nanoseconds" }), 0, "time part dropped"); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-case-insensitive.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-case-insensitive.js new file mode 100644 index 0000000000..8f5955df5e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-case-insensitive.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.calendar.prototype.dateuntil +description: The calendar name is case-insensitive +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "IsO8601"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.dateUntil(arg, new Temporal.PlainDate(1976, 11, 19)); +TemporalHelpers.assertDuration(result1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "Calendar is case-insensitive (first argument)"); +const result2 = instance.dateUntil(new Temporal.PlainDate(1976, 11, 19), arg); +TemporalHelpers.assertDuration(result2, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "Calendar is case-insensitive (second argument)"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result3 = instance.dateUntil(arg, new Temporal.PlainDate(1976, 11, 19)); +TemporalHelpers.assertDuration(result3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "Calendar is case-insensitive (nested property, first argument)"); +const result4 = instance.dateUntil(new Temporal.PlainDate(1976, 11, 19), arg); +TemporalHelpers.assertDuration(result4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "Calendar is case-insensitive (nested property, second argument)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-instance-does-not-get-calendar-property.js new file mode 100644 index 0000000000..42584e5f7a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-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.calendar.prototype.dateuntil +description: > + A Temporal.Calendar instance passed to dateUntil() in a property bag does + not have its 'calendar' property observably checked +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = new Temporal.Calendar("iso8601"); +Object.defineProperty(calendar, "calendar", { + get() { + throw new Test262Error("calendar.calendar should not be accessed"); + }, +}); + +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +instance.dateUntil(arg, arg); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-leap-second.js new file mode 100644 index 0000000000..df692ceec4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-leap-second.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.calendar.prototype.dateuntil +description: Leap second is a valid ISO string for a calendar in a property bag +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.dateUntil(arg, new Temporal.PlainDate(1976, 11, 19)); +TemporalHelpers.assertDuration(result1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "leap second is a valid ISO string for calendar (first argument)"); +const result2 = instance.dateUntil(new Temporal.PlainDate(1976, 11, 19), arg); +TemporalHelpers.assertDuration(result2, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "leap second is a valid ISO string for calendar (second argument)"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result3 = instance.dateUntil(arg, new Temporal.PlainDate(1976, 11, 19)); +TemporalHelpers.assertDuration(result3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "leap second is a valid ISO string for calendar (nested property, first argument)"); +const result4 = instance.dateUntil(new Temporal.PlainDate(1976, 11, 19), arg); +TemporalHelpers.assertDuration(result4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "leap second is a valid ISO string for calendar (nested property, second argument)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-number.js new file mode 100644 index 0000000000..9e48cdb500 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-number.js @@ -0,0 +1,59 @@ +// |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.calendar.prototype.dateuntil +description: A number as calendar in a property bag is converted to a string, then to a calendar +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.dateUntil(arg, new Temporal.PlainDate(1976, 11, 19)); +TemporalHelpers.assertDuration(result1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar (first argument)"); +const result2 = instance.dateUntil(new Temporal.PlainDate(1976, 11, 19), arg); +TemporalHelpers.assertDuration(result2, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar (second argument)"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result3 = instance.dateUntil(arg, new Temporal.PlainDate(1976, 11, 19)); +TemporalHelpers.assertDuration(result3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar (nested property, first argument)"); +const result4 = instance.dateUntil(new Temporal.PlainDate(1976, 11, 19), arg); +TemporalHelpers.assertDuration(result4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar (nested property, second argument)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + assert.throws( + RangeError, + () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)), + `Number ${calendar} does not convert to a valid ISO string for calendar (first argument)` + ); + assert.throws( + RangeError, + () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (second argument)` + ); + arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property, first argument)` + ); + assert.throws( + RangeError, + () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property, second argument)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-string.js new file mode 100644 index 0000000000..5b5b120b37 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-string.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.calendar.prototype.dateuntil +description: A calendar ID is valid input for Calendar +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "iso8601"; + +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + +const result1 = instance.dateUntil(arg, new Temporal.PlainDate(1976, 11, 18)); +TemporalHelpers.assertDuration(result1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, `Calendar created from string "${arg} (first argument)"`); + +const result2 = instance.dateUntil(new Temporal.PlainDate(1976, 11, 18), arg); +TemporalHelpers.assertDuration(result2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, `Calendar created from string "${arg} (second argument)"`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 0000000000..8a27f75bf3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,56 @@ +// |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.calendar.prototype.dateuntil +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.Calendar("iso8601"); + +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 [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)), `${description} does not convert to a valid ISO string (first argument)`); + assert.throws(RangeError, () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg), `${description} does not convert to a valid ISO string (second argument)`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)), `${description} does not convert to a valid ISO string (nested property, first argument)`); + assert.throws(RangeError, () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg), `${description} does not convert to a valid ISO string (nested property, second argument)`); +} + +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.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)), `${description} is not a valid property bag and does not convert to a string (first argument)`); + assert.throws(TypeError, () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg), `${description} is not a valid property bag and does not convert to a string (second argument)`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)), `${description} is not a valid property bag and does not convert to a string (nested property, first argument)`); + assert.throws(TypeError, () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg), `${description} is not a valid property bag and does not convert to a string (nested property, second argument)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)), `nested undefined calendar property is always a RangeError (first argument)`); +assert.throws(RangeError, () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg), `nested undefined calendar property is always a RangeError (second argument)`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-year-zero.js new file mode 100644 index 0000000000..e227d73895 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-year-zero.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.calendar.prototype.dateuntil +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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)), + "reject minus zero as extended year (first argument)" + ); + assert.throws( + RangeError, + () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg), + "reject minus zero as extended year (second argument)" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-calendar-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-calendar-annotation.js new file mode 100644 index 0000000000..60e1f05c9c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/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.calendar.prototype.dateuntil +description: Various forms of calendar annotation; critical flag has no effect +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const tests = [ + ["2000-05-02[u-ca=iso8601]", "without time or time zone"], + ["2000-05-02[UTC][u-ca=iso8601]", "with time zone and no time"], + ["2000-05-02T15:23[u-ca=iso8601]", "without time zone"], + ["2000-05-02T15:23[UTC][u-ca=iso8601]", "with time zone"], + ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], + ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], + ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], + ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.dateUntil(arg, arg); + + TemporalHelpers.assertDuration( + result, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + `calendar annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-critical-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-critical-unknown-annotation.js new file mode 100644 index 0000000000..994389219f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-critical-unknown-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.calendar.prototype.dateuntil +description: Unknown annotations with critical flag are rejected +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[!foo=bar]", + "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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)), + `reject unknown annotation with critical flag: ${arg} (first argument)` + ); + assert.throws( + RangeError, + () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg), + `reject unknown annotation with critical flag: ${arg} (second argument)` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-date-with-utc-offset.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-date-with-utc-offset.js new file mode 100644 index 0000000000..9339859924 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/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.calendar.prototype.dateuntil +description: UTC offset not valid with format that does not include a time +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const validStrings = [ + "2000-05-02T00+00:00", + "2000-05-02T00+00:00[UTC]", + "2000-05-02T00+00:00[!UTC]", + "2000-05-02T00-02:30[America/St_Johns]", +]; + +for (const arg of validStrings) { + TemporalHelpers.assertDuration( + instance.dateUntil(arg, arg), + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + `"${arg}" is a valid UTC offset with time for PlainDate` + ); +} + +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.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)), + `"${arg}" UTC offset without time is not valid for PlainDate (first argument)` + ); + assert.throws( + RangeError, + () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg), + `"${arg}" UTC offset without time is not valid for PlainDate (second argument)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-invalid.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-invalid.js new file mode 100644 index 0000000000..58e7360222 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-invalid.js @@ -0,0 +1,70 @@ +// |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.calendar.prototype.dateuntil +description: > + RangeError thrown if an invalid ISO string (or syntactically valid ISO string + that is not supported) is used as a PlainDate +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + // invalid ISO strings: + "", + "invalid iso8601", + "2020-01-00", + "2020-01-32", + "2020-02-30", + "2021-02-29", + "2020-00-01", + "2020-13-01", + "2020-01-01T", + "2020-01-01T25:00:00", + "2020-01-01T01:60:00", + "2020-01-01T01:60:61", + "2020-01-01junk", + "2020-01-01T00:00:00junk", + "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-01", + "2020-001-01", + "2020-01-001", + "2020-01-01T001", + "2020-01-01T01:001", + "2020-01-01T01:01:001", + // valid, but forms not supported in Temporal: + "2020-W01-1", + "2020-001", + "+0002020-01-01", + // valid, but this calendar must not exist: + "2020-01-01[u-ca=notexist]", + // may be valid in other contexts, but insufficient information for PlainDate: + "2020-01", + "+002020-01", + "01-01", + "2020-W01", + "P1Y", + "-P12Y", + // valid, but outside the supported range: + "-999999-01-01", + "+999999-01-01", +]; +const instance = new Temporal.Calendar("iso8601"); +const other = new Temporal.PlainDate(2020, 1, 1, instance); +for (const arg of invalidStrings) { + assert.throws( + RangeError, + () => instance.dateUntil(arg, other), + `"${arg}" should not be a valid ISO string for a PlainDate (first argument)` + ); + assert.throws( + RangeError, + () => instance.dateUntil(other, arg), + `"${arg}" should not be a valid ISO string for a PlainDate (second argument)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-multiple-time-zone.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-multiple-time-zone.js new file mode 100644 index 0000000000..ac4c599325 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-multiple-time-zone.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.calendar.prototype.dateuntil +description: More than one time zone annotation is not syntactical +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[UTC][UTC]", + "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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)), + `reject more than one time zone annotation: ${arg} (first argument)` + ); + assert.throws( + RangeError, + () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg), + `reject more than one time zone annotation: ${arg} (second argument)` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-time-separators.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-time-separators.js new file mode 100644 index 0000000000..b845de6366 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-time-separators.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.calendar.prototype.dateuntil +description: Time separator in string argument can vary +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const date = new Temporal.PlainDate(2000, 5, 3); +const tests = [ + ["2000-05-02T15:23", "uppercase T"], + ["2000-05-02t15:23", "lowercase T"], + ["2000-05-02 15:23", "space between date and time"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + TemporalHelpers.assertDuration( + instance.dateUntil(arg, date), + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + `variant time separators (${description}), first argument` + ); + + TemporalHelpers.assertDuration( + instance.dateUntil(date, arg), + 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, + `variant time separators (${description}), second argument` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-time-zone-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-time-zone-annotation.js new file mode 100644 index 0000000000..55d68d0ccd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-time-zone-annotation.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.calendar.prototype.dateuntil +description: Various forms of time zone annotation; critical flag has no effect +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const tests = [ + ['2000-05-02[Asia/Kolkata]', 'named, with no time'], + ['2000-05-02[!Europe/Vienna]', 'named, with ! and no time'], + ['2000-05-02[+00:00]', 'numeric, with no time'], + ['2000-05-02[!-02:30]', 'numeric, with ! and no time'], + ["2000-05-02T15:23[America/Sao_Paulo]", "named, with no offset"], + ["2000-05-02T15:23[!Asia/Tokyo]", "named, with ! and no offset"], + ["2000-05-02T15:23[-02:30]", "numeric, with no offset"], + ["2000-05-02T15:23[!+00:00]", "numeric, with ! and no offset"], + ["2000-05-02T15:23+00:00[America/New_York]", "named, with offset"], + ["2000-05-02T15:23+00:00[!UTC]", "named, with offset and !"], + ["2000-05-02T15:23+00:00[+01:00]", "numeric, with offset"], + ["2000-05-02T15:23+00:00[!-08:00]", "numeric, with offset and !"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.dateUntil(arg, arg); + + TemporalHelpers.assertDuration( + result, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + `time zone annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-unknown-annotation.js new file mode 100644 index 0000000000..3f36293f89 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-unknown-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.calendar.prototype.dateuntil +description: Various forms of unknown annotation +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const tests = [ + ["2000-05-02[foo=bar]", "without time"], + ["2000-05-02T15:23[foo=bar]", "alone"], + ["2000-05-02T15:23[UTC][foo=bar]", "with time zone"], + ["2000-05-02T15:23[u-ca=iso8601][foo=bar]", "with calendar"], + ["2000-05-02T15:23[UTC][foo=bar][u-ca=iso8601]", "with time zone and calendar"], + ["2000-05-02T15:23[foo=bar][_foo-bar0=Ignore-This-999999999999]", "with another unknown annotation"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.dateUntil(arg, arg); + + TemporalHelpers.assertDuration( + result, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + `unknown annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-with-utc-designator.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-with-utc-designator.js new file mode 100644 index 0000000000..c7d2382e0c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-with-utc-designator.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.calendar.prototype.dateuntil +description: RangeError thrown if a string with UTC designator is used as a PlainDate +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "2019-10-01T09:00:00Z", + "2019-10-01T09:00:00Z[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +const plainDate = new Temporal.PlainDate(2000, 5, 2); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.dateUntil(arg, plainDate), + "String with UTC designator should not be valid as a PlainDate (first argument)" + ); + assert.throws( + RangeError, + () => instance.dateUntil(plainDate, arg), + "String with UTC designator should not be valid as a PlainDate (second argument)" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-wrong-type.js new file mode 100644 index 0000000000..7765e0384d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-wrong-type.js @@ -0,0 +1,42 @@ +// |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.calendar.prototype.dateuntil +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.Calendar("iso8601"); + +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.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)), `${description} does not convert to a valid ISO string (first argument)`); + assert.throws(RangeError, () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg), `${description} does not convert to a valid ISO string (first argument)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)), `${description} is not a valid property bag and does not convert to a string (second argument)`); + assert.throws(TypeError, () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg), `${description} is not a valid property bag and does not convert to a string (second argument)`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-zoneddatetime-slots.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-zoneddatetime-slots.js new file mode 100644 index 0000000000..ac02f5a047 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-zoneddatetime-slots.js @@ -0,0 +1,41 @@ +// |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.calendar.prototype.dateuntil +description: Getters are not called when converting a ZonedDateTime to a PlainDate. +includes: [compareArray.js] +features: [Temporal] +---*/ + +const actual = []; +const prototypeDescrs = Object.getOwnPropertyDescriptors(Temporal.ZonedDateTime.prototype); +const getters = ["year", "month", "monthCode", "day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond", "calendar"]; + +for (const property of getters) { + Object.defineProperty(Temporal.ZonedDateTime.prototype, property, { + get() { + actual.push(`get ${property}`); + const value = prototypeDescrs[property].get.call(this); + return { + toString() { + actual.push(`toString ${property}`); + return value.toString(); + }, + valueOf() { + actual.push(`valueOf ${property}`); + return value; + }, + }; + }, + }); +} + +const arg = new Temporal.ZonedDateTime(0n, "UTC"); +const instance = new Temporal.Calendar("iso8601"); +instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)); +instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg); +assert.compareArray(actual, []); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js new file mode 100644 index 0000000000..96abbb46e3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.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.calendar.prototype.dateuntil +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 calendar = new Temporal.Calendar("iso8601"); + const date = new Temporal.PlainDate(2000, 5, 2); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + + assert.throws(RangeError, () => calendar.dateUntil(datetime, date)); + assert.throws(RangeError, () => calendar.dateUntil(date, datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js new file mode 100644 index 0000000000..18bb629148 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.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.calendar.prototype.dateuntil +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 calendar = new Temporal.Calendar("iso8601"); + const date = new Temporal.PlainDate(2000, 5, 2); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + timeZone.getOffsetNanosecondsFor = notCallable; + + assert.throws( + TypeError, + () => calendar.dateUntil(datetime, date), + `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError` + ); + assert.throws( + TypeError, + () => calendar.dateUntil(date, datetime), + `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js new file mode 100644 index 0000000000..e14b3bd0ef --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.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.calendar.prototype.dateuntil +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 calendar = new Temporal.Calendar("iso8601"); + const date = new Temporal.PlainDate(2000, 5, 2); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + + assert.throws(RangeError, () => calendar.dateUntil(datetime, date)); + assert.throws(RangeError, () => calendar.dateUntil(date, datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js new file mode 100644 index 0000000000..f865e6185e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js @@ -0,0 +1,31 @@ +// |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.calendar.prototype.dateuntil +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 calendar = new Temporal.Calendar("iso8601"); + const date = new Temporal.PlainDate(2000, 5, 2); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + + assert.throws(TypeError, () => calendar.dateUntil(datetime, date)); + assert.throws(TypeError, () => calendar.dateUntil(date, datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/basic.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/basic.js new file mode 100644 index 0000000000..578969af39 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/basic.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.calendar.prototype.dateuntil +description: Basic tests for dateUntil(). +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const iso = Temporal.Calendar.from("iso8601"); +const date1 = Temporal.PlainDate.from("1999-09-03"); +const date2 = Temporal.PlainDate.from("2000-01-01"); + +TemporalHelpers.assertDuration( + iso.dateUntil(date1, date2, {}), + 0, 0, 0, 120, 0, 0, 0, 0, 0, 0, "two PlainDates"); + +TemporalHelpers.assertDuration( + iso.dateUntil(Temporal.PlainDateTime.from("1999-09-03T08:15:30"), date2, {}), + 0, 0, 0, 120, 0, 0, 0, 0, 0, 0, "first argument: PlainDateTime"); + +TemporalHelpers.assertDuration( + iso.dateUntil({ year: 1999, month: 9, day: 3 }, date2, {}), + 0, 0, 0, 120, 0, 0, 0, 0, 0, 0, "first argument: property bag"); + +TemporalHelpers.assertDuration( + iso.dateUntil("1999-09-03", date2, {}), + 0, 0, 0, 120, 0, 0, 0, 0, 0, 0, "first argument: string"); + +assert.throws(TypeError, () => iso.dateUntil({ month: 11 }, date2, {}), "first argument: missing property"); + +TemporalHelpers.assertDuration( + iso.dateUntil(date1, Temporal.PlainDateTime.from("2000-01-01T08:15:30"), {}), + 0, 0, 0, 120, 0, 0, 0, 0, 0, 0, "second argument: PlainDateTime"); + +TemporalHelpers.assertDuration( + iso.dateUntil(date1, { year: 2000, month: 1, day: 1 }, {}), + 0, 0, 0, 120, 0, 0, 0, 0, 0, 0, "second argument: property bag"); + +TemporalHelpers.assertDuration( + iso.dateUntil(date1, "2000-01-01", {}), + 0, 0, 0, 120, 0, 0, 0, 0, 0, 0, "second argument: string"); + +assert.throws(TypeError, () => iso.dateUntil(date1, { month: 11 }, {}), "second argument: missing property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/branding.js new file mode 100644 index 0000000000..821019468d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/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.calendar.prototype.dateuntil +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const dateUntil = Temporal.Calendar.prototype.dateUntil; + +assert.sameValue(typeof dateUntil, "function"); + +const args = [new Temporal.PlainDate(2021, 7, 16), new Temporal.PlainDate(2021, 7, 17)]; + +assert.throws(TypeError, () => dateUntil.apply(undefined, args), "undefined"); +assert.throws(TypeError, () => dateUntil.apply(null, args), "null"); +assert.throws(TypeError, () => dateUntil.apply(true, args), "true"); +assert.throws(TypeError, () => dateUntil.apply("", args), "empty string"); +assert.throws(TypeError, () => dateUntil.apply(Symbol(), args), "symbol"); +assert.throws(TypeError, () => dateUntil.apply(1, args), "1"); +assert.throws(TypeError, () => dateUntil.apply({}, args), "plain object"); +assert.throws(TypeError, () => dateUntil.apply(Temporal.Calendar, args), "Temporal.Calendar"); +assert.throws(TypeError, () => dateUntil.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/builtin.js new file mode 100644 index 0000000000..6d815bb5f5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/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.calendar.prototype.dateuntil +description: > + Tests that Temporal.Calendar.prototype.dateUntil + 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.Calendar.prototype.dateUntil), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.dateUntil), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.dateUntil), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.Calendar.prototype.dateUntil.hasOwnProperty("prototype"), + false, "prototype property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/calendar-datefromfields-called-with-options-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/calendar-datefromfields-called-with-options-undefined.js new file mode 100644 index 0000000000..dd0bf1d426 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/calendar-datefromfields-called-with-options-undefined.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.calendar.prototype.dateuntil +description: > + Calendar.dateFromFields method is called with undefined as the options value + when call originates internally +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = TemporalHelpers.calendarFromFieldsUndefinedOptions(); +calendar.dateUntil({ year: 2000, month: 5, day: 2, calendar }, { year: 2000, month: 5, day: 3, calendar }); +assert.sameValue(calendar.dateFromFieldsCallCount, 2); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/calendar-fields-iterable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/calendar-fields-iterable.js new file mode 100644 index 0000000000..dbdb3f0840 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/calendar-fields-iterable.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.calendar.prototype.dateuntil +description: Verify the result of calendar.fields() is treated correctly. +info: | + sec-temporal.calendar.prototype.dateuntil steps 4–5: + 4. Set _one_ to ? ToTemporalDate(_one_). + 5. Set _two_ to ? ToTemporalDate(_two_). + sec-temporal-totemporaldate step 2.c: + c. Let _fieldNames_ be ? CalendarFields(_calendar_, « *"day"*, *"month"*, *"monthCode"*, *"year"* »). + sec-temporal-calendarfields step 4: + 4. Let _result_ be ? IterableToListOfType(_fieldsArray_, « String »). +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + "day", + "month", + "monthCode", + "year", +]; + +const calendar1 = TemporalHelpers.calendarFieldsIterable(); +const calendar2 = TemporalHelpers.calendarFieldsIterable(); +const calendar3 = TemporalHelpers.calendarFieldsIterable(); +calendar1.dateUntil( + { year: 2000, month: 5, day: 2, calendar: calendar2 }, + { year: 2005, month: 6, day: 3, calendar: calendar3 }, +); + +assert.sameValue(calendar1.fieldsCallCount, 0, "fields() method not called"); +assert.sameValue(calendar2.fieldsCallCount, 1, "fields() method called once"); +assert.sameValue(calendar3.fieldsCallCount, 1, "fields() method called once"); +assert.compareArray(calendar2.fieldsCalledWith[0], expected, "fields() method called with correct args"); +assert(calendar2.iteratorExhausted[0], "iterated through the whole iterable"); +assert.compareArray(calendar3.fieldsCalledWith[0], expected, "fields() method called with correct args"); +assert(calendar3.iteratorExhausted[0], "iterated through the whole iterable"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/calendar-temporal-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/calendar-temporal-object.js new file mode 100644 index 0000000000..999db10664 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/calendar-temporal-object.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.calendar.prototype.dateuntil +description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots +info: | + sec-temporal.calendar.prototype.dateuntil steps 4–5: + 4. Set _one_ to ? ToTemporalDate(_one_). + 5. Set _two_ to ? ToTemporalDate(_two_). + sec-temporal-totemporaldate 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 calendar = new Temporal.Calendar("iso8601"); + calendar.dateUntil( + { year: 2000, month: 5, day: 2, calendar: temporalObject }, + { year: 2005, month: 6, day: 3, calendar: temporalObject }, + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/largest-unit-day.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/largest-unit-day.js new file mode 100644 index 0000000000..fa8a543221 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/largest-unit-day.js @@ -0,0 +1,62 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dateuntil +description: Temporal.Calendar.prototype.dateUntil with largestUnit is "day" +info: | + 1. Let calendar be the this value. + 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]). + 3. Assert: calendar.[[Identifier]] is "iso8601". + 4. Set one to ? ToTemporalDate(one). + 5. Set two to ? ToTemporalDate(two). + 6. Set options to ? GetOptionsObject(options). + 7. Let largestUnit be ? ToLargestTemporalUnit(options, « "hour", "minute", "second", "millisecond", "microsecond", "nanosecond" », "auto", "day"). + 8. Let result be ! DifferenceISODate(one.[[ISOYear]], one.[[ISOMonth]], one.[[ISODay]], two.[[ISOYear]], two.[[ISOMonth]], two.[[ISODay]], largestUnit). + 9. Return ? CreateTemporalDuration(result.[[Years]], result.[[Months]], result.[[Weeks]], result.[[Days]], 0, 0, 0, 0, 0, 0). +features: [Temporal] +includes: [temporalHelpers.js] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +["day", "days"].forEach(function(largestUnit) { + let opt = {largestUnit}; + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2021-07-16", opt), + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "same day"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2021-07-17", opt), + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "one day"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2021-08-17", opt), + 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, "32 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2021-09-16", opt), + 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, "62 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2022-07-16", opt), + 0, 0, 0, 365, 0, 0, 0, 0, 0, 0, "365 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2031-07-16", opt), + 0, 0, 0, 3652, 0, 0, 0, 0, 0, 0, "3652 days"); + + + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-17", "2021-07-16", opt), + 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "negative one day"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-08-17", "2021-07-16", opt), + 0, 0, 0, -32, 0, 0, 0, 0, 0, 0, "negative 32 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-09-16", "2021-07-16", opt), + 0, 0, 0, -62, 0, 0, 0, 0, 0, 0, "negative 62 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2022-07-16", "2021-07-16", opt), + 0, 0, 0, -365, 0, 0, 0, 0, 0, 0, "negative 365 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2031-07-16", "2021-07-16", opt), + 0, 0, 0, -3652, 0, 0, 0, 0, 0, 0, "negative 3652 days"); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/largest-unit-month.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/largest-unit-month.js new file mode 100644 index 0000000000..9e36bfe183 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/largest-unit-month.js @@ -0,0 +1,97 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dateuntil +description: Temporal.Calendar.prototype.dateUntil with largestUnit is "month" +info: | + 1. Let calendar be the this value. + 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]). + 3. Assert: calendar.[[Identifier]] is "iso8601". + 4. Set one to ? ToTemporalDate(one). + 5. Set two to ? ToTemporalDate(two). + 6. Set options to ? GetOptionsObject(options). + 7. Let largestUnit be ? ToLargestTemporalUnit(options, « "hour", "minute", "second", "millisecond", "microsecond", "nanosecond" », "auto", "day"). + 8. Let result be ! DifferenceISODate(one.[[ISOYear]], one.[[ISOMonth]], one.[[ISODay]], two.[[ISOYear]], two.[[ISOMonth]], two.[[ISODay]], largestUnit). + 9. Return ? CreateTemporalDuration(result.[[Years]], result.[[Months]], result.[[Weeks]], result.[[Days]], 0, 0, 0, 0, 0, 0). +features: [Temporal] +includes: [temporalHelpers.js] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +["month", "months"].forEach(function(largestUnit) { + let opt = {largestUnit}; + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2021-07-16", opt), + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "same day"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2021-07-17", opt), + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "one day"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2021-07-23", opt), + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, "7 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2021-08-16", opt), + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "1 month in same year"); + TemporalHelpers.assertDuration( + cal.dateUntil("2020-12-16", "2021-01-16", opt), + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "1 month in different year"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-01-05", "2021-02-05", opt), + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "1 month in same year"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-01-07", "2021-03-07", opt), + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, "2 month in same year across Feb 28"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2021-08-17", opt), + 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, "1 month and 1 day in a month with 31 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2021-08-13", opt), + 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, "28 days roll across a month which has 31 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2021-09-16", opt), + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, "2 months with both months which have 31 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2022-07-16", opt), + 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, "12 months"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2031-07-16", opt), + 0, 120, 0, 0, 0, 0, 0, 0, 0, 0, "120 months"); + + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-17", "2021-07-16", opt), + 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "negative one day"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-23", "2021-07-16", opt), + 0, 0, 0, -7, 0, 0, 0, 0, 0, 0, "negative 7 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-08-16", "2021-07-16", opt), + 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, "negative 1 month in same year"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-01-16", "2020-12-16", opt), + 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, "negative 1 month in different year"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-02-05", "2021-01-05", opt), + 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, "negative 1 month in same year"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-03-07", "2021-01-07", opt), + 0, -2, 0, 0, 0, 0, 0, 0, 0, 0, "negative 2 month in same year across Feb 28"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-08-17", "2021-07-16", opt), + 0, -1, 0, -1, 0, 0, 0, 0, 0, 0, "negative 1 month and 1 day in a month with 31 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-08-13", "2021-07-16", opt), + 0, 0, 0, -28, 0, 0, 0, 0, 0, 0, "negative 28 days roll across a month which has 31 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-09-16", "2021-07-16", opt), + 0, -2, 0, 0, 0, 0, 0, 0, 0, 0, "negative 2 months with both months which have 31 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2022-07-16", "2021-07-16", opt), + 0, -12, 0, 0, 0, 0, 0, 0, 0, 0, "negative 12 months"); + TemporalHelpers.assertDuration( + cal.dateUntil("2031-07-16", "2021-07-16", opt), + 0, -120, 0, 0, 0, 0, 0, 0, 0, 0, "negative 120 months"); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/largest-unit-week.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/largest-unit-week.js new file mode 100644 index 0000000000..2104690318 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/largest-unit-week.js @@ -0,0 +1,74 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dateuntil +description: Temporal.Calendar.prototype.dateUntil with largestUnit is "week" +info: | + 1. Let calendar be the this value. + 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]). + 3. Assert: calendar.[[Identifier]] is "iso8601". + 4. Set one to ? ToTemporalDate(one). + 5. Set two to ? ToTemporalDate(two). + 6. Set options to ? GetOptionsObject(options). + 7. Let largestUnit be ? ToLargestTemporalUnit(options, « "hour", "minute", "second", "millisecond", "microsecond", "nanosecond" », "auto", "day"). + 8. Let result be ! DifferenceISODate(one.[[ISOYear]], one.[[ISOMonth]], one.[[ISODay]], two.[[ISOYear]], two.[[ISOMonth]], two.[[ISODay]], largestUnit). + 9. Return ? CreateTemporalDuration(result.[[Years]], result.[[Months]], result.[[Weeks]], result.[[Days]], 0, 0, 0, 0, 0, 0). +features: [Temporal] +includes: [temporalHelpers.js] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +["week", "weeks"].forEach(function(largestUnit) { + let opt = {largestUnit}; + + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2021-07-16", opt), + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "same day"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2021-07-17", opt), + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "one day"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2021-07-23", opt), + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "7 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2021-08-16", opt), + 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, "4 weeks and 3 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2021-08-13", opt), + 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, "4 weeks"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2021-09-16", opt), + 0, 0, 8, 6, 0, 0, 0, 0, 0, 0, "8 weeks and 6 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2022-07-16", opt), + 0, 0, 52, 1, 0, 0, 0, 0, 0, 0, "52 weeks and 1 day"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2031-07-16", opt), + 0, 0, 521, 5, 0, 0, 0, 0, 0, 0, "521 weeks and 5 days"); + + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-17", "2021-07-16", opt), + 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "negative one day"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-23", "2021-07-16", opt), + 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, "negative 7 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-08-16", "2021-07-16", opt), + 0, 0, -4, -3, 0, 0, 0, 0, 0, 0, "negative 4 weeks and 3 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-08-13", "2021-07-16", opt), + 0, 0, -4, 0, 0, 0, 0, 0, 0, 0, "negative 4 weeks"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-09-16", "2021-07-16", opt), + 0, 0, -8, -6, 0, 0, 0, 0, 0, 0, "negative 8 weeks and 6 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2022-07-16", "2021-07-16", opt), + 0, 0, -52, -1, 0, 0, 0, 0, 0, 0, "negative 52 weeks and 1 day"); + TemporalHelpers.assertDuration( + cal.dateUntil("2031-07-16", "2021-07-16", opt), + 0, 0, -521, -5, 0, 0, 0, 0, 0, 0, "negative 521 weeks and 5 days"); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/largest-unit-year.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/largest-unit-year.js new file mode 100644 index 0000000000..8ecda7e1d5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/largest-unit-year.js @@ -0,0 +1,207 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dateuntil +description: Temporal.Calendar.prototype.dateUntil with largestUnit is "year" +info: | + 1. Let calendar be the this value. + 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]). + 3. Assert: calendar.[[Identifier]] is "iso8601". + 4. Set one to ? ToTemporalDate(one). + 5. Set two to ? ToTemporalDate(two). + 6. Set options to ? GetOptionsObject(options). + 7. Let largestUnit be ? ToLargestTemporalUnit(options, « "hour", "minute", "second", "millisecond", "microsecond", "nanosecond" », "auto", "day"). + 8. Let result be ! DifferenceISODate(one.[[ISOYear]], one.[[ISOMonth]], one.[[ISODay]], two.[[ISOYear]], two.[[ISOMonth]], two.[[ISODay]], largestUnit). + 9. Return ? CreateTemporalDuration(result.[[Years]], result.[[Months]], result.[[Weeks]], result.[[Days]], 0, 0, 0, 0, 0, 0). +features: [Temporal] +includes: [temporalHelpers.js] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +["year", "years"].forEach(function(largestUnit) { + let opt = {largestUnit}; + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2021-07-16", opt), + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "same day"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2021-07-17", opt), + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "one day"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2021-07-23", opt), + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, "7 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2021-08-16", opt), + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "1 month in same year"); + TemporalHelpers.assertDuration( + cal.dateUntil("2020-12-16", "2021-01-16", opt), + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "1 month in different year"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-01-05", "2021-02-05", opt), + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "1 month in same year"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-01-07", "2021-03-07", opt), + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, "2 month in same year across Feb 28"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2021-08-17", opt), + 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, "1 month and 1 day in a month with 31 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2021-08-13", opt), + 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, "28 days roll across a month which has 31 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2021-09-16", opt), + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, "2 months with both months which have 31 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2022-07-16", opt), + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "1 year"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2031-07-16", opt), + 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, "10 years"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2022-07-19", opt), + 1, 0, 0, 3, 0, 0, 0, 0, 0, 0, "1 year and 3 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2022-09-19", opt), + 1, 2, 0, 3, 0, 0, 0, 0, 0, 0, "1 year 2 months and 3 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2031-12-16", opt), + 10, 5, 0, 0, 0, 0, 0, 0, 0, 0, "10 years and 5 months"); + TemporalHelpers.assertDuration( + cal.dateUntil("1997-12-16", "2021-07-16", opt), + 23, 7, 0, 0, 0, 0, 0, 0, 0, 0, "23 years and 7 months"); + TemporalHelpers.assertDuration( + cal.dateUntil("1997-07-16", "2021-07-16", opt), + 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, "24 years"); + TemporalHelpers.assertDuration( + cal.dateUntil("1997-07-16", "2021-07-15", opt), + 23, 11, 0, 29, 0, 0, 0, 0, 0, 0, "23 years, 11 months and 29 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("1997-06-16", "2021-06-15", opt), + 23, 11, 0, 30, 0, 0, 0, 0, 0, 0, "23 years, 11 months and 30 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("1960-02-16", "2020-03-16", opt), + 60, 1, 0, 0, 0, 0, 0, 0, 0, 0, "60 years, 1 month"); + TemporalHelpers.assertDuration( + cal.dateUntil("1960-02-16", "2021-03-15", opt), + 61, 0, 0, 27, 0, 0, 0, 0, 0, 0, "61 years, 27 days in non leap year"); + TemporalHelpers.assertDuration( + cal.dateUntil("1960-02-16", "2020-03-15", opt), + 60, 0, 0, 28, 0, 0, 0, 0, 0, 0, "60 years, 28 days in leap year"); + + TemporalHelpers.assertDuration( + cal.dateUntil("2021-03-30", "2021-07-16", opt), + 0, 3, 0, 16, 0, 0, 0, 0, 0, 0, "3 months and 16 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2020-03-30", "2021-07-16", opt), + 1, 3, 0, 16, 0, 0, 0, 0, 0, 0, "1 year, 3 months and 16 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("1960-03-30", "2021-07-16", opt), + 61, 3, 0, 16, 0, 0, 0, 0, 0, 0, "61 years, 3 months and 16 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2019-12-30", "2021-07-16", opt), + 1, 6, 0, 16, 0, 0, 0, 0, 0, 0, "1 year, 6 months and 16 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2020-12-30", "2021-07-16", opt), + 0, 6, 0, 16, 0, 0, 0, 0, 0, 0, "6 months and 16 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("1997-12-30", "2021-07-16", opt), + 23, 6, 0, 16, 0, 0, 0, 0, 0, 0, "23 years, 6 months and 16 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("0001-12-25", "2021-07-16", opt), + 2019, 6, 0, 21, 0, 0, 0, 0, 0, 0, "2019 years, 6 months and 21 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2019-12-30", "2021-03-05", opt), + 1, 2, 0, 5, 0, 0, 0, 0, 0, 0, "1 year, 2 months and 5 days"); + + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-17", "2021-07-16", opt), + 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "negative one day"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-23", "2021-07-16", opt), + 0, 0, 0, -7, 0, 0, 0, 0, 0, 0, "negative 7 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-08-16", "2021-07-16", opt), + 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, "negative 1 month in same year"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-01-16", "2020-12-16", opt), + 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, "negative 1 month in different year"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-02-05", "2021-01-05", opt), + 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, "negative 1 month in same year"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-03-07", "2021-01-07", opt), + 0, -2, 0, 0, 0, 0, 0, 0, 0, 0, "negative 2 month in same year across Feb 28"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-08-17", "2021-07-16", opt), + 0, -1, 0, -1, 0, 0, 0, 0, 0, 0, "negative 1 month and 1 day in a month with 31 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-08-13", "2021-07-16", opt), + 0, 0, 0, -28, 0, 0, 0, 0, 0, 0, "negative 28 days roll across a month which has 31 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-09-16", "2021-07-16", opt), + 0, -2, 0, 0, 0, 0, 0, 0, 0, 0, "negative 2 months with both months which have 31 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2022-07-16", "2021-07-16", opt), + -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "negative 1 year"); + TemporalHelpers.assertDuration( + cal.dateUntil("2031-07-16", "2021-07-16", opt), + -10, 0, 0, 0, 0, 0, 0, 0, 0, 0, "negative 10 years"); + TemporalHelpers.assertDuration( + cal.dateUntil("2022-07-19", "2021-07-16", opt), + -1, 0, 0, -3, 0, 0, 0, 0, 0, 0, "negative 1 year and 3 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2022-09-19", "2021-07-16", opt), + -1, -2, 0, -3, 0, 0, 0, 0, 0, 0, "negative 1 year 2 months and 3 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2031-12-16", "2021-07-16", opt), + -10, -5, 0, 0, 0, 0, 0, 0, 0, 0, "negative 10 years and 5 months"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "1997-12-16", opt), + -23, -7, 0, 0, 0, 0, 0, 0, 0, 0, "negative 23 years and 7 months"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "1997-07-16", opt), + -24, 0, 0, 0, 0, 0, 0, 0, 0, 0, "negative 24 years"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-15", "1997-07-16", opt), + -23, -11, 0, -30, 0, 0, 0, 0, 0, 0, "negative 23 years, 11 months and 30 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-06-15", "1997-06-16", opt), + -23, -11, 0, -29, 0, 0, 0, 0, 0, 0, "negative 23 years, 11 months and 29 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2020-03-16", "1960-02-16", opt), + -60, -1, 0, 0, 0, 0, 0, 0, 0, 0, "negative 60 years, 1 month"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-03-15", "1960-02-16", opt), + -61, 0, 0, -28, 0, 0, 0, 0, 0, 0, "negative 61 years, 28 days in non leap year"); + TemporalHelpers.assertDuration( + cal.dateUntil("2020-03-15", "1960-02-16", opt), + -60, 0, 0, -28, 0, 0, 0, 0, 0, 0, "negative 60 years, 28 days in leap year"); + + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2021-03-30", opt), + 0, -3, 0, -17, 0, 0, 0, 0, 0, 0, "negative 3 months and 17 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2020-03-30", opt), + -1, -3, 0, -17, 0, 0, 0, 0, 0, 0, "negative 1 year, 3 months and 17 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "1960-03-30", opt), + -61, -3, 0, -17, 0, 0, 0, 0, 0, 0, "negative 61 years, 3 months and 17 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2019-12-30", opt), + -1, -6, 0, -17, 0, 0, 0, 0, 0, 0, "negative 1 year, 6 months and 17 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2020-12-30", opt), + 0, -6, 0, -17, 0, 0, 0, 0, 0, 0, "negative 6 months and 17 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "1997-12-30", opt), + -23, -6, 0, -17, 0, 0, 0, 0, 0, 0, "negative 23 years, 6 months and 17 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "0001-12-25", opt), + -2019, -6, 0, -22, 0, 0, 0, 0, 0, 0, "negative 2019 years, 6 months and 22 days"); + TemporalHelpers.assertDuration( + cal.dateUntil("2021-03-05", "2019-12-30", opt), + -1, -2, 0, -6, 0, 0, 0, 0, 0, 0, "negative 1 year, 2 months and 6 days"); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/largestunit-plurals-accepted.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/largestunit-plurals-accepted.js new file mode 100644 index 0000000000..6763066050 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/largestunit-plurals-accepted.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.calendar.prototype.dateuntil +description: Plural units are accepted as well for the largestUnit option +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const earlier = new Temporal.PlainDate(2000, 5, 2); +const later = new Temporal.PlainDate(2001, 6, 12); +const calendar = new Temporal.Calendar("iso8601"); +const validUnits = [ + "year", + "month", + "week", + "day", +]; +TemporalHelpers.checkPluralUnitsAccepted((largestUnit) => calendar.dateUntil(earlier, later, { largestUnit }), validUnits); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/leap-second.js new file mode 100644 index 0000000000..cd9435d73d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/leap-second.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.calendar.prototype.dateuntil +description: Leap second is a valid ISO string for PlainDate +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +let arg = "2016-12-31T23:59:60"; +let result = instance.dateUntil(arg, new Temporal.PlainDate(2017, 1, 1)); +TemporalHelpers.assertDuration(result, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "leap second is a valid ISO string for PlainDate (first argument)"); +result = instance.dateUntil(new Temporal.PlainDate(2017, 1, 1), arg); +TemporalHelpers.assertDuration(result, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "leap second is a valid ISO string for PlainDate (second argument)"); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +result = instance.dateUntil(arg, new Temporal.PlainDate(2017, 1, 1)); +TemporalHelpers.assertDuration(result, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "second: 60 is ignored in property bag for PlainDate (first argument)"); +result = instance.dateUntil(new Temporal.PlainDate(2017, 1, 1), arg); +TemporalHelpers.assertDuration(result, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "second: 60 is ignored in property bag for PlainDate (second argument)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/length.js new file mode 100644 index 0000000000..22d2b1063f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/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.calendar.prototype.dateuntil +description: Temporal.Calendar.prototype.dateUntil.length is 2 +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.Calendar.prototype.dateUntil, "length", { + value: 2, + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/name.js new file mode 100644 index 0000000000..7b3135ecc0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/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.calendar.prototype.dateuntil +description: Temporal.Calendar.prototype.dateUntil.name is "dateUntil". +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.Calendar.prototype.dateUntil, "name", { + value: "dateUntil", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/no-options.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/no-options.js new file mode 100644 index 0000000000..97e8ffde1b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/no-options.js @@ -0,0 +1,59 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dateuntil +description: Temporal.Calendar.prototype.dateUntil with no options +info: | + 1. Let calendar be the this value. + 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]). + 3. Assert: calendar.[[Identifier]] is "iso8601". + 4. Set one to ? ToTemporalDate(one). + 5. Set two to ? ToTemporalDate(two). + 6. Set options to ? GetOptionsObject(options). + 7. Let largestUnit be ? ToLargestTemporalUnit(options, « "hour", "minute", "second", "millisecond", "microsecond", "nanosecond" », "auto", "day"). + 8. Let result be ! DifferenceISODate(one.[[ISOYear]], one.[[ISOMonth]], one.[[ISODay]], two.[[ISOYear]], two.[[ISOMonth]], two.[[ISODay]], largestUnit). + 9. Return ? CreateTemporalDuration(result.[[Years]], result.[[Months]], result.[[Weeks]], result.[[Days]], 0, 0, 0, 0, 0, 0). +features: [Temporal] +includes: [temporalHelpers.js] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2021-07-16"), + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "same day"); +TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2021-07-17"), + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "one day"); +TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2021-08-17"), + 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, "32 days"); +TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2021-09-16"), + 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, "62 days"); +TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2022-07-16"), + 0, 0, 0, 365, 0, 0, 0, 0, 0, 0, "365 days"); +TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-16", "2031-07-16"), + 0, 0, 0, 3652, 0, 0, 0, 0, 0, 0, "3652 days"); + + +TemporalHelpers.assertDuration( + cal.dateUntil("2021-07-17", "2021-07-16"), + 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "negative one day"); +TemporalHelpers.assertDuration( + cal.dateUntil("2021-08-17", "2021-07-16"), + 0, 0, 0, -32, 0, 0, 0, 0, 0, 0, "negative 32 days"); +TemporalHelpers.assertDuration( + cal.dateUntil("2021-09-16", "2021-07-16"), + 0, 0, 0, -62, 0, 0, 0, 0, 0, 0, "negative 62 days"); +TemporalHelpers.assertDuration( + cal.dateUntil("2022-07-16", "2021-07-16"), + 0, 0, 0, -365, 0, 0, 0, 0, 0, 0, "negative 365 days"); +TemporalHelpers.assertDuration( + cal.dateUntil("2031-07-16", "2021-07-16"), + 0, 0, 0, -3652, 0, 0, 0, 0, 0, 0, "negative 3652 days"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/not-a-constructor.js new file mode 100644 index 0000000000..c3b14a2f28 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/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.calendar.prototype.dateuntil +description: > + Temporal.Calendar.prototype.dateUntil 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.Calendar.prototype.dateUntil(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.Calendar.prototype.dateUntil), false, + "isConstructor(Temporal.Calendar.prototype.dateUntil)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/options-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/options-object.js new file mode 100644 index 0000000000..b13ec09df5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/options-object.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.calendar.prototype.dateuntil +description: Empty or a function object may be used as options +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const result1 = instance.dateUntil(new Temporal.PlainDate(1976, 11, 18), new Temporal.PlainDate(1984, 5, 31), {}); +TemporalHelpers.assertDuration( + result1, 0, 0, 0, 2751, 0, 0, 0, 0, 0, 0, + "options may be an empty plain object" +); + +const result2 = instance.dateUntil(new Temporal.PlainDate(1976, 11, 18), new Temporal.PlainDate(1984, 5, 31), () => {}); +TemporalHelpers.assertDuration( + result2, 0, 0, 0, 2751, 0, 0, 0, 0, 0, 0, + "options may be a function object" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/options-wrong-type.js new file mode 100644 index 0000000000..deb5807e24 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/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.calendar.prototype.dateuntil +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.Calendar("iso8601"); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.dateUntil(new Temporal.PlainDate(1976, 11, 18), new Temporal.PlainDate(1984, 5, 31), value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/order-of-operations.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/order-of-operations.js new file mode 100644 index 0000000000..f613485222 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/order-of-operations.js @@ -0,0 +1,87 @@ +// |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.calendar.prototype.dateuntil +description: Properties on an object passed to dateUntil() are accessed in the correct order +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + // ToTemporalDate 1 → GetTemporalCalendarWithISODefault + "get one.calendar", + "has one.calendar.calendar", + // ToTemporalDate 1 → CalendarFields + "get one.calendar.fields", + "call one.calendar.fields", + // ToTemporalDate 1 → PrepareTemporalFields + "get one.day", + "get one.day.valueOf", + "call one.day.valueOf", + "get one.month", + "get one.month.valueOf", + "call one.month.valueOf", + "get one.monthCode", + "get one.monthCode.toString", + "call one.monthCode.toString", + "get one.year", + "get one.year.valueOf", + "call one.year.valueOf", + // ToTemporalDate 1 → CalendarDateFromFields + "get one.calendar.dateFromFields", + "call one.calendar.dateFromFields", + // ToTemporalDate 2 → GetTemporalCalendarWithISODefault + "get two.calendar", + "has two.calendar.calendar", + // ToTemporalDate 2 → CalendarFields + "get two.calendar.fields", + "call two.calendar.fields", + // ToTemporalDate 2 → PrepareTemporalFields + "get two.day", + "get two.day.valueOf", + "call two.day.valueOf", + "get two.month", + "get two.month.valueOf", + "call two.month.valueOf", + "get two.monthCode", + "get two.monthCode.toString", + "call two.monthCode.toString", + "get two.year", + "get two.year.valueOf", + "call two.year.valueOf", + // ToTemporalDate 2 → CalendarDateFromFields + "get two.calendar.dateFromFields", + "call two.calendar.dateFromFields", + // GetTemporalUnit + "get options.largestUnit", + "get options.largestUnit.toString", + "call options.largestUnit.toString", +]; +const actual = []; + +const instance = new Temporal.Calendar("iso8601"); + +const one = TemporalHelpers.propertyBagObserver(actual, { + year: 2000, + month: 5, + monthCode: "M05", + day: 2, + calendar: TemporalHelpers.calendarObserver(actual, "one.calendar"), +}, "one"); + +const two = TemporalHelpers.propertyBagObserver(actual, { + year: 2001, + month: 10, + monthCode: "M10", + day: 4, + calendar: TemporalHelpers.calendarObserver(actual, "two.calendar"), +}, "two"); + +const options = TemporalHelpers.propertyBagObserver(actual, { largestUnit: "day" }, "options"); + +instance.dateUntil(one, two, options); +assert.compareArray(actual, expected, "order of operations"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/prop-desc.js new file mode 100644 index 0000000000..96f6e8f8df --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/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.calendar.prototype.dateuntil +description: The "dateUntil" property of Temporal.Calendar.prototype +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.Calendar.prototype.dateUntil, + "function", + "`typeof Calendar.prototype.dateUntil` is `function`" +); + +verifyProperty(Temporal.Calendar.prototype, "dateUntil", { + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/shell.js new file mode 100644 index 0000000000..eda1477282 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/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/Calendar/prototype/dateUntil/throws-range-error-ToLargestTemporalUnit.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/throws-range-error-ToLargestTemporalUnit.js new file mode 100644 index 0000000000..257f3f1d96 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/throws-range-error-ToLargestTemporalUnit.js @@ -0,0 +1,20 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dateuntil +description: Temporal.Calendar.prototype.dateUntil throw RangeError on ToLargestTemporalUnit with invalide or disallowed unit +info: | + 7. Let largestUnit be ? ToLargestTemporalUnit(options, « "hour", "minute", "second", "millisecond", "microsecond", "nanosecond" », "auto", "day"). +features: [Temporal, arrow-function] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +["invalid", "hour", "minute", "second", "millisecond", "microsecond", + "nanosecond"].forEach(function(largestUnit) { + assert.throws(RangeError, () => cal.dateUntil("2021-07-16", "2022-03-04", {largestUnit}), + 'cal.dateUntil("2021-07-16", "2022-03-04", {largestUnit}) throws a RangeError exception'); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/throws-range-error-ToTemporalDate.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/throws-range-error-ToTemporalDate.js new file mode 100644 index 0000000000..571e1da479 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/throws-range-error-ToTemporalDate.js @@ -0,0 +1,21 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dateuntil +description: Temporal.Calendar.prototype.dateUntil throw RangeError on ToTemporalDate +info: | + 1. Let calendar be the this value. + 4. Set one to ? ToTemporalDate(one). + 5. Set two to ? ToTemporalDate(two). +features: [Temporal, arrow-function] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +assert.throws(RangeError, () => cal.dateUntil("2021-07-16", "invalide date"), + 'cal.dateUntil("2021-07-16", "invalide date") throws a RangeError exception'); +assert.throws(RangeError, () => cal.dateUntil("invalide date", "2021-07-16"), + 'cal.dateUntil("invalide date", "2021-07-16") throws a RangeError exception'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/throws-type-error-GetOptionsObject.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/throws-type-error-GetOptionsObject.js new file mode 100644 index 0000000000..058f714074 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/throws-type-error-GetOptionsObject.js @@ -0,0 +1,21 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-temporal.calendar.prototype.dateuntil +description: Temporal.Calendar.prototype.dateUntil throw TypeError on GetOptionsObject +info: | + 6. Set options to ? GetOptionsObject(options). +features: [BigInt, Symbol, Temporal, arrow-function] +---*/ +let cal = new Temporal.Calendar('iso8601'); + +['string', null, true, false, 123, 456n, Symbol(), Infinity, NaN].forEach(function(opt) { + assert.throws( + TypeError, + () => cal.dateUntil('2021-07-16', '2021-08-11', opt), + 'cal.dateUntil("2021-07-16", "2021-08-11", opt) throws a TypeError exception' + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/year-zero.js new file mode 100644 index 0000000000..085e0717cf --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/year-zero.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.calendar.prototype.dateuntil +description: Negative zero, as extended year, is invalid +features: [Temporal] +---*/ + +const calendar = new Temporal.Calendar("iso8601"); +const date = new Temporal.PlainDate(2000, 5, 2); +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; + +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => calendar.dateUntil(arg, date), + "cannot use minus zero as extended date (first argument)" + ); + + assert.throws( + RangeError, + () => calendar.dateUntil(date, arg), + "cannot use minus zero as extended date (second argument)" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-calendar-datefromfields-called-with-null-prototype-fields.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-calendar-datefromfields-called-with-null-prototype-fields.js new file mode 100644 index 0000000000..0952062b0d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-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.calendar.prototype.day +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.Calendar("iso8601"); +const arg = { year: 2000, month: 5, day: 2, calendar }; +instance.day(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/Calendar/prototype/day/argument-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-leap-second.js new file mode 100644 index 0000000000..5438835f5a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-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.calendar.prototype.day +description: Leap second is a valid ISO string for PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.day(arg); +assert.sameValue( + result1, + 31, + "leap second is a valid ISO string for PlainDate" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.day(arg); +assert.sameValue( + result2, + 31, + "second: 60 is ignored in property bag for PlainDate" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-number.js new file mode 100644 index 0000000000..0d32a0c922 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/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.calendar.prototype.day +description: A number is converted to a string, then to Temporal.PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const arg = 19761118; + +const result = instance.day(arg); +assert.sameValue(result, 18, "19761118 is a valid ISO string for PlainDate"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.day(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-case-insensitive.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-case-insensitive.js new file mode 100644 index 0000000000..aee9a21aef --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/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.calendar.prototype.day +description: The calendar name is case-insensitive +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "IsO8601"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.day(arg); +assert.sameValue(result1, 18, "Calendar is case-insensitive"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.day(arg); +assert.sameValue(result2, 18, "Calendar is case-insensitive (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-instance-does-not-get-calendar-property.js new file mode 100644 index 0000000000..776c1a1f11 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/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.calendar.prototype.day +description: > + A Temporal.Calendar instance passed to day() in a property bag does + not have its 'calendar' property observably checked +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +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.day(arg); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +instance.day(arg); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-leap-second.js new file mode 100644 index 0000000000..e44efd899d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/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.calendar.prototype.day +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.day(arg); +assert.sameValue( + result1, + 18, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.day(arg); +assert.sameValue( + result2, + 18, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-number.js new file mode 100644 index 0000000000..d20d595da5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/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.calendar.prototype.day +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.day(arg); +assert.sameValue(result1, 18, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.day(arg); +assert.sameValue(result2, 18, "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.day(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.day(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/Calendar/prototype/day/argument-propertybag-calendar-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-string.js new file mode 100644 index 0000000000..0be67a04be --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/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.calendar.prototype.day +description: A calendar ID is valid input for Calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "iso8601"; + +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.day(arg); +assert.sameValue(result, 18, `Calendar created from string "${calendar}"`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 0000000000..e74f0884f7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/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.calendar.prototype.day +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.Calendar("iso8601"); + +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.day(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.day(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.day(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.day(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.day(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-year-zero.js new file mode 100644 index 0000000000..7a29209bce --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/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.calendar.prototype.day +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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.day(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-calendar-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-calendar-annotation.js new file mode 100644 index 0000000000..462d131285 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/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.calendar.prototype.day +description: Various forms of calendar annotation; critical flag has no effect +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02[u-ca=iso8601]", "without time or time zone"], + ["2000-05-02[UTC][u-ca=iso8601]", "with time zone and no time"], + ["2000-05-02T15:23[u-ca=iso8601]", "without time zone"], + ["2000-05-02T15:23[UTC][u-ca=iso8601]", "with time zone"], + ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], + ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], + ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], + ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.day(arg); + + assert.sameValue( + result, + 2, + `calendar annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-critical-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-critical-unknown-annotation.js new file mode 100644 index 0000000000..c5665b5833 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-critical-unknown-annotation.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.calendar.prototype.day +description: Unknown annotations with critical flag are rejected +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[!foo=bar]", + "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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.day(arg), + `reject unknown annotation with critical flag: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-date-with-utc-offset.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-date-with-utc-offset.js new file mode 100644 index 0000000000..581dd0ae01 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/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.calendar.prototype.day +description: UTC offset not valid with format that does not include a time +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const validStrings = [ + "2000-05-02T00+00:00", + "2000-05-02T00+00:00[UTC]", + "2000-05-02T00+00:00[!UTC]", + "2000-05-02T00-02:30[America/St_Johns]", +]; + +for (const arg of validStrings) { + const result = instance.day(arg); + + assert.sameValue( + result, + 2, + `"${arg}" is a valid UTC offset with time for PlainDate` + ); +} + +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.day(arg), + `"${arg}" UTC offset without time is not valid for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-invalid.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-invalid.js new file mode 100644 index 0000000000..38e12423ab --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-invalid.js @@ -0,0 +1,64 @@ +// |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.calendar.prototype.day +description: > + RangeError thrown if an invalid ISO string (or syntactically valid ISO string + that is not supported) is used as a PlainDate +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + // invalid ISO strings: + "", + "invalid iso8601", + "2020-01-00", + "2020-01-32", + "2020-02-30", + "2021-02-29", + "2020-00-01", + "2020-13-01", + "2020-01-01T", + "2020-01-01T25:00:00", + "2020-01-01T01:60:00", + "2020-01-01T01:60:61", + "2020-01-01junk", + "2020-01-01T00:00:00junk", + "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-01", + "2020-001-01", + "2020-01-001", + "2020-01-01T001", + "2020-01-01T01:001", + "2020-01-01T01:01:001", + // valid, but forms not supported in Temporal: + "2020-W01-1", + "2020-001", + "+0002020-01-01", + // valid, but this calendar must not exist: + "2020-01-01[u-ca=notexist]", + // may be valid in other contexts, but insufficient information for PlainDate: + "2020-01", + "+002020-01", + "01-01", + "2020-W01", + "P1Y", + "-P12Y", + // valid, but outside the supported range: + "-999999-01-01", + "+999999-01-01", +]; +const instance = new Temporal.Calendar("iso8601"); +for (const arg of invalidStrings) { + assert.throws( + RangeError, + () => instance.day(arg), + `"${arg}" should not be a valid ISO string for a PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-multiple-time-zone.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-multiple-time-zone.js new file mode 100644 index 0000000000..76daebf1bc --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-multiple-time-zone.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.calendar.prototype.day +description: More than one time zone annotation is not syntactical +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[UTC][UTC]", + "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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.day(arg), + `reject more than one time zone annotation: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-time-separators.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-time-separators.js new file mode 100644 index 0000000000..e5bcbdbccb --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/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.calendar.prototype.day +description: Time separator in string argument can vary +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02T15:23", "uppercase T"], + ["2000-05-02t15:23", "lowercase T"], + ["2000-05-02 15:23", "space between date and time"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.day(arg); + + assert.sameValue( + result, + 2, + `variant time separators (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-time-zone-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-time-zone-annotation.js new file mode 100644 index 0000000000..188484b2ac --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-time-zone-annotation.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.calendar.prototype.day +description: Various forms of time zone annotation; critical flag has no effect +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02[Asia/Kolkata]", "named, with no time"], + ["2000-05-02[!Europe/Vienna]", "named, with ! and no time"], + ["2000-05-02[+00:00]", "numeric, with no time"], + ["2000-05-02[!-02:30]", "numeric, with ! and no time"], + ["2000-05-02T15:23[America/Sao_Paulo]", "named, with no offset"], + ["2000-05-02T15:23[!Asia/Tokyo]", "named, with ! and no offset"], + ["2000-05-02T15:23[-02:30]", "numeric, with no offset"], + ["2000-05-02T15:23[!+00:00]", "numeric, with ! and no offset"], + ["2000-05-02T15:23+00:00[America/New_York]", "named, with offset"], + ["2000-05-02T15:23+00:00[!UTC]", "named, with offset and !"], + ["2000-05-02T15:23+00:00[+01:00]", "numeric, with offset"], + ["2000-05-02T15:23+00:00[!-08:00]", "numeric, with offset and !"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.day(arg); + + assert.sameValue( + result, + 2, + `time zone annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-unknown-annotation.js new file mode 100644 index 0000000000..b3c54bd07b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/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.calendar.prototype.day +description: Various forms of unknown annotation +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02[foo=bar]", "without time"], + ["2000-05-02T15:23[foo=bar]", "alone"], + ["2000-05-02T15:23[UTC][foo=bar]", "with time zone"], + ["2000-05-02T15:23[u-ca=iso8601][foo=bar]", "with calendar"], + ["2000-05-02T15:23[UTC][foo=bar][u-ca=iso8601]", "with time zone and calendar"], + ["2000-05-02T15:23[foo=bar][_foo-bar0=Ignore-This-999999999999]", "with another unknown annotation"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.day(arg); + + assert.sameValue( + result, + 2, + `unknown annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-with-utc-designator.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-with-utc-designator.js new file mode 100644 index 0000000000..6771a5c5b4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/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.calendar.prototype.day +description: RangeError thrown if a string with UTC designator is used as a PlainDate +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "2019-10-01T09:00:00Z", + "2019-10-01T09:00:00Z[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.day(arg), + "String with UTC designator should not be valid as a PlainDate" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-wrong-type.js new file mode 100644 index 0000000000..0644cf7cca --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/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.calendar.prototype.day +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +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.day(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.day(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/Calendar/prototype/day/argument-zoneddatetime-convert.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-zoneddatetime-convert.js new file mode 100644 index 0000000000..2847e14ab1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-zoneddatetime-convert.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.calendar.prototype.day +description: An exception from TimeZone#getOffsetNanosecondsFor() is propagated. +features: [Temporal] +---*/ + +class TZ extends Temporal.TimeZone { + constructor() { super("UTC") } + getOffsetNanosecondsFor() { throw new Test262Error() } +} + +const tz = new TZ(); +const arg = new Temporal.ZonedDateTime(0n, tz); +const instance = new Temporal.Calendar("iso8601"); + +assert.throws(Test262Error, () => instance.day(arg)); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-zoneddatetime-slots.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-zoneddatetime-slots.js new file mode 100644 index 0000000000..03e7e2b6f3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-zoneddatetime-slots.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.calendar.prototype.day +description: Getters are not called when converting a ZonedDateTime to a PlainDate. +includes: [compareArray.js] +features: [Temporal] +---*/ + +const actual = []; +const prototypeDescrs = Object.getOwnPropertyDescriptors(Temporal.ZonedDateTime.prototype); +const getters = ["year", "month", "monthCode", "day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond", "calendar"]; + +for (const property of getters) { + Object.defineProperty(Temporal.ZonedDateTime.prototype, property, { + get() { + actual.push(`get ${property}`); + const value = prototypeDescrs[property].get.call(this); + return { + toString() { + actual.push(`toString ${property}`); + return value.toString(); + }, + valueOf() { + actual.push(`valueOf ${property}`); + return value; + }, + }; + }, + }); +} + +const arg = new Temporal.ZonedDateTime(0n, "UTC"); +const instance = new Temporal.Calendar("iso8601"); +instance.day(arg); +assert.compareArray(actual, []); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js new file mode 100644 index 0000000000..f0416d816f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/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.calendar.prototype.day +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(RangeError, () => calendar.day(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js new file mode 100644 index 0000000000..dc5d032d27 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/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.calendar.prototype.day +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + timeZone.getOffsetNanosecondsFor = notCallable; + assert.throws( + TypeError, + () => calendar.day(datetime), + `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js new file mode 100644 index 0000000000..fbfb9248e6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/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.calendar.prototype.day +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(RangeError, () => calendar.day(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js new file mode 100644 index 0000000000..da2d674f18 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/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.calendar.prototype.day +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(TypeError, () => calendar.day(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/basic.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/basic.js new file mode 100644 index 0000000000..8824d7edd2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/basic.js @@ -0,0 +1,20 @@ +// |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.calendar.prototype.day +description: Basic tests for day(). +features: [Temporal] +---*/ + +const iso = Temporal.Calendar.from("iso8601"); +const res = 5; +assert.sameValue(iso.day(Temporal.PlainDate.from("1994-11-05")), res, "PlainDate"); +assert.sameValue(iso.day(Temporal.PlainDateTime.from("1994-11-05T08:15:30")), res, "PlainDateTime"); +assert.sameValue(iso.day(Temporal.PlainMonthDay.from("11-05")), res, "PlainMonthDay"); +assert.sameValue(iso.day({ year: 1994, month: 11, day: 5 }), res, "property bag"); +assert.sameValue(iso.day("1994-11-05"), res, "string"); +assert.throws(TypeError, () => iso.day({ year: 2000 }), "property bag with missing properties"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/branding.js new file mode 100644 index 0000000000..2ed97c1d31 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/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.calendar.prototype.day +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const day = Temporal.Calendar.prototype.day; + +assert.sameValue(typeof day, "function"); + +const args = [new Temporal.PlainDate(2000, 1, 1)]; + +assert.throws(TypeError, () => day.apply(undefined, args), "undefined"); +assert.throws(TypeError, () => day.apply(null, args), "null"); +assert.throws(TypeError, () => day.apply(true, args), "true"); +assert.throws(TypeError, () => day.apply("", args), "empty string"); +assert.throws(TypeError, () => day.apply(Symbol(), args), "symbol"); +assert.throws(TypeError, () => day.apply(1, args), "1"); +assert.throws(TypeError, () => day.apply({}, args), "plain object"); +assert.throws(TypeError, () => day.apply(Temporal.Calendar, args), "Temporal.Calendar"); +assert.throws(TypeError, () => day.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/builtin.js new file mode 100644 index 0000000000..f3a6ae8533 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/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.calendar.prototype.day +description: > + Tests that Temporal.Calendar.prototype.day + 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.Calendar.prototype.day), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.day), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.day), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.Calendar.prototype.day.hasOwnProperty("prototype"), + false, "prototype property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/calendar-datefromfields-called-with-options-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/calendar-datefromfields-called-with-options-undefined.js new file mode 100644 index 0000000000..496d6af5ac --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/calendar-datefromfields-called-with-options-undefined.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.calendar.prototype.day +description: > + Calendar.dateFromFields method is called with undefined as the options value + when call originates internally +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = TemporalHelpers.calendarFromFieldsUndefinedOptions(); +calendar.day({ year: 2000, month: 5, day: 3, calendar }); +assert.sameValue(calendar.dateFromFieldsCallCount, 1); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/calendar-fields-iterable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/calendar-fields-iterable.js new file mode 100644 index 0000000000..878618d19f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/calendar-fields-iterable.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.calendar.prototype.day +description: Verify the result of calendar.fields() is treated correctly. +info: | + sec-temporal.calendar.prototype.day step 4: + 4. Return ? ISODay(_dateOrDateTime_). + sec-temporal-isoday step 1.a: + a. Set _dateOrDateTime_ to ? ToTemporalDate(_dateOrDateTime_). + sec-temporal-totemporaldate step 2.c: + c. Let _fieldNames_ be ? CalendarFields(calendar, « *"day"*, *"month"*, *"monthCode"*, *"year"* »). + sec-temporal-calendarfields step 4: + 4. Let _result_ be ? IterableToListOfType(_fieldsArray_, « String »). +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + "day", + "month", + "monthCode", + "year", +]; + +const calendar1 = TemporalHelpers.calendarFieldsIterable(); +const calendar2 = TemporalHelpers.calendarFieldsIterable(); +calendar1.day({ year: 2000, month: 5, day: 2, calendar: calendar2 }); + +assert.sameValue(calendar1.fieldsCallCount, 0, "fields() method not called"); +assert.sameValue(calendar2.fieldsCallCount, 1, "fields() method called once"); +assert.compareArray(calendar2.fieldsCalledWith[0], expected, "fields() method called with correct args"); +assert(calendar2.iteratorExhausted[0], "iterated through the whole iterable"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/calendar-temporal-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/calendar-temporal-object.js new file mode 100644 index 0000000000..2f6a3c6820 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/calendar-temporal-object.js @@ -0,0 +1,31 @@ +// |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.calendar.prototype.day +description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots +info: | + sec-temporal.calendar.prototype.day step 4: + 4. Return ? ISODay(_dateOrDateTime_). + sec-temporal-isoday step 1.a: + a. Set _dateOrDateTime_ to ? ToTemporalDate(_dateOrDateTime_). + sec-temporal-totemporaldate 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 calendar = new Temporal.Calendar("iso8601"); + calendar.day({ year: 2000, month: 5, day: 2, calendar: temporalObject }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/date-time.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/date-time.js new file mode 100644 index 0000000000..469b7baa5a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/date-time.js @@ -0,0 +1,19 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.day +description: > + Temporal.Calendar.prototype.day will take PlainDateTime and return + the value of the day. +info: | + 5. Return ! ISODay(temporalDateLike). +features: [Temporal] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +let dateTime = new Temporal.PlainDateTime(1997, 8, 23, 5, 30, 13) +assert.sameValue(cal.day(dateTime), 23, 'cal.day(new Temporal.PlainDateTime(1997, 8, 23, 5, 30, 13)) must return 23'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/date.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/date.js new file mode 100644 index 0000000000..35840d9e5b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/date.js @@ -0,0 +1,19 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.day +description: > + Temporal.Calendar.prototype.day will take PlainDate and return + the value of the day. +info: | + 5. Return ! ISODay(temporalDateLike). +features: [Temporal] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +let date = new Temporal.PlainDate(2021, 7, 15); +assert.sameValue(cal.day(date), 15, 'cal.day(new Temporal.PlainDate(2021, 7, 15)) must return 15'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/infinity-throws-rangeerror.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/infinity-throws-rangeerror.js new file mode 100644 index 0000000000..65411f306d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/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.calendar.prototype.day +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); +const base = { year: 2000, month: 5, day: 2 }; + +[Infinity, -Infinity].forEach((inf) => { + ["year", "month", "day"].forEach((prop) => { + assert.throws(RangeError, () => instance.day({ ...base, [prop]: inf }), `${prop} property cannot be ${inf}`); + + const calls = []; + const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop); + assert.throws(RangeError, () => instance.day({ ...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/Calendar/prototype/day/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/length.js new file mode 100644 index 0000000000..775613ee78 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/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.calendar.prototype.day +description: Temporal.Calendar.prototype.day.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.Calendar.prototype.day, "length", { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/month-day.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/month-day.js new file mode 100644 index 0000000000..b39787e931 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/month-day.js @@ -0,0 +1,23 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.day +description: > + Temporal.Calendar.prototype.day will take PlainMonthDay and return + the value of the day. +info: | + 4. If Type(temporalDateLike) is not Object or temporalDateLike does not have + an [[InitializedTemporalDate]] or [[InitializedTemporalYearMonth]] internal + slot, then + a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike). + 5. Return ! ISODay(temporalDateLike). +features: [Temporal] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +let monthDay = new Temporal.PlainMonthDay(7, 15); +assert.sameValue(cal.day(monthDay), 15, 'cal.day(new Temporal.PlainMonthDay(7, 15)) must return 15'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/name.js new file mode 100644 index 0000000000..0c8d624505 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/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.calendar.prototype.day +description: Temporal.Calendar.prototype.day.name is "day". +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.Calendar.prototype.day, "name", { + value: "day", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/not-a-constructor.js new file mode 100644 index 0000000000..fe3072332d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/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.calendar.prototype.day +description: > + Temporal.Calendar.prototype.day 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.Calendar.prototype.day(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.Calendar.prototype.day), false, + "isConstructor(Temporal.Calendar.prototype.day)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/prop-desc.js new file mode 100644 index 0000000000..78410ff8f4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/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.calendar.prototype.day +description: The "day" property of Temporal.Calendar.prototype +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.Calendar.prototype.day, + "function", + "`typeof Calendar.prototype.day` is `function`" +); + +verifyProperty(Temporal.Calendar.prototype, "day", { + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/shell.js new file mode 100644 index 0000000000..eda1477282 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/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/Calendar/prototype/day/string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/string.js new file mode 100644 index 0000000000..9a958a8b93 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/string.js @@ -0,0 +1,22 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.day +description: > + Temporal.Calendar.prototype.day will take ISO8601 string and return + the value of the day. +info: | + 4. If Type(temporalDateLike) is not Object or temporalDateLike does not have + an [[InitializedTemporalDate]] or [[InitializedTemporalYearMonth]] internal + slot, then + a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike). + 5. Return ! ISODay(temporalDateLike). +features: [Temporal] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +assert.sameValue(cal.day("2019-03-15"), 15, 'cal.day("2019-03-15") must return 15'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/throw-range-error-ToTemporalDate.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/throw-range-error-ToTemporalDate.js new file mode 100644 index 0000000000..2a2d6fc025 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/throw-range-error-ToTemporalDate.js @@ -0,0 +1,22 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.day +description: > + Temporal.Calendar.prototype.day throws RangeError on + ToTemporalDate when temporalDateLike is invalid string. +info: | + 4. If Type(temporalDateLike) is not Object or temporalDateLike + does not have an [[InitializedTemporalDate]] or + [[InitializedTemporalYearMonth]] internal slot, then + a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike). +features: [Temporal, arrow-function] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +assert.throws(RangeError, () => cal.day("invalid string"), + 'cal.day("invalid string") throws a RangeError exception'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/year-zero.js new file mode 100644 index 0000000000..71c80d23f6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/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.calendar.prototype.day +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.day(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-calendar-datefromfields-called-with-null-prototype-fields.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-calendar-datefromfields-called-with-null-prototype-fields.js new file mode 100644 index 0000000000..9dab930f32 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-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.calendar.prototype.dayofweek +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.Calendar("iso8601"); +const arg = { year: 2000, month: 5, day: 2, calendar }; +instance.dayOfWeek(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/Calendar/prototype/dayOfWeek/argument-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-leap-second.js new file mode 100644 index 0000000000..31b44a6c82 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-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.calendar.prototype.dayofweek +description: Leap second is a valid ISO string for PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.dayOfWeek(arg); +assert.sameValue( + result1, + 6, + "leap second is a valid ISO string for PlainDate" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.dayOfWeek(arg); +assert.sameValue( + result2, + 6, + "second: 60 is ignored in property bag for PlainDate" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-number.js new file mode 100644 index 0000000000..f5f45225e3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/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.calendar.prototype.dayofweek +description: A number is converted to a string, then to Temporal.PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const arg = 19761118; + +const result = instance.dayOfWeek(arg); +assert.sameValue(result, 4, "19761118 is a valid ISO string for PlainDate"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.dayOfWeek(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-case-insensitive.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-case-insensitive.js new file mode 100644 index 0000000000..1cc4d0f280 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/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.calendar.prototype.dayofweek +description: The calendar name is case-insensitive +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "IsO8601"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.dayOfWeek(arg); +assert.sameValue(result1, 4, "Calendar is case-insensitive"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.dayOfWeek(arg); +assert.sameValue(result2, 4, "Calendar is case-insensitive (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-instance-does-not-get-calendar-property.js new file mode 100644 index 0000000000..0f088a9e92 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/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.calendar.prototype.dayofweek +description: > + A Temporal.Calendar instance passed to dayOfWeek() in a property bag does + not have its 'calendar' property observably checked +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +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.dayOfWeek(arg); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +instance.dayOfWeek(arg); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-leap-second.js new file mode 100644 index 0000000000..daa66528c1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/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.calendar.prototype.dayofweek +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.dayOfWeek(arg); +assert.sameValue( + result1, + 4, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.dayOfWeek(arg); +assert.sameValue( + result2, + 4, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-number.js new file mode 100644 index 0000000000..a939edc725 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/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.calendar.prototype.dayofweek +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.dayOfWeek(arg); +assert.sameValue(result1, 4, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.dayOfWeek(arg); +assert.sameValue(result2, 4, "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.dayOfWeek(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.dayOfWeek(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/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-string.js new file mode 100644 index 0000000000..432ae4a753 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/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.calendar.prototype.dayofweek +description: A calendar ID is valid input for Calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "iso8601"; + +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.dayOfWeek(arg); +assert.sameValue(result, 4, `Calendar created from string "${calendar}"`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 0000000000..20d252c371 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/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.calendar.prototype.dayofweek +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.Calendar("iso8601"); + +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.dayOfWeek(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.dayOfWeek(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.dayOfWeek(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.dayOfWeek(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.dayOfWeek(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-year-zero.js new file mode 100644 index 0000000000..0c0012006c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/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.calendar.prototype.dayofweek +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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.dayOfWeek(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-calendar-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-calendar-annotation.js new file mode 100644 index 0000000000..a4fa3d0abe --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/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.calendar.prototype.dayofweek +description: Various forms of calendar annotation; critical flag has no effect +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02[u-ca=iso8601]", "without time or time zone"], + ["2000-05-02[UTC][u-ca=iso8601]", "with time zone and no time"], + ["2000-05-02T15:23[u-ca=iso8601]", "without time zone"], + ["2000-05-02T15:23[UTC][u-ca=iso8601]", "with time zone"], + ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], + ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], + ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], + ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.dayOfWeek(arg); + + assert.sameValue( + result, + 2, + `calendar annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-critical-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-critical-unknown-annotation.js new file mode 100644 index 0000000000..a9b359a0e0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-critical-unknown-annotation.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.calendar.prototype.dayofweek +description: Unknown annotations with critical flag are rejected +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[!foo=bar]", + "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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.dayOfWeek(arg), + `reject unknown annotation with critical flag: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-date-with-utc-offset.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-date-with-utc-offset.js new file mode 100644 index 0000000000..7929f5ddc4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/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.calendar.prototype.dayofweek +description: UTC offset not valid with format that does not include a time +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const validStrings = [ + "2000-05-02T00+00:00", + "2000-05-02T00+00:00[UTC]", + "2000-05-02T00+00:00[!UTC]", + "2000-05-02T00-02:30[America/St_Johns]", +]; + +for (const arg of validStrings) { + const result = instance.dayOfWeek(arg); + + assert.sameValue( + result, + 2, + `"${arg}" is a valid UTC offset with time for PlainDate` + ); +} + +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.dayOfWeek(arg), + `"${arg}" UTC offset without time is not valid for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-invalid.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-invalid.js new file mode 100644 index 0000000000..281f911713 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-invalid.js @@ -0,0 +1,64 @@ +// |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.calendar.prototype.dayofweek +description: > + RangeError thrown if an invalid ISO string (or syntactically valid ISO string + that is not supported) is used as a PlainDate +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + // invalid ISO strings: + "", + "invalid iso8601", + "2020-01-00", + "2020-01-32", + "2020-02-30", + "2021-02-29", + "2020-00-01", + "2020-13-01", + "2020-01-01T", + "2020-01-01T25:00:00", + "2020-01-01T01:60:00", + "2020-01-01T01:60:61", + "2020-01-01junk", + "2020-01-01T00:00:00junk", + "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-01", + "2020-001-01", + "2020-01-001", + "2020-01-01T001", + "2020-01-01T01:001", + "2020-01-01T01:01:001", + // valid, but forms not supported in Temporal: + "2020-W01-1", + "2020-001", + "+0002020-01-01", + // valid, but this calendar must not exist: + "2020-01-01[u-ca=notexist]", + // may be valid in other contexts, but insufficient information for PlainDate: + "2020-01", + "+002020-01", + "01-01", + "2020-W01", + "P1Y", + "-P12Y", + // valid, but outside the supported range: + "-999999-01-01", + "+999999-01-01", +]; +const instance = new Temporal.Calendar("iso8601"); +for (const arg of invalidStrings) { + assert.throws( + RangeError, + () => instance.dayOfWeek(arg), + `"${arg}" should not be a valid ISO string for a PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-multiple-time-zone.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-multiple-time-zone.js new file mode 100644 index 0000000000..15856d3841 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-multiple-time-zone.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.calendar.prototype.dayofweek +description: More than one time zone annotation is not syntactical +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[UTC][UTC]", + "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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.dayOfWeek(arg), + `reject more than one time zone annotation: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-time-separators.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-time-separators.js new file mode 100644 index 0000000000..a1a841e832 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/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.calendar.prototype.dayofweek +description: Time separator in string argument can vary +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02T15:23", "uppercase T"], + ["2000-05-02t15:23", "lowercase T"], + ["2000-05-02 15:23", "space between date and time"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.dayOfWeek(arg); + + assert.sameValue( + result, + 2, + `variant time separators (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-time-zone-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-time-zone-annotation.js new file mode 100644 index 0000000000..c5560d6715 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-time-zone-annotation.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.calendar.prototype.dayofweek +description: Various forms of time zone annotation; critical flag has no effect +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02[Asia/Kolkata]", "named, with no time"], + ["2000-05-02[!Europe/Vienna]", "named, with ! and no time"], + ["2000-05-02[+00:00]", "numeric, with no time"], + ["2000-05-02[!-02:30]", "numeric, with ! and no time"], + ["2000-05-02T15:23[America/Sao_Paulo]", "named, with no offset"], + ["2000-05-02T15:23[!Asia/Tokyo]", "named, with ! and no offset"], + ["2000-05-02T15:23[-02:30]", "numeric, with no offset"], + ["2000-05-02T15:23[!+00:00]", "numeric, with ! and no offset"], + ["2000-05-02T15:23+00:00[America/New_York]", "named, with offset"], + ["2000-05-02T15:23+00:00[!UTC]", "named, with offset and !"], + ["2000-05-02T15:23+00:00[+01:00]", "numeric, with offset"], + ["2000-05-02T15:23+00:00[!-08:00]", "numeric, with offset and !"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.dayOfWeek(arg); + + assert.sameValue( + result, + 2, + `time zone annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-unknown-annotation.js new file mode 100644 index 0000000000..ad8b0e3689 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/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.calendar.prototype.dayofweek +description: Various forms of unknown annotation +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02[foo=bar]", "without time"], + ["2000-05-02T15:23[foo=bar]", "alone"], + ["2000-05-02T15:23[UTC][foo=bar]", "with time zone"], + ["2000-05-02T15:23[u-ca=iso8601][foo=bar]", "with calendar"], + ["2000-05-02T15:23[UTC][foo=bar][u-ca=iso8601]", "with time zone and calendar"], + ["2000-05-02T15:23[foo=bar][_foo-bar0=Ignore-This-999999999999]", "with another unknown annotation"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.dayOfWeek(arg); + + assert.sameValue( + result, + 2, + `unknown annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-with-utc-designator.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-with-utc-designator.js new file mode 100644 index 0000000000..8a363399fe --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/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.calendar.prototype.dayofweek +description: RangeError thrown if a string with UTC designator is used as a PlainDate +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "2019-10-01T09:00:00Z", + "2019-10-01T09:00:00Z[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.dayOfWeek(arg), + "String with UTC designator should not be valid as a PlainDate" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-wrong-type.js new file mode 100644 index 0000000000..f29edf6aae --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/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.calendar.prototype.dayofweek +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +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.dayOfWeek(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.dayOfWeek(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/Calendar/prototype/dayOfWeek/argument-zoneddatetime-convert.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-zoneddatetime-convert.js new file mode 100644 index 0000000000..9f28a7809a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-zoneddatetime-convert.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.calendar.prototype.dayofweek +description: An exception from TimeZone#getOffsetNanosecondsFor() is propagated. +features: [Temporal] +---*/ + +class TZ extends Temporal.TimeZone { + constructor() { super("UTC") } + getOffsetNanosecondsFor() { throw new Test262Error() } +} + +const tz = new TZ(); +const arg = new Temporal.ZonedDateTime(0n, tz); +const instance = new Temporal.Calendar("iso8601"); + +assert.throws(Test262Error, () => instance.dayOfWeek(arg)); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-zoneddatetime-slots.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-zoneddatetime-slots.js new file mode 100644 index 0000000000..a988baba9d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-zoneddatetime-slots.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.calendar.prototype.dayofweek +description: Getters are not called when converting a ZonedDateTime to a PlainDate. +includes: [compareArray.js] +features: [Temporal] +---*/ + +const actual = []; +const prototypeDescrs = Object.getOwnPropertyDescriptors(Temporal.ZonedDateTime.prototype); +const getters = ["year", "month", "monthCode", "day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond", "calendar"]; + +for (const property of getters) { + Object.defineProperty(Temporal.ZonedDateTime.prototype, property, { + get() { + actual.push(`get ${property}`); + const value = prototypeDescrs[property].get.call(this); + return { + toString() { + actual.push(`toString ${property}`); + return value.toString(); + }, + valueOf() { + actual.push(`valueOf ${property}`); + return value; + }, + }; + }, + }); +} + +const arg = new Temporal.ZonedDateTime(0n, "UTC"); +const instance = new Temporal.Calendar("iso8601"); +instance.dayOfWeek(arg); +assert.compareArray(actual, []); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js new file mode 100644 index 0000000000..8514f362e4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/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.calendar.prototype.dayofweek +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(RangeError, () => calendar.dayOfWeek(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js new file mode 100644 index 0000000000..5a78f2fc95 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/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.calendar.prototype.dayofweek +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + timeZone.getOffsetNanosecondsFor = notCallable; + assert.throws( + TypeError, + () => calendar.dayOfWeek(datetime), + `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js new file mode 100644 index 0000000000..66b71a4fd6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/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.calendar.prototype.dayofweek +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(RangeError, () => calendar.dayOfWeek(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js new file mode 100644 index 0000000000..d600914036 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/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.calendar.prototype.dayofweek +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(TypeError, () => calendar.dayOfWeek(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/basic.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/basic.js new file mode 100644 index 0000000000..e74758fa0e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/basic.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.calendar.prototype.dayofweek +description: Basic tests for dayOfWeek(). +features: [Temporal] +---*/ + +const iso = Temporal.Calendar.from("iso8601"); +const res = 6; +assert.sameValue(iso.dayOfWeek(Temporal.PlainDate.from("1994-11-05")), res, "PlainDate"); +assert.sameValue(iso.dayOfWeek(Temporal.PlainDateTime.from("1994-11-05T08:15:30")), res, "PlainDateTime"); +assert.sameValue(iso.dayOfWeek({ year: 1994, month: 11, day: 5 }), res, "property bag"); +assert.sameValue(iso.dayOfWeek("1994-11-05"), res, "string"); +assert.throws(TypeError, () => iso.dayOfWeek({ year: 2000 }), "property bag with missing properties"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/branding.js new file mode 100644 index 0000000000..3eb3a92638 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/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.calendar.prototype.dayofweek +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const dayOfWeek = Temporal.Calendar.prototype.dayOfWeek; + +assert.sameValue(typeof dayOfWeek, "function"); + +const args = [new Temporal.PlainDate(2000, 1, 1)]; + +assert.throws(TypeError, () => dayOfWeek.apply(undefined, args), "undefined"); +assert.throws(TypeError, () => dayOfWeek.apply(null, args), "null"); +assert.throws(TypeError, () => dayOfWeek.apply(true, args), "true"); +assert.throws(TypeError, () => dayOfWeek.apply("", args), "empty string"); +assert.throws(TypeError, () => dayOfWeek.apply(Symbol(), args), "symbol"); +assert.throws(TypeError, () => dayOfWeek.apply(1, args), "1"); +assert.throws(TypeError, () => dayOfWeek.apply({}, args), "plain object"); +assert.throws(TypeError, () => dayOfWeek.apply(Temporal.Calendar, args), "Temporal.Calendar"); +assert.throws(TypeError, () => dayOfWeek.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/builtin.js new file mode 100644 index 0000000000..bd31bbd744 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/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.calendar.prototype.dayofweek +description: > + Tests that Temporal.Calendar.prototype.dayOfWeek + 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.Calendar.prototype.dayOfWeek), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.dayOfWeek), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.dayOfWeek), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.Calendar.prototype.dayOfWeek.hasOwnProperty("prototype"), + false, "prototype property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/calendar-datefromfields-called-with-options-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/calendar-datefromfields-called-with-options-undefined.js new file mode 100644 index 0000000000..e79f8f7c68 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/calendar-datefromfields-called-with-options-undefined.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.calendar.prototype.dayofweek +description: > + Calendar.dateFromFields method is called with undefined as the options value + when call originates internally +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = TemporalHelpers.calendarFromFieldsUndefinedOptions(); +calendar.dayOfWeek({ year: 2000, month: 5, day: 3, calendar }); +assert.sameValue(calendar.dateFromFieldsCallCount, 1); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/calendar-fields-iterable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/calendar-fields-iterable.js new file mode 100644 index 0000000000..844511f854 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/calendar-fields-iterable.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.calendar.prototype.dayofweek +description: Verify the result of calendar.fields() is treated correctly. +info: | + sec-temporal.calendar.prototype.dayofweek step 4: + 4. Let _date_ be ? ToTemporalDate(_dateOrDateTime_). + sec-temporal-totemporaldate step 2.c: + c. Let _fieldNames_ be ? CalendarFields(_calendar_, « *"day"*, *"month"*, *"monthCode"*, *"year"* »). + sec-temporal-calendarfields step 4: + 4. Let _result_ be ? IterableToListOfType(_fieldsArray_, « String »). +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + "day", + "month", + "monthCode", + "year", +]; + +const calendar1 = TemporalHelpers.calendarFieldsIterable(); +const calendar2 = TemporalHelpers.calendarFieldsIterable(); +calendar1.dayOfWeek({ year: 2000, month: 5, day: 2, calendar: calendar2 }); + +assert.sameValue(calendar1.fieldsCallCount, 0, "fields() method not called"); +assert.sameValue(calendar2.fieldsCallCount, 1, "fields() method called once"); +assert.compareArray(calendar2.fieldsCalledWith[0], expected, "fields() method called with correct args"); +assert(calendar2.iteratorExhausted[0], "iterated through the whole iterable"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/calendar-temporal-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/calendar-temporal-object.js new file mode 100644 index 0000000000..a9f12061ee --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/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.calendar.prototype.dayofweek +description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots +info: | + sec-temporal.calendar.prototype.dayofweek step 4: + 4. Let _date_ be ? ToTemporalDate(_dateOrDateTime_). + sec-temporal-totemporaldate 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 calendar = new Temporal.Calendar("iso8601"); + calendar.dayOfWeek({ year: 2000, month: 5, day: 2, calendar: temporalObject }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/infinity-throws-rangeerror.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/infinity-throws-rangeerror.js new file mode 100644 index 0000000000..bf25784b40 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/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.calendar.prototype.dayofweek +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); +const base = { year: 2000, month: 5, day: 2 }; + +[Infinity, -Infinity].forEach((inf) => { + ["year", "month", "day"].forEach((prop) => { + assert.throws(RangeError, () => instance.dayOfWeek({ ...base, [prop]: inf }), `${prop} property cannot be ${inf}`); + + const calls = []; + const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop); + assert.throws(RangeError, () => instance.dayOfWeek({ ...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/Calendar/prototype/dayOfWeek/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/length.js new file mode 100644 index 0000000000..68bc41673e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/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.calendar.prototype.dayofweek +description: Temporal.Calendar.prototype.dayOfWeek.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.Calendar.prototype.dayOfWeek, "length", { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/name.js new file mode 100644 index 0000000000..eefb875e81 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/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.calendar.prototype.dayofweek +description: Temporal.Calendar.prototype.dayOfWeek.name is "dayOfWeek". +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.Calendar.prototype.dayOfWeek, "name", { + value: "dayOfWeek", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/not-a-constructor.js new file mode 100644 index 0000000000..53f48cf4e2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/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.calendar.prototype.dayofweek +description: > + Temporal.Calendar.prototype.dayOfWeek 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.Calendar.prototype.dayOfWeek(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.Calendar.prototype.dayOfWeek), false, + "isConstructor(Temporal.Calendar.prototype.dayOfWeek)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/plain-date-time.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/plain-date-time.js new file mode 100644 index 0000000000..06e9c5ebfa --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/plain-date-time.js @@ -0,0 +1,40 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-temporal.calendar.prototype.dayofweek +description: > + Temporal.Calendar.prototype.dayOfWeek will take Temporal.PlainDateTime objects + and return the day of week. +info: | + 5. Return 𝔽(! ToISODayOfWeek(temporalDate.[[ISOYear]], temporalDate.[[ISOMonth]], temporalDate.[[ISODay]])). +features: [Temporal] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +let dt = new Temporal.PlainDateTime(1997, 1, 23, 5, 30, 13); +assert.sameValue( + cal.dayOfWeek(dt), + 4, + 'cal.dayOfWeek(new Temporal.PlainDateTime(1997, 1, 23, 5, 30, 13)) must return 4' +); +dt = new Temporal.PlainDateTime(1996, 2, 23, 5, 30, 13); +assert.sameValue( + cal.dayOfWeek(dt), + 5, + 'cal.dayOfWeek(new Temporal.PlainDateTime(1996, 2, 23, 5, 30, 13)) must return 5' +); +dt = new Temporal.PlainDateTime(1997, 2, 23, 5, 30, 13); +assert.sameValue( + cal.dayOfWeek(dt), + 7, + 'cal.dayOfWeek(new Temporal.PlainDateTime(1997, 2, 23, 5, 30, 13)) must return 7' +); +dt = new Temporal.PlainDateTime(1997, 6, 23, 5, 30, 13); +assert.sameValue( + cal.dayOfWeek(dt), + 1, + 'cal.dayOfWeek(new Temporal.PlainDateTime(1997, 6, 23, 5, 30, 13)) must return 1' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/plain-date.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/plain-date.js new file mode 100644 index 0000000000..8375c0c362 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/plain-date.js @@ -0,0 +1,22 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-temporal.calendar.prototype.dayofweek +description: > + Temporal.Calendar.prototype.dayOfWeek will take Temporal.PlainDate objects + and return the day of week. +info: | + 5. Return 𝔽(! ToISODayOfWeek(temporalDate.[[ISOYear]], temporalDate.[[ISOMonth]], temporalDate.[[ISODay]])). +features: [Temporal] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +let d = new Temporal.PlainDate(1970, 1, 1); +assert.sameValue(4, cal.dayOfWeek(d), '4 must return the same value returned by cal.dayOfWeek(d)'); +d = new Temporal.PlainDate(2021, 2, 15); +assert.sameValue(1, cal.dayOfWeek(d), '1 must return the same value returned by cal.dayOfWeek(d)'); +d = new Temporal.PlainDate(2021, 8, 15); +assert.sameValue(7, cal.dayOfWeek(d), '7 must return the same value returned by cal.dayOfWeek(d)'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/prop-desc.js new file mode 100644 index 0000000000..3b8516bf3a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/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.calendar.prototype.dayofweek +description: The "dayOfWeek" property of Temporal.Calendar.prototype +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.Calendar.prototype.dayOfWeek, + "function", + "`typeof Calendar.prototype.dayOfWeek` is `function`" +); + +verifyProperty(Temporal.Calendar.prototype, "dayOfWeek", { + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/shell.js new file mode 100644 index 0000000000..eda1477282 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/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/Calendar/prototype/dayOfWeek/string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/string.js new file mode 100644 index 0000000000..c4ea8da784 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/string.js @@ -0,0 +1,21 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-temporal.calendar.prototype.dayofweek +description: > + Temporal.Calendar.prototype.dayOfWeek will take ISO8601 string + and return the day of week. +info: | + 4. Let temporalDate be ? ToTemporalDate(temporalDateLike). + 5. Return 𝔽(! ToISODayOfWeek(temporalDate.[[ISOYear]], temporalDate.[[ISOMonth]], temporalDate.[[ISODay]])). +features: [Temporal] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +assert.sameValue(cal.dayOfWeek("2019-01-18"), 5, 'cal.dayOfWeek("2019-01-18") must return 5'); +assert.sameValue(cal.dayOfWeek("2019-03-18"), 1, 'cal.dayOfWeek("2019-03-18") must return 1'); +assert.sameValue(cal.dayOfWeek("2019-05-18"), 6, 'cal.dayOfWeek("2019-05-18") must return 6'); +assert.sameValue(cal.dayOfWeek("2019-08-18"), 7, 'cal.dayOfWeek("2019-08-18") must return 7'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/throw-range-error-ToTemporalDate.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/throw-range-error-ToTemporalDate.js new file mode 100644 index 0000000000..5b67bc8256 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/throw-range-error-ToTemporalDate.js @@ -0,0 +1,18 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-temporal.calendar.prototype.dayOfWeek +description: > + Temporal.Calendar.prototype.dayOfWeek throws RangeError on + ToTemporalDate when temporalDateLike is invalid string. +info: | + 4. Let temporalDate be ? ToTemporalDate(temporalDateLike). +features: [Temporal, arrow-function] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +assert.throws(RangeError, () => cal.dayOfWeek("invalid string"), + 'cal.dayOfWeek("invalid string") throws a RangeError exception'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/year-zero.js new file mode 100644 index 0000000000..0a81bab672 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/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.calendar.prototype.dayofweek +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.dayOfWeek(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-calendar-datefromfields-called-with-null-prototype-fields.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-calendar-datefromfields-called-with-null-prototype-fields.js new file mode 100644 index 0000000000..35fbeffb61 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-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.calendar.prototype.dayofyear +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.Calendar("iso8601"); +const arg = { year: 2000, month: 5, day: 2, calendar }; +instance.dayOfYear(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/Calendar/prototype/dayOfYear/argument-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-leap-second.js new file mode 100644 index 0000000000..242299d75e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-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.calendar.prototype.dayofyear +description: Leap second is a valid ISO string for PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.dayOfYear(arg); +assert.sameValue( + result1, + 366, + "leap second is a valid ISO string for PlainDate" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.dayOfYear(arg); +assert.sameValue( + result2, + 366, + "second: 60 is ignored in property bag for PlainDate" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-number.js new file mode 100644 index 0000000000..b5f97c68cf --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/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.calendar.prototype.dayofyear +description: A number is converted to a string, then to Temporal.PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const arg = 19761118; + +const result = instance.dayOfYear(arg); +assert.sameValue(result, 323, "19761118 is a valid ISO string for PlainDate"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.dayOfYear(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-case-insensitive.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-case-insensitive.js new file mode 100644 index 0000000000..f3b396e4b7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/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.calendar.prototype.dayofyear +description: The calendar name is case-insensitive +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "IsO8601"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.dayOfYear(arg); +assert.sameValue(result1, 323, "Calendar is case-insensitive"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.dayOfYear(arg); +assert.sameValue(result2, 323, "Calendar is case-insensitive (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js new file mode 100644 index 0000000000..6efbc59161 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/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.calendar.prototype.dayofyear +description: > + A Temporal.Calendar instance passed to dayOfYear() in a property bag does + not have its 'calendar' property observably checked +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +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.dayOfYear(arg); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +instance.dayOfYear(arg); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-leap-second.js new file mode 100644 index 0000000000..f40f60b269 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/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.calendar.prototype.dayofyear +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.dayOfYear(arg); +assert.sameValue( + result1, + 323, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.dayOfYear(arg); +assert.sameValue( + result2, + 323, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-number.js new file mode 100644 index 0000000000..dd89b9f401 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/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.calendar.prototype.dayofyear +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.dayOfYear(arg); +assert.sameValue(result1, 323, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.dayOfYear(arg); +assert.sameValue(result2, 323, "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.dayOfYear(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.dayOfYear(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/Calendar/prototype/dayOfYear/argument-propertybag-calendar-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-string.js new file mode 100644 index 0000000000..0c784bd37e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/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.calendar.prototype.dayofyear +description: A calendar ID is valid input for Calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "iso8601"; + +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.dayOfYear(arg); +assert.sameValue(result, 323, `Calendar created from string "${calendar}"`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 0000000000..f6e4baece7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/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.calendar.prototype.dayofyear +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.Calendar("iso8601"); + +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.dayOfYear(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.dayOfYear(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.dayOfYear(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.dayOfYear(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.dayOfYear(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-year-zero.js new file mode 100644 index 0000000000..3ad481707f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/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.calendar.prototype.dayofyear +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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.dayOfYear(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-calendar-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-calendar-annotation.js new file mode 100644 index 0000000000..e50f321b08 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/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.calendar.prototype.dayofyear +description: Various forms of calendar annotation; critical flag has no effect +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02[u-ca=iso8601]", "without time or time zone"], + ["2000-05-02[UTC][u-ca=iso8601]", "with time zone and no time"], + ["2000-05-02T15:23[u-ca=iso8601]", "without time zone"], + ["2000-05-02T15:23[UTC][u-ca=iso8601]", "with time zone"], + ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], + ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], + ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], + ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.dayOfYear(arg); + + assert.sameValue( + result, + 123, + `calendar annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-critical-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-critical-unknown-annotation.js new file mode 100644 index 0000000000..eb3c0c2774 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-critical-unknown-annotation.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.calendar.prototype.dayofyear +description: Unknown annotations with critical flag are rejected +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[!foo=bar]", + "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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.dayOfYear(arg), + `reject unknown annotation with critical flag: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-date-with-utc-offset.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-date-with-utc-offset.js new file mode 100644 index 0000000000..83a543552e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/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.calendar.prototype.dayofyear +description: UTC offset not valid with format that does not include a time +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const validStrings = [ + "2000-05-02T00+00:00", + "2000-05-02T00+00:00[UTC]", + "2000-05-02T00+00:00[!UTC]", + "2000-05-02T00-02:30[America/St_Johns]", +]; + +for (const arg of validStrings) { + const result = instance.dayOfYear(arg); + + assert.sameValue( + result, + 123, + `"${arg}" is a valid UTC offset with time for PlainDate` + ); +} + +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.dayOfYear(arg), + `"${arg}" UTC offset without time is not valid for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-invalid.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-invalid.js new file mode 100644 index 0000000000..ffab72c98e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-invalid.js @@ -0,0 +1,64 @@ +// |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.calendar.prototype.dayofyear +description: > + RangeError thrown if an invalid ISO string (or syntactically valid ISO string + that is not supported) is used as a PlainDate +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + // invalid ISO strings: + "", + "invalid iso8601", + "2020-01-00", + "2020-01-32", + "2020-02-30", + "2021-02-29", + "2020-00-01", + "2020-13-01", + "2020-01-01T", + "2020-01-01T25:00:00", + "2020-01-01T01:60:00", + "2020-01-01T01:60:61", + "2020-01-01junk", + "2020-01-01T00:00:00junk", + "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-01", + "2020-001-01", + "2020-01-001", + "2020-01-01T001", + "2020-01-01T01:001", + "2020-01-01T01:01:001", + // valid, but forms not supported in Temporal: + "2020-W01-1", + "2020-001", + "+0002020-01-01", + // valid, but this calendar must not exist: + "2020-01-01[u-ca=notexist]", + // may be valid in other contexts, but insufficient information for PlainDate: + "2020-01", + "+002020-01", + "01-01", + "2020-W01", + "P1Y", + "-P12Y", + // valid, but outside the supported range: + "-999999-01-01", + "+999999-01-01", +]; +const instance = new Temporal.Calendar("iso8601"); +for (const arg of invalidStrings) { + assert.throws( + RangeError, + () => instance.dayOfYear(arg), + `"${arg}" should not be a valid ISO string for a PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-multiple-time-zone.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-multiple-time-zone.js new file mode 100644 index 0000000000..3ab6d25147 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-multiple-time-zone.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.calendar.prototype.dayofyear +description: More than one time zone annotation is not syntactical +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[UTC][UTC]", + "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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.dayOfYear(arg), + `reject more than one time zone annotation: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-time-separators.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-time-separators.js new file mode 100644 index 0000000000..fa5ccca0ce --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/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.calendar.prototype.dayofyear +description: Time separator in string argument can vary +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02T15:23", "uppercase T"], + ["2000-05-02t15:23", "lowercase T"], + ["2000-05-02 15:23", "space between date and time"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.dayOfYear(arg); + + assert.sameValue( + result, + 123, + `variant time separators (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-time-zone-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-time-zone-annotation.js new file mode 100644 index 0000000000..dfe4b8a9d0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-time-zone-annotation.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.calendar.prototype.dayofyear +description: Various forms of time zone annotation; critical flag has no effect +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02[Asia/Kolkata]", "named, with no time"], + ["2000-05-02[!Europe/Vienna]", "named, with ! and no time"], + ["2000-05-02[+00:00]", "numeric, with no time"], + ["2000-05-02[!-02:30]", "numeric, with ! and no time"], + ["2000-05-02T15:23[America/Sao_Paulo]", "named, with no offset"], + ["2000-05-02T15:23[!Asia/Tokyo]", "named, with ! and no offset"], + ["2000-05-02T15:23[-02:30]", "numeric, with no offset"], + ["2000-05-02T15:23[!+00:00]", "numeric, with ! and no offset"], + ["2000-05-02T15:23+00:00[America/New_York]", "named, with offset"], + ["2000-05-02T15:23+00:00[!UTC]", "named, with offset and !"], + ["2000-05-02T15:23+00:00[+01:00]", "numeric, with offset"], + ["2000-05-02T15:23+00:00[!-08:00]", "numeric, with offset and !"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.dayOfYear(arg); + + assert.sameValue( + result, + 123, + `time zone annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-unknown-annotation.js new file mode 100644 index 0000000000..f79c2a0974 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/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.calendar.prototype.dayofyear +description: Various forms of unknown annotation +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02[foo=bar]", "without time"], + ["2000-05-02T15:23[foo=bar]", "alone"], + ["2000-05-02T15:23[UTC][foo=bar]", "with time zone"], + ["2000-05-02T15:23[u-ca=iso8601][foo=bar]", "with calendar"], + ["2000-05-02T15:23[UTC][foo=bar][u-ca=iso8601]", "with time zone and calendar"], + ["2000-05-02T15:23[foo=bar][_foo-bar0=Ignore-This-999999999999]", "with another unknown annotation"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.dayOfYear(arg); + + assert.sameValue( + result, + 123, + `unknown annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-with-utc-designator.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-with-utc-designator.js new file mode 100644 index 0000000000..8f0677f5f9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/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.calendar.prototype.dayofyear +description: RangeError thrown if a string with UTC designator is used as a PlainDate +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "2019-10-01T09:00:00Z", + "2019-10-01T09:00:00Z[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.dayOfYear(arg), + "String with UTC designator should not be valid as a PlainDate" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-wrong-type.js new file mode 100644 index 0000000000..9b12533701 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/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.calendar.prototype.dayofyear +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +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.dayOfYear(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.dayOfYear(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/Calendar/prototype/dayOfYear/argument-zoneddatetime-convert.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-zoneddatetime-convert.js new file mode 100644 index 0000000000..b70138594f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-zoneddatetime-convert.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.calendar.prototype.dayofyear +description: An exception from TimeZone#getOffsetNanosecondsFor() is propagated. +features: [Temporal] +---*/ + +class TZ extends Temporal.TimeZone { + constructor() { super("UTC") } + getOffsetNanosecondsFor() { throw new Test262Error() } +} + +const tz = new TZ(); +const arg = new Temporal.ZonedDateTime(0n, tz); +const instance = new Temporal.Calendar("iso8601"); + +assert.throws(Test262Error, () => instance.dayOfYear(arg)); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-zoneddatetime-slots.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-zoneddatetime-slots.js new file mode 100644 index 0000000000..8b9e8e2722 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-zoneddatetime-slots.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.calendar.prototype.dayofyear +description: Getters are not called when converting a ZonedDateTime to a PlainDate. +includes: [compareArray.js] +features: [Temporal] +---*/ + +const actual = []; +const prototypeDescrs = Object.getOwnPropertyDescriptors(Temporal.ZonedDateTime.prototype); +const getters = ["year", "month", "monthCode", "day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond", "calendar"]; + +for (const property of getters) { + Object.defineProperty(Temporal.ZonedDateTime.prototype, property, { + get() { + actual.push(`get ${property}`); + const value = prototypeDescrs[property].get.call(this); + return { + toString() { + actual.push(`toString ${property}`); + return value.toString(); + }, + valueOf() { + actual.push(`valueOf ${property}`); + return value; + }, + }; + }, + }); +} + +const arg = new Temporal.ZonedDateTime(0n, "UTC"); +const instance = new Temporal.Calendar("iso8601"); +instance.dayOfYear(arg); +assert.compareArray(actual, []); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js new file mode 100644 index 0000000000..873c5f6c99 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/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.calendar.prototype.dayofyear +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(RangeError, () => calendar.dayOfYear(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js new file mode 100644 index 0000000000..e531f39ff1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/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.calendar.prototype.dayofyear +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + timeZone.getOffsetNanosecondsFor = notCallable; + assert.throws( + TypeError, + () => calendar.dayOfYear(datetime), + `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js new file mode 100644 index 0000000000..35063a6122 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/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.calendar.prototype.dayofyear +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(RangeError, () => calendar.dayOfYear(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js new file mode 100644 index 0000000000..9887a5aee8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/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.calendar.prototype.dayofyear +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(TypeError, () => calendar.dayOfYear(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/basic.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/basic.js new file mode 100644 index 0000000000..9af5dd2cfd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/basic.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.calendar.prototype.dayofyear +description: Basic tests for dayOfYear(). +features: [Temporal] +---*/ + +const iso = Temporal.Calendar.from("iso8601"); +const res = 309; +assert.sameValue(iso.dayOfYear(Temporal.PlainDate.from("1994-11-05")), res, "PlainDate"); +assert.sameValue(iso.dayOfYear(Temporal.PlainDateTime.from("1994-11-05T08:15:30")), res, "PlainDateTime"); +assert.sameValue(iso.dayOfYear({ year: 1994, month: 11, day: 5 }), res, "property bag"); +assert.sameValue(iso.dayOfYear("1994-11-05"), res, "string"); +assert.throws(TypeError, () => iso.dayOfYear({ year: 2000 }), "property bag with missing properties"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/branding.js new file mode 100644 index 0000000000..629ef89b1a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/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.calendar.prototype.dayofyear +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const dayOfYear = Temporal.Calendar.prototype.dayOfYear; + +assert.sameValue(typeof dayOfYear, "function"); + +const args = [new Temporal.PlainDate(2000, 1, 1)]; + +assert.throws(TypeError, () => dayOfYear.apply(undefined, args), "undefined"); +assert.throws(TypeError, () => dayOfYear.apply(null, args), "null"); +assert.throws(TypeError, () => dayOfYear.apply(true, args), "true"); +assert.throws(TypeError, () => dayOfYear.apply("", args), "empty string"); +assert.throws(TypeError, () => dayOfYear.apply(Symbol(), args), "symbol"); +assert.throws(TypeError, () => dayOfYear.apply(1, args), "1"); +assert.throws(TypeError, () => dayOfYear.apply({}, args), "plain object"); +assert.throws(TypeError, () => dayOfYear.apply(Temporal.Calendar, args), "Temporal.Calendar"); +assert.throws(TypeError, () => dayOfYear.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/builtin.js new file mode 100644 index 0000000000..78d992e125 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/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.calendar.prototype.dayofyear +description: > + Tests that Temporal.Calendar.prototype.dayOfYear + 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.Calendar.prototype.dayOfYear), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.dayOfYear), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.dayOfYear), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.Calendar.prototype.dayOfYear.hasOwnProperty("prototype"), + false, "prototype property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/calendar-datefromfields-called-with-options-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/calendar-datefromfields-called-with-options-undefined.js new file mode 100644 index 0000000000..a20cc4449e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/calendar-datefromfields-called-with-options-undefined.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.calendar.prototype.dayofyear +description: > + Calendar.dateFromFields method is called with undefined as the options value + when call originates internally +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = TemporalHelpers.calendarFromFieldsUndefinedOptions(); +calendar.dayOfYear({ year: 2000, month: 5, day: 3, calendar }); +assert.sameValue(calendar.dateFromFieldsCallCount, 1); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/calendar-fields-iterable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/calendar-fields-iterable.js new file mode 100644 index 0000000000..fb91b200fe --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/calendar-fields-iterable.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.calendar.prototype.dayofyear +description: Verify the result of calendar.fields() is treated correctly. +info: | + sec-temporal.calendar.prototype.dayofyear step 4: + 4. Let _date_ be ? ToTemporalDate(_dateOrDateTime_). + sec-temporal-totemporaldate step 2.c: + c. Let _fieldNames_ be ? CalendarFields(_calendar_, « *"day"*, *"month"*, *"monthCode"*, *"year"* »). + sec-temporal-calendarfields step 4: + 4. Let _result_ be ? IterableToListOfType(_fieldsArray_, « String »). +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + "day", + "month", + "monthCode", + "year", +]; + +const calendar1 = TemporalHelpers.calendarFieldsIterable(); +const calendar2 = TemporalHelpers.calendarFieldsIterable(); +calendar1.dayOfYear({ year: 2000, month: 5, day: 2, calendar: calendar2 }); + +assert.sameValue(calendar1.fieldsCallCount, 0, "fields() method not called"); +assert.sameValue(calendar2.fieldsCallCount, 1, "fields() method called once"); +assert.compareArray(calendar2.fieldsCalledWith[0], expected, "fields() method called with correct args"); +assert(calendar2.iteratorExhausted[0], "iterated through the whole iterable"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/calendar-temporal-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/calendar-temporal-object.js new file mode 100644 index 0000000000..565c10a09d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/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.calendar.prototype.dayofyear +description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots +info: | + sec-temporal.calendar.prototype.dayofyear step 4: + 4. Let _date_ be ? ToTemporalDate(_dateOrDateTime_). + sec-temporal-totemporaldate 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 calendar = new Temporal.Calendar("iso8601"); + calendar.dayOfYear({ year: 2000, month: 5, day: 2, calendar: temporalObject }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/infinity-throws-rangeerror.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/infinity-throws-rangeerror.js new file mode 100644 index 0000000000..69b2375eab --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/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.calendar.prototype.dayofyear +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); +const base = { year: 2000, month: 5, day: 2 }; + +[Infinity, -Infinity].forEach((inf) => { + ["year", "month", "day"].forEach((prop) => { + assert.throws(RangeError, () => instance.dayOfYear({ ...base, [prop]: inf }), `${prop} property cannot be ${inf}`); + + const calls = []; + const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop); + assert.throws(RangeError, () => instance.dayOfYear({ ...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/Calendar/prototype/dayOfYear/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/length.js new file mode 100644 index 0000000000..7453a909a9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/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.calendar.prototype.dayofyear +description: Temporal.Calendar.prototype.dayOfYear.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.Calendar.prototype.dayOfYear, "length", { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/name.js new file mode 100644 index 0000000000..4532e747a1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/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.calendar.prototype.dayofyear +description: Temporal.Calendar.prototype.dayOfYear.name is "dayOfYear". +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.Calendar.prototype.dayOfYear, "name", { + value: "dayOfYear", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/not-a-constructor.js new file mode 100644 index 0000000000..14da7c69f0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/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.calendar.prototype.dayofyear +description: > + Temporal.Calendar.prototype.dayOfYear 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.Calendar.prototype.dayOfYear(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.Calendar.prototype.dayOfYear), false, + "isConstructor(Temporal.Calendar.prototype.dayOfYear)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/plain-date-time.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/plain-date-time.js new file mode 100644 index 0000000000..fdefe2b25f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/plain-date-time.js @@ -0,0 +1,58 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-temporal.calendar.prototype.dayofyear +description: > + Temporal.Calendar.prototype.dayOfYear will take PlainDateTime object and + return the day of year. +info: | + 4. Let temporalDate be ? ToTemporalDate(temporalDateLike). + 5. Return 𝔽(! ToISODayOfYear(temporalDate.[[ISOYear]], temporalDate.[[ISOMonth]], temporalDate.[[ISODay]])). +features: [Temporal] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +let dt = new Temporal.PlainDateTime(1997, 1, 23, 5, 30, 13); +assert.sameValue( + cal.dayOfYear(dt), + 23, + 'cal.dayOfYear(new Temporal.PlainDateTime(1997, 1, 23, 5, 30, 13)) must return 23' +); + +dt = new Temporal.PlainDateTime(1997, 2, 23, 5, 30, 13); +assert.sameValue( + cal.dayOfYear(dt), + 54, + 'cal.dayOfYear(new Temporal.PlainDateTime(1997, 2, 23, 5, 30, 13)) must return 54' +); + +dt = new Temporal.PlainDateTime(1996, 3, 23, 5, 30, 13); +assert.sameValue( + cal.dayOfYear(dt), + 83, + 'cal.dayOfYear(new Temporal.PlainDateTime(1996, 3, 23, 5, 30, 13)) must return 83' +); + +dt = new Temporal.PlainDateTime(1997, 3, 23, 5, 30, 13); +assert.sameValue( + cal.dayOfYear(dt), + 82, + 'cal.dayOfYear(new Temporal.PlainDateTime(1997, 3, 23, 5, 30, 13)) must return 82' +); + +dt = new Temporal.PlainDateTime(1997, 12, 31, 5, 30, 13); +assert.sameValue( + cal.dayOfYear(dt), + 365, + 'cal.dayOfYear(new Temporal.PlainDateTime(1997, 12, 31, 5, 30, 13)) must return 365' +); + +dt = new Temporal.PlainDateTime(1996, 12, 31, 5, 30, 13); +assert.sameValue( + cal.dayOfYear(dt), + 366, + 'cal.dayOfYear(new Temporal.PlainDateTime(1996, 12, 31, 5, 30, 13)) must return 366' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/plain-date.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/plain-date.js new file mode 100644 index 0000000000..6e7258b642 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/plain-date.js @@ -0,0 +1,41 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-temporal.calendar.prototype.dayofyear +description: > + Temporal.Calendar.prototype.dayOfYear will take PlainDate object and + return the day of year. +info: | + 5. Return 𝔽(! ToISODayOfYear(temporalDate.[[ISOYear]], temporalDate.[[ISOMonth]], temporalDate.[[ISODay]])). +features: [Temporal] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +let d = new Temporal.PlainDate(1970, 1, 1); +assert.sameValue(cal.dayOfYear(d), 1, 'cal.dayOfYear(new Temporal.PlainDate(1970, 1, 1)) must return 1'); +d = new Temporal.PlainDate(2000, 1, 1); +assert.sameValue(cal.dayOfYear(d), 1, 'cal.dayOfYear(new Temporal.PlainDate(2000, 1, 1)) must return 1'); + +d = new Temporal.PlainDate(2021, 1, 15); +assert.sameValue(cal.dayOfYear(d), 15, 'cal.dayOfYear(new Temporal.PlainDate(2021, 1, 15)) must return 15'); + +d = new Temporal.PlainDate(2020, 2, 15); +assert.sameValue(cal.dayOfYear(d), 46, 'cal.dayOfYear(new Temporal.PlainDate(2020, 2, 15)) must return 46'); + +d = new Temporal.PlainDate(2020, 3, 15); +assert.sameValue(cal.dayOfYear(d), 75, 'cal.dayOfYear(new Temporal.PlainDate(2020, 3, 15)) must return 75'); + +d = new Temporal.PlainDate(2000, 3, 15); +assert.sameValue(cal.dayOfYear(d), 75, 'cal.dayOfYear(new Temporal.PlainDate(2000, 3, 15)) must return 75'); + +d = new Temporal.PlainDate(2001, 3, 15); +assert.sameValue(cal.dayOfYear(d), 74, 'cal.dayOfYear(new Temporal.PlainDate(2001, 3, 15)) must return 74'); + +d = new Temporal.PlainDate(2000, 12, 31); +assert.sameValue(cal.dayOfYear(d), 366, 'cal.dayOfYear(new Temporal.PlainDate(2000, 12, 31)) must return 366'); + +d = new Temporal.PlainDate(2001, 12, 31); +assert.sameValue(cal.dayOfYear(d), 365, 'cal.dayOfYear(new Temporal.PlainDate(2001, 12, 31)) must return 365'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/prop-desc.js new file mode 100644 index 0000000000..a63b783bd4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/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.calendar.prototype.dayofyear +description: The "dayOfYear" property of Temporal.Calendar.prototype +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.Calendar.prototype.dayOfYear, + "function", + "`typeof Calendar.prototype.dayOfYear` is `function`" +); + +verifyProperty(Temporal.Calendar.prototype, "dayOfYear", { + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/shell.js new file mode 100644 index 0000000000..eda1477282 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/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/Calendar/prototype/dayOfYear/string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/string.js new file mode 100644 index 0000000000..043a9bd747 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/string.js @@ -0,0 +1,37 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-temporal.calendar.prototype.dayofyear +description: > + Temporal.Calendar.prototype.dayOfYear will take ISO8601 string and + return the day of year. +info: | + 4. Let temporalDate be ? ToTemporalDate(temporalDateLike). + 5. Return 𝔽(! ToISODayOfYear(temporalDate.[[ISOYear]], temporalDate.[[ISOMonth]], temporalDate.[[ISODay]])). +features: [Temporal] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +assert.sameValue( + cal.dayOfYear("2019-01-18"), + 18, + 'cal.dayOfYear("2019-01-18") must return 18' +); +assert.sameValue( + cal.dayOfYear("2020-02-18"), + 49, + 'cal.dayOfYear("2020-02-18") must return 49' +); +assert.sameValue( + cal.dayOfYear("2019-12-31"), + 365, + 'cal.dayOfYear("2019-12-31") must return 365' +); +assert.sameValue( + cal.dayOfYear("2000-12-31"), + 366, + 'cal.dayOfYear("2000-12-31") must return 366' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/throw-range-error-ToTemporalDate.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/throw-range-error-ToTemporalDate.js new file mode 100644 index 0000000000..e74f6e5ad2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/throw-range-error-ToTemporalDate.js @@ -0,0 +1,18 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-temporal.calendar.prototype.dayOfYear +description: > + Temporal.Calendar.prototype.dayOfYear throws RangeError on + ToTemporalDate when temporalDateLike is invalid string. +info: | + 4. Let temporalDate be ? ToTemporalDate(temporalDateLike). +features: [Temporal, arrow-function] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +assert.throws(RangeError, () => cal.dayOfYear("invalid string"), + 'cal.dayOfYear("invalid string") throws a RangeError exception'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/year-zero.js new file mode 100644 index 0000000000..51543e03c0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/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.calendar.prototype.dayofyear +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.dayOfYear(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-calendar-datefromfields-called-with-null-prototype-fields.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-calendar-datefromfields-called-with-null-prototype-fields.js new file mode 100644 index 0000000000..50464ae11c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-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.calendar.prototype.daysinmonth +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.Calendar("iso8601"); +const arg = { year: 2000, month: 5, day: 2, calendar }; +instance.daysInMonth(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/Calendar/prototype/daysInMonth/argument-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-leap-second.js new file mode 100644 index 0000000000..fbe398944d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-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.calendar.prototype.daysinmonth +description: Leap second is a valid ISO string for PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.daysInMonth(arg); +assert.sameValue( + result1, + 31, + "leap second is a valid ISO string for PlainDate" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.daysInMonth(arg); +assert.sameValue( + result2, + 31, + "second: 60 is ignored in property bag for PlainDate" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-number.js new file mode 100644 index 0000000000..62b98d7a94 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/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.calendar.prototype.daysinmonth +description: A number is converted to a string, then to Temporal.PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const arg = 19761118; + +const result = instance.daysInMonth(arg); +assert.sameValue(result, 30, "19761118 is a valid ISO string for PlainDate"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.daysInMonth(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-case-insensitive.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-case-insensitive.js new file mode 100644 index 0000000000..65f444586c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/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.calendar.prototype.daysinmonth +description: The calendar name is case-insensitive +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "IsO8601"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.daysInMonth(arg); +assert.sameValue(result1, 30, "Calendar is case-insensitive"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.daysInMonth(arg); +assert.sameValue(result2, 30, "Calendar is case-insensitive (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-instance-does-not-get-calendar-property.js new file mode 100644 index 0000000000..38e08cc2f8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/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.calendar.prototype.daysinmonth +description: > + A Temporal.Calendar instance passed to daysInMonth() in a property bag does + not have its 'calendar' property observably checked +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +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.daysInMonth(arg); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +instance.daysInMonth(arg); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-leap-second.js new file mode 100644 index 0000000000..5f1cb805fd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/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.calendar.prototype.daysinmonth +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.daysInMonth(arg); +assert.sameValue( + result1, + 30, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.daysInMonth(arg); +assert.sameValue( + result2, + 30, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-number.js new file mode 100644 index 0000000000..ff8a04645b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/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.calendar.prototype.daysinmonth +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.daysInMonth(arg); +assert.sameValue(result1, 30, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.daysInMonth(arg); +assert.sameValue(result2, 30, "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.daysInMonth(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.daysInMonth(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/Calendar/prototype/daysInMonth/argument-propertybag-calendar-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-string.js new file mode 100644 index 0000000000..889d102c40 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/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.calendar.prototype.daysinmonth +description: A calendar ID is valid input for Calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "iso8601"; + +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.daysInMonth(arg); +assert.sameValue(result, 30, `Calendar created from string "${calendar}"`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 0000000000..043baab71d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/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.calendar.prototype.daysinmonth +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.Calendar("iso8601"); + +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.daysInMonth(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.daysInMonth(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.daysInMonth(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.daysInMonth(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.daysInMonth(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-year-zero.js new file mode 100644 index 0000000000..39c5839416 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/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.calendar.prototype.daysinmonth +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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.daysInMonth(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-calendar-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-calendar-annotation.js new file mode 100644 index 0000000000..35f4b75206 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/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.calendar.prototype.daysinmonth +description: Various forms of calendar annotation; critical flag has no effect +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02[u-ca=iso8601]", "without time or time zone"], + ["2000-05-02[UTC][u-ca=iso8601]", "with time zone and no time"], + ["2000-05-02T15:23[u-ca=iso8601]", "without time zone"], + ["2000-05-02T15:23[UTC][u-ca=iso8601]", "with time zone"], + ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], + ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], + ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], + ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.daysInMonth(arg); + + assert.sameValue( + result, + 31, + `calendar annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-critical-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-critical-unknown-annotation.js new file mode 100644 index 0000000000..019411b338 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-critical-unknown-annotation.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.calendar.prototype.daysinmonth +description: Unknown annotations with critical flag are rejected +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[!foo=bar]", + "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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.daysInMonth(arg), + `reject unknown annotation with critical flag: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-date-with-utc-offset.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-date-with-utc-offset.js new file mode 100644 index 0000000000..5e32c817b2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/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.calendar.prototype.daysinmonth +description: UTC offset not valid with format that does not include a time +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const validStrings = [ + "2000-05-02T00+00:00", + "2000-05-02T00+00:00[UTC]", + "2000-05-02T00+00:00[!UTC]", + "2000-05-02T00-02:30[America/St_Johns]", +]; + +for (const arg of validStrings) { + const result = instance.daysInMonth(arg); + + assert.sameValue( + result, + 31, + `"${arg}" is a valid UTC offset with time for PlainDate` + ); +} + +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.daysInMonth(arg), + `"${arg}" UTC offset without time is not valid for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-invalid.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-invalid.js new file mode 100644 index 0000000000..77af97c445 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-invalid.js @@ -0,0 +1,64 @@ +// |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.calendar.prototype.daysinmonth +description: > + RangeError thrown if an invalid ISO string (or syntactically valid ISO string + that is not supported) is used as a PlainDate +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + // invalid ISO strings: + "", + "invalid iso8601", + "2020-01-00", + "2020-01-32", + "2020-02-30", + "2021-02-29", + "2020-00-01", + "2020-13-01", + "2020-01-01T", + "2020-01-01T25:00:00", + "2020-01-01T01:60:00", + "2020-01-01T01:60:61", + "2020-01-01junk", + "2020-01-01T00:00:00junk", + "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-01", + "2020-001-01", + "2020-01-001", + "2020-01-01T001", + "2020-01-01T01:001", + "2020-01-01T01:01:001", + // valid, but forms not supported in Temporal: + "2020-W01-1", + "2020-001", + "+0002020-01-01", + // valid, but this calendar must not exist: + "2020-01-01[u-ca=notexist]", + // may be valid in other contexts, but insufficient information for PlainDate: + "2020-01", + "+002020-01", + "01-01", + "2020-W01", + "P1Y", + "-P12Y", + // valid, but outside the supported range: + "-999999-01-01", + "+999999-01-01", +]; +const instance = new Temporal.Calendar("iso8601"); +for (const arg of invalidStrings) { + assert.throws( + RangeError, + () => instance.daysInMonth(arg), + `"${arg}" should not be a valid ISO string for a PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-multiple-time-zone.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-multiple-time-zone.js new file mode 100644 index 0000000000..5f09b3cfe1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-multiple-time-zone.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.calendar.prototype.daysinmonth +description: More than one time zone annotation is not syntactical +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[UTC][UTC]", + "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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.daysInMonth(arg), + `reject more than one time zone annotation: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-time-separators.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-time-separators.js new file mode 100644 index 0000000000..5a1f398c5f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/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.calendar.prototype.daysinmonth +description: Time separator in string argument can vary +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02T15:23", "uppercase T"], + ["2000-05-02t15:23", "lowercase T"], + ["2000-05-02 15:23", "space between date and time"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.daysInMonth(arg); + + assert.sameValue( + result, + 31, + `variant time separators (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-time-zone-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-time-zone-annotation.js new file mode 100644 index 0000000000..4eb7904a53 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-time-zone-annotation.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.calendar.prototype.daysinmonth +description: Various forms of time zone annotation; critical flag has no effect +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02[Asia/Kolkata]", "named, with no time"], + ["2000-05-02[!Europe/Vienna]", "named, with ! and no time"], + ["2000-05-02[+00:00]", "numeric, with no time"], + ["2000-05-02[!-02:30]", "numeric, with ! and no time"], + ["2000-05-02T15:23[America/Sao_Paulo]", "named, with no offset"], + ["2000-05-02T15:23[!Asia/Tokyo]", "named, with ! and no offset"], + ["2000-05-02T15:23[-02:30]", "numeric, with no offset"], + ["2000-05-02T15:23[!+00:00]", "numeric, with ! and no offset"], + ["2000-05-02T15:23+00:00[America/New_York]", "named, with offset"], + ["2000-05-02T15:23+00:00[!UTC]", "named, with offset and !"], + ["2000-05-02T15:23+00:00[+01:00]", "numeric, with offset"], + ["2000-05-02T15:23+00:00[!-08:00]", "numeric, with offset and !"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.daysInMonth(arg); + + assert.sameValue( + result, + 31, + `time zone annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-unknown-annotation.js new file mode 100644 index 0000000000..939a78c5ae --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/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.calendar.prototype.daysinmonth +description: Various forms of unknown annotation +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02[foo=bar]", "without time"], + ["2000-05-02T15:23[foo=bar]", "alone"], + ["2000-05-02T15:23[UTC][foo=bar]", "with time zone"], + ["2000-05-02T15:23[u-ca=iso8601][foo=bar]", "with calendar"], + ["2000-05-02T15:23[UTC][foo=bar][u-ca=iso8601]", "with time zone and calendar"], + ["2000-05-02T15:23[foo=bar][_foo-bar0=Ignore-This-999999999999]", "with another unknown annotation"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.daysInMonth(arg); + + assert.sameValue( + result, + 31, + `unknown annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-with-utc-designator.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-with-utc-designator.js new file mode 100644 index 0000000000..a7d1498944 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/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.calendar.prototype.daysinmonth +description: RangeError thrown if a string with UTC designator is used as a PlainDate +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "2019-10-01T09:00:00Z", + "2019-10-01T09:00:00Z[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.daysInMonth(arg), + "String with UTC designator should not be valid as a PlainDate" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-wrong-type.js new file mode 100644 index 0000000000..9e43a5f031 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/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.calendar.prototype.daysinmonth +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +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.daysInMonth(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.daysInMonth(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/Calendar/prototype/daysInMonth/argument-zoneddatetime-convert.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-zoneddatetime-convert.js new file mode 100644 index 0000000000..df123c7c3f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-zoneddatetime-convert.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.calendar.prototype.daysinmonth +description: An exception from TimeZone#getOffsetNanosecondsFor() is propagated. +features: [Temporal] +---*/ + +class TZ extends Temporal.TimeZone { + constructor() { super("UTC") } + getOffsetNanosecondsFor() { throw new Test262Error() } +} + +const tz = new TZ(); +const arg = new Temporal.ZonedDateTime(0n, tz); +const instance = new Temporal.Calendar("iso8601"); + +assert.throws(Test262Error, () => instance.daysInMonth(arg)); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-zoneddatetime-slots.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-zoneddatetime-slots.js new file mode 100644 index 0000000000..af9c02eb05 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-zoneddatetime-slots.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.calendar.prototype.daysinmonth +description: Getters are not called when converting a ZonedDateTime to a PlainDate. +includes: [compareArray.js] +features: [Temporal] +---*/ + +const actual = []; +const prototypeDescrs = Object.getOwnPropertyDescriptors(Temporal.ZonedDateTime.prototype); +const getters = ["year", "month", "monthCode", "day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond", "calendar"]; + +for (const property of getters) { + Object.defineProperty(Temporal.ZonedDateTime.prototype, property, { + get() { + actual.push(`get ${property}`); + const value = prototypeDescrs[property].get.call(this); + return { + toString() { + actual.push(`toString ${property}`); + return value.toString(); + }, + valueOf() { + actual.push(`valueOf ${property}`); + return value; + }, + }; + }, + }); +} + +const arg = new Temporal.ZonedDateTime(0n, "UTC"); +const instance = new Temporal.Calendar("iso8601"); +instance.daysInMonth(arg); +assert.compareArray(actual, []); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js new file mode 100644 index 0000000000..9b4622874c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/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.calendar.prototype.daysinmonth +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(RangeError, () => calendar.daysInMonth(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js new file mode 100644 index 0000000000..94dfa4e820 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/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.calendar.prototype.daysinmonth +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + timeZone.getOffsetNanosecondsFor = notCallable; + assert.throws( + TypeError, + () => calendar.daysInMonth(datetime), + `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js new file mode 100644 index 0000000000..8dce624fa2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/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.calendar.prototype.daysinmonth +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(RangeError, () => calendar.daysInMonth(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js new file mode 100644 index 0000000000..081fd70657 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/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.calendar.prototype.daysinmonth +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(TypeError, () => calendar.daysInMonth(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/basic.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/basic.js new file mode 100644 index 0000000000..6a6a95db1a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/basic.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.calendar.prototype.daysinmonth +description: Basic tests for daysInMonth(). +features: [Temporal] +---*/ + +const iso = Temporal.Calendar.from("iso8601"); +const res = 30; +assert.sameValue(iso.daysInMonth(Temporal.PlainDate.from("1994-11-05")), res, "PlainDate"); +assert.sameValue(iso.daysInMonth(Temporal.PlainDateTime.from("1994-11-05T08:15:30")), res, "PlainDateTime"); +assert.sameValue(iso.daysInMonth({ year: 1994, month: 11, day: 5 }), res, "property bag"); +assert.sameValue(iso.daysInMonth("1994-11-05"), res, "string"); +assert.throws(TypeError, () => iso.daysInMonth({ year: 2000 }), "property bag with missing properties"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/branding.js new file mode 100644 index 0000000000..49cb03ffef --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/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.calendar.prototype.daysinmonth +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const daysInMonth = Temporal.Calendar.prototype.daysInMonth; + +assert.sameValue(typeof daysInMonth, "function"); + +const args = [new Temporal.PlainDate(2000, 1, 1)]; + +assert.throws(TypeError, () => daysInMonth.apply(undefined, args), "undefined"); +assert.throws(TypeError, () => daysInMonth.apply(null, args), "null"); +assert.throws(TypeError, () => daysInMonth.apply(true, args), "true"); +assert.throws(TypeError, () => daysInMonth.apply("", args), "empty string"); +assert.throws(TypeError, () => daysInMonth.apply(Symbol(), args), "symbol"); +assert.throws(TypeError, () => daysInMonth.apply(1, args), "1"); +assert.throws(TypeError, () => daysInMonth.apply({}, args), "plain object"); +assert.throws(TypeError, () => daysInMonth.apply(Temporal.Calendar, args), "Temporal.Calendar"); +assert.throws(TypeError, () => daysInMonth.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/builtin.js new file mode 100644 index 0000000000..b13e455659 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/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.calendar.prototype.daysinmonth +description: > + Tests that Temporal.Calendar.prototype.daysInMonth + 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.Calendar.prototype.daysInMonth), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.daysInMonth), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.daysInMonth), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.Calendar.prototype.daysInMonth.hasOwnProperty("prototype"), + false, "prototype property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/calendar-datefromfields-called-with-options-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/calendar-datefromfields-called-with-options-undefined.js new file mode 100644 index 0000000000..f11712fa6f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/calendar-datefromfields-called-with-options-undefined.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.calendar.prototype.daysinmonth +description: > + Calendar.dateFromFields method is called with undefined as the options value + when call originates internally +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = TemporalHelpers.calendarFromFieldsUndefinedOptions(); +calendar.daysInMonth({ year: 2000, month: 5, day: 3, calendar }); +assert.sameValue(calendar.dateFromFieldsCallCount, 1); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/calendar-fields-iterable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/calendar-fields-iterable.js new file mode 100644 index 0000000000..14e3c8580f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/calendar-fields-iterable.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.calendar.prototype.daysinmonth +description: Verify the result of calendar.fields() is treated correctly. +info: | + sec-temporal.calendar.prototype.daysinmonth step 4.a: + a. Set _dateOrDateTime_ to ? ToTemporalDate(_dateOrDateTime_). + sec-temporal-totemporaldate step 2.c: + c. Let _fieldNames_ be ? CalendarFields(_calendar_, « *"day"*, *"month"*, *"monthCode"*, *"year"* »). + sec-temporal-calendarfields step 4: + 4. Let _result_ be ? IterableToListOfType(_fieldsArray_, « String »). +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + "day", + "month", + "monthCode", + "year", +]; + +const calendar1 = TemporalHelpers.calendarFieldsIterable(); +const calendar2 = TemporalHelpers.calendarFieldsIterable(); +calendar1.daysInMonth({ year: 2000, month: 5, day: 2, calendar: calendar2 }); + +assert.sameValue(calendar1.fieldsCallCount, 0, "fields() method not called"); +assert.sameValue(calendar2.fieldsCallCount, 1, "fields() method called once"); +assert.compareArray(calendar2.fieldsCalledWith[0], expected, "fields() method called with correct args"); +assert(calendar2.iteratorExhausted[0], "iterated through the whole iterable"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/calendar-temporal-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/calendar-temporal-object.js new file mode 100644 index 0000000000..5d510c28d2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/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.calendar.prototype.daysinmonth +description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots +info: | + sec-temporal.calendar.prototype.daysinmonth step 4.a: + a. Set _dateOrDateTime_ to ? ToTemporalDate(_dateOrDateTime_). + sec-temporal-totemporaldate 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 calendar = new Temporal.Calendar("iso8601"); + calendar.daysInMonth({ year: 2000, month: 5, day: 2, calendar: temporalObject }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/infinity-throws-rangeerror.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/infinity-throws-rangeerror.js new file mode 100644 index 0000000000..674c209075 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/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.calendar.prototype.daysinmonth +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); +const base = { year: 2000, month: 5, day: 2 }; + +[Infinity, -Infinity].forEach((inf) => { + ["year", "month", "day"].forEach((prop) => { + assert.throws(RangeError, () => instance.daysInMonth({ ...base, [prop]: inf }), `${prop} property cannot be ${inf}`); + + const calls = []; + const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop); + assert.throws(RangeError, () => instance.daysInMonth({ ...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/Calendar/prototype/daysInMonth/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/length.js new file mode 100644 index 0000000000..8216ecf055 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/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.calendar.prototype.daysinmonth +description: Temporal.Calendar.prototype.daysInMonth.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.Calendar.prototype.daysInMonth, "length", { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/name.js new file mode 100644 index 0000000000..c2e238c756 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/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.calendar.prototype.daysinmonth +description: Temporal.Calendar.prototype.daysInMonth.name is "daysInMonth". +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.Calendar.prototype.daysInMonth, "name", { + value: "daysInMonth", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/not-a-constructor.js new file mode 100644 index 0000000000..7e0029ff33 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/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.calendar.prototype.daysinmonth +description: > + Temporal.Calendar.prototype.daysInMonth 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.Calendar.prototype.daysInMonth(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.Calendar.prototype.daysInMonth), false, + "isConstructor(Temporal.Calendar.prototype.daysInMonth)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/plain-date-time.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/plain-date-time.js new file mode 100644 index 0000000000..a220cde06e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/plain-date-time.js @@ -0,0 +1,116 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-temporal.calendar.prototype.daysinmonth +description: > + Temporal.Calendar.prototype.daysInMonth will take Temporal.PlainDateTime object + and return the number of days in that month. +info: | + 4. If Type(temporalDateLike) is not Object or temporalDateLike does not have an [[InitializedTemporalDate]] or [[InitializedTemporalYearMonth]] internal slots, then + a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike). + 5. Return 𝔽(! ISODaysInMonth(temporalDateLike.[[ISOYear]], temporalDateLike.[[ISOMonth]])). +features: [Temporal] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +let dt = new Temporal.PlainDateTime(1997, 1, 23, 5, 30, 13); +assert.sameValue( + cal.daysInMonth(dt), + 31, + 'cal.daysInMonth(new Temporal.PlainDateTime(1997, 1, 23, 5, 30, 13)) must return 31' +); + +// leap year +dt = new Temporal.PlainDateTime(1996, 2, 23, 5, 30, 13); +assert.sameValue( + cal.daysInMonth(dt), + 29, + 'cal.daysInMonth(new Temporal.PlainDateTime(1996, 2, 23, 5, 30, 13)) must return 29' +); +dt = new Temporal.PlainDateTime(2000, 2, 23, 5, 30, 13); +assert.sameValue( + cal.daysInMonth(dt), + 29, + 'cal.daysInMonth(new Temporal.PlainDateTime(2000, 2, 23, 5, 30, 13)) must return 29' +); + +// non leap year +dt = new Temporal.PlainDateTime(1997, 2, 23, 5, 30, 13); +assert.sameValue( + cal.daysInMonth(dt), + 28, + 'cal.daysInMonth(new Temporal.PlainDateTime(1997, 2, 23, 5, 30, 13)) must return 28' +); + +dt = new Temporal.PlainDateTime(1997, 3, 23, 5, 30, 13); +assert.sameValue( + cal.daysInMonth(dt), + 31, + 'cal.daysInMonth(new Temporal.PlainDateTime(1997, 3, 23, 5, 30, 13)) must return 31' +); + +dt = new Temporal.PlainDateTime(1997, 4, 23, 5, 30, 13); +assert.sameValue( + cal.daysInMonth(dt), + 30, + 'cal.daysInMonth(new Temporal.PlainDateTime(1997, 4, 23, 5, 30, 13)) must return 30' +); + +dt = new Temporal.PlainDateTime(1997, 5, 23, 5, 30, 13); +assert.sameValue( + cal.daysInMonth(dt), + 31, + 'cal.daysInMonth(new Temporal.PlainDateTime(1997, 5, 23, 5, 30, 13)) must return 31' +); + +dt = new Temporal.PlainDateTime(1997, 6, 23, 5, 30, 13); +assert.sameValue( + cal.daysInMonth(dt), + 30, + 'cal.daysInMonth(new Temporal.PlainDateTime(1997, 6, 23, 5, 30, 13)) must return 30' +); + +dt = new Temporal.PlainDateTime(1997, 7, 23, 5, 30, 13); +assert.sameValue( + cal.daysInMonth(dt), + 31, + 'cal.daysInMonth(new Temporal.PlainDateTime(1997, 7, 23, 5, 30, 13)) must return 31' +); + +dt = new Temporal.PlainDateTime(1997, 8, 23, 5, 30, 13); +assert.sameValue( + cal.daysInMonth(dt), + 31, + 'cal.daysInMonth(new Temporal.PlainDateTime(1997, 8, 23, 5, 30, 13)) must return 31' +); + +dt = new Temporal.PlainDateTime(1997, 9, 23, 5, 30, 13); +assert.sameValue( + cal.daysInMonth(dt), + 30, + 'cal.daysInMonth(new Temporal.PlainDateTime(1997, 9, 23, 5, 30, 13)) must return 30' +); + +dt = new Temporal.PlainDateTime(1997, 10, 23, 5, 30, 13); +assert.sameValue( + cal.daysInMonth(dt), + 31, + 'cal.daysInMonth(new Temporal.PlainDateTime(1997, 10, 23, 5, 30, 13)) must return 31' +); + +dt = new Temporal.PlainDateTime(1997, 11, 23, 5, 30, 13); +assert.sameValue( + cal.daysInMonth(dt), + 30, + 'cal.daysInMonth(new Temporal.PlainDateTime(1997, 11, 23, 5, 30, 13)) must return 30' +); + +dt = new Temporal.PlainDateTime(1997, 12, 23, 5, 30, 13); +assert.sameValue( + cal.daysInMonth(dt), + 31, + 'cal.daysInMonth(new Temporal.PlainDateTime(1997, 12, 23, 5, 30, 13)) must return 31' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/plain-date.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/plain-date.js new file mode 100644 index 0000000000..743b5f48d1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/plain-date.js @@ -0,0 +1,58 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-temporal.calendar.prototype.daysinmonth +description: > + Temporal.Calendar.prototype.daysInMonth will take Temporal.PlainDate object + and return the number of days in that month. +info: | + 5. Return 𝔽(! ISODaysInMonth(temporalDateLike.[[ISOYear]], temporalDateLike.[[ISOMonth]])). +features: [Temporal] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +let d = new Temporal.PlainDate(2021, 1, 15); +assert.sameValue(cal.daysInMonth(d), 31, 'cal.daysInMonth(new Temporal.PlainDate(2021, 1, 15)) must return 31'); + +// non-leap year +d = new Temporal.PlainDate(2021, 2, 15); +assert.sameValue(cal.daysInMonth(d), 28, 'cal.daysInMonth(new Temporal.PlainDate(2021, 2, 15)) must return 28'); + +// leap year +d = new Temporal.PlainDate(2020, 2, 15); +assert.sameValue(cal.daysInMonth(d), 29, 'cal.daysInMonth(new Temporal.PlainDate(2020, 2, 15)) must return 29'); +d = new Temporal.PlainDate(2000, 2, 15); +assert.sameValue(cal.daysInMonth(d), 29, 'cal.daysInMonth(new Temporal.PlainDate(2000, 2, 15)) must return 29'); + +d = new Temporal.PlainDate(2021, 3, 15); +assert.sameValue(cal.daysInMonth(d), 31, 'cal.daysInMonth(new Temporal.PlainDate(2021, 3, 15)) must return 31'); + +d = new Temporal.PlainDate(2021, 4, 15); +assert.sameValue(cal.daysInMonth(d), 30, 'cal.daysInMonth(new Temporal.PlainDate(2021, 4, 15)) must return 30'); + +d = new Temporal.PlainDate(2021, 5, 15); +assert.sameValue(cal.daysInMonth(d), 31, 'cal.daysInMonth(new Temporal.PlainDate(2021, 5, 15)) must return 31'); + +d = new Temporal.PlainDate(2021, 6, 15); +assert.sameValue(cal.daysInMonth(d), 30, 'cal.daysInMonth(new Temporal.PlainDate(2021, 6, 15)) must return 30'); + +d = new Temporal.PlainDate(2021, 7, 15); +assert.sameValue(cal.daysInMonth(d), 31, 'cal.daysInMonth(new Temporal.PlainDate(2021, 7, 15)) must return 31'); + +d = new Temporal.PlainDate(2021, 8, 15); +assert.sameValue(cal.daysInMonth(d), 31, 'cal.daysInMonth(new Temporal.PlainDate(2021, 8, 15)) must return 31'); + +d = new Temporal.PlainDate(2021, 9, 15); +assert.sameValue(cal.daysInMonth(d), 30, 'cal.daysInMonth(new Temporal.PlainDate(2021, 9, 15)) must return 30'); + +d = new Temporal.PlainDate(2021, 10, 15); +assert.sameValue(cal.daysInMonth(d), 31, 'cal.daysInMonth(new Temporal.PlainDate(2021, 10, 15)) must return 31'); + +d = new Temporal.PlainDate(2021, 11, 15); +assert.sameValue(cal.daysInMonth(d), 30, 'cal.daysInMonth(new Temporal.PlainDate(2021, 11, 15)) must return 30'); + +d = new Temporal.PlainDate(2021, 12, 15); +assert.sameValue(cal.daysInMonth(d), 31, 'cal.daysInMonth(new Temporal.PlainDate(2021, 12, 15)) must return 31'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/prop-desc.js new file mode 100644 index 0000000000..182387a01f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/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.calendar.prototype.daysinmonth +description: The "daysInMonth" property of Temporal.Calendar.prototype +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.Calendar.prototype.daysInMonth, + "function", + "`typeof Calendar.prototype.daysInMonth` is `function`" +); + +verifyProperty(Temporal.Calendar.prototype, "daysInMonth", { + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/shell.js new file mode 100644 index 0000000000..eda1477282 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/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/Calendar/prototype/daysInMonth/string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/string.js new file mode 100644 index 0000000000..e630334f57 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/string.js @@ -0,0 +1,35 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-temporal.calendar.prototype.daysinmonth +description: > + Temporal.Calendar.prototype.daysInMonth will take ISO8601 string + and return the number of days in that month. +info: | + 4. If Type(temporalDateLike) is not Object or temporalDateLike does not have + an [[InitializedTemporalDate]] or [[InitializedTemporalYearMonth]] internal + slots, then + a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike). + 5. Return 𝔽(! ISODaysInMonth(temporalDateLike.[[ISOYear]], temporalDateLike.[[ISOMonth]])). +features: [Temporal] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +assert.sameValue(cal.daysInMonth("2019-01-18"), 31, 'cal.daysInMonth("2019-01-18") must return 31'); +// leap year +assert.sameValue(cal.daysInMonth("2020-02-18"), 29, 'cal.daysInMonth("2020-02-18") must return 29'); +// non leap +assert.sameValue(cal.daysInMonth("2019-02-18"), 28, 'cal.daysInMonth("2019-02-18") must return 28'); +assert.sameValue(cal.daysInMonth("2019-03-18"), 31, 'cal.daysInMonth("2019-03-18") must return 31'); +assert.sameValue(cal.daysInMonth("2019-04-18"), 30, 'cal.daysInMonth("2019-04-18") must return 30'); +assert.sameValue(cal.daysInMonth("2019-05-18"), 31, 'cal.daysInMonth("2019-05-18") must return 31'); +assert.sameValue(cal.daysInMonth("2019-06-18"), 30, 'cal.daysInMonth("2019-06-18") must return 30'); +assert.sameValue(cal.daysInMonth("2019-07-18"), 31, 'cal.daysInMonth("2019-07-18") must return 31'); +assert.sameValue(cal.daysInMonth("2019-08-18"), 31, 'cal.daysInMonth("2019-08-18") must return 31'); +assert.sameValue(cal.daysInMonth("2019-09-18"), 30, 'cal.daysInMonth("2019-09-18") must return 30'); +assert.sameValue(cal.daysInMonth("2019-10-18"), 31, 'cal.daysInMonth("2019-10-18") must return 31'); +assert.sameValue(cal.daysInMonth("2019-11-18"), 30, 'cal.daysInMonth("2019-11-18") must return 30'); +assert.sameValue(cal.daysInMonth("2019-12-18"), 31, 'cal.daysInMonth("2019-12-18") must return 31'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/throw-range-error-ToTemporalDate.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/throw-range-error-ToTemporalDate.js new file mode 100644 index 0000000000..78211a0f83 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/throw-range-error-ToTemporalDate.js @@ -0,0 +1,21 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-temporal.calendar.prototype.daysInMonth +description: > + Temporal.Calendar.prototype.daysInMonth throws RangeError on + ToTemporalDate when temporalDateLike is invalid string. +info: | + 4. If Type(temporalDateLike) is not Object or temporalDateLike does not have + an [[InitializedTemporalDate]] or [[InitializedTemporalYearMonth]] internal + slots, then + a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike). +features: [Temporal, arrow-function] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +assert.throws(RangeError, () => cal.daysInMonth("invalid string"), + 'cal.daysInMonth("invalid string") throws a RangeError exception'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/year-zero.js new file mode 100644 index 0000000000..fa887a46e9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/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.calendar.prototype.daysinmonth +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.daysInMonth(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-calendar-datefromfields-called-with-null-prototype-fields.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-calendar-datefromfields-called-with-null-prototype-fields.js new file mode 100644 index 0000000000..d09833dd5a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-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.calendar.prototype.daysinweek +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.Calendar("iso8601"); +const arg = { year: 2000, month: 5, day: 2, calendar }; +instance.daysInWeek(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/Calendar/prototype/daysInWeek/argument-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-leap-second.js new file mode 100644 index 0000000000..084bbbe6e4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-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.calendar.prototype.daysinweek +description: Leap second is a valid ISO string for PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.daysInWeek(arg); +assert.sameValue( + result1, + 7, + "leap second is a valid ISO string for PlainDate" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.daysInWeek(arg); +assert.sameValue( + result2, + 7, + "second: 60 is ignored in property bag for PlainDate" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-number.js new file mode 100644 index 0000000000..184c1952ff --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/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.calendar.prototype.daysinweek +description: A number is converted to a string, then to Temporal.PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const arg = 19761118; + +const result = instance.daysInWeek(arg); +assert.sameValue(result, 7, "19761118 is a valid ISO string for PlainDate"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.daysInWeek(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-case-insensitive.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-case-insensitive.js new file mode 100644 index 0000000000..b6dc6eeb39 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/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.calendar.prototype.daysinweek +description: The calendar name is case-insensitive +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "IsO8601"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.daysInWeek(arg); +assert.sameValue(result1, 7, "Calendar is case-insensitive"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.daysInWeek(arg); +assert.sameValue(result2, 7, "Calendar is case-insensitive (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-instance-does-not-get-calendar-property.js new file mode 100644 index 0000000000..5b8d97d035 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/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.calendar.prototype.daysinweek +description: > + A Temporal.Calendar instance passed to daysInWeek() in a property bag does + not have its 'calendar' property observably checked +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +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.daysInWeek(arg); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +instance.daysInWeek(arg); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-leap-second.js new file mode 100644 index 0000000000..ce17da50a3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/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.calendar.prototype.daysinweek +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.daysInWeek(arg); +assert.sameValue( + result1, + 7, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.daysInWeek(arg); +assert.sameValue( + result2, + 7, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-number.js new file mode 100644 index 0000000000..9c8044c633 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/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.calendar.prototype.daysinweek +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.daysInWeek(arg); +assert.sameValue(result1, 7, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.daysInWeek(arg); +assert.sameValue(result2, 7, "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.daysInWeek(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.daysInWeek(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/Calendar/prototype/daysInWeek/argument-propertybag-calendar-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-string.js new file mode 100644 index 0000000000..b09687d84c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/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.calendar.prototype.daysinweek +description: A calendar ID is valid input for Calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "iso8601"; + +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.daysInWeek(arg); +assert.sameValue(result, 7, `Calendar created from string "${calendar}"`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 0000000000..62cad9b23b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/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.calendar.prototype.daysinweek +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.Calendar("iso8601"); + +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.daysInWeek(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.daysInWeek(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.daysInWeek(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.daysInWeek(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.daysInWeek(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-year-zero.js new file mode 100644 index 0000000000..611aa36476 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/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.calendar.prototype.daysinweek +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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.daysInWeek(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-calendar-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-calendar-annotation.js new file mode 100644 index 0000000000..f0d1b014b5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/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.calendar.prototype.daysinweek +description: Various forms of calendar annotation; critical flag has no effect +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02[u-ca=iso8601]", "without time or time zone"], + ["2000-05-02[UTC][u-ca=iso8601]", "with time zone and no time"], + ["2000-05-02T15:23[u-ca=iso8601]", "without time zone"], + ["2000-05-02T15:23[UTC][u-ca=iso8601]", "with time zone"], + ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], + ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], + ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], + ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.daysInWeek(arg); + + assert.sameValue( + result, + 7, + `calendar annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-critical-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-critical-unknown-annotation.js new file mode 100644 index 0000000000..122996a8e1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-critical-unknown-annotation.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.calendar.prototype.daysinweek +description: Unknown annotations with critical flag are rejected +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[!foo=bar]", + "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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.daysInWeek(arg), + `reject unknown annotation with critical flag: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-date-with-utc-offset.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-date-with-utc-offset.js new file mode 100644 index 0000000000..3fc7f239cc --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/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.calendar.prototype.daysinweek +description: UTC offset not valid with format that does not include a time +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const validStrings = [ + "2000-05-02T00+00:00", + "2000-05-02T00+00:00[UTC]", + "2000-05-02T00+00:00[!UTC]", + "2000-05-02T00-02:30[America/St_Johns]", +]; + +for (const arg of validStrings) { + const result = instance.daysInWeek(arg); + + assert.sameValue( + result, + 7, + `"${arg}" is a valid UTC offset with time for PlainDate` + ); +} + +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.daysInWeek(arg), + `"${arg}" UTC offset without time is not valid for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-invalid.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-invalid.js new file mode 100644 index 0000000000..209fcecb37 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-invalid.js @@ -0,0 +1,64 @@ +// |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.calendar.prototype.daysinweek +description: > + RangeError thrown if an invalid ISO string (or syntactically valid ISO string + that is not supported) is used as a PlainDate +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + // invalid ISO strings: + "", + "invalid iso8601", + "2020-01-00", + "2020-01-32", + "2020-02-30", + "2021-02-29", + "2020-00-01", + "2020-13-01", + "2020-01-01T", + "2020-01-01T25:00:00", + "2020-01-01T01:60:00", + "2020-01-01T01:60:61", + "2020-01-01junk", + "2020-01-01T00:00:00junk", + "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-01", + "2020-001-01", + "2020-01-001", + "2020-01-01T001", + "2020-01-01T01:001", + "2020-01-01T01:01:001", + // valid, but forms not supported in Temporal: + "2020-W01-1", + "2020-001", + "+0002020-01-01", + // valid, but this calendar must not exist: + "2020-01-01[u-ca=notexist]", + // may be valid in other contexts, but insufficient information for PlainDate: + "2020-01", + "+002020-01", + "01-01", + "2020-W01", + "P1Y", + "-P12Y", + // valid, but outside the supported range: + "-999999-01-01", + "+999999-01-01", +]; +const instance = new Temporal.Calendar("iso8601"); +for (const arg of invalidStrings) { + assert.throws( + RangeError, + () => instance.daysInWeek(arg), + `"${arg}" should not be a valid ISO string for a PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-multiple-time-zone.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-multiple-time-zone.js new file mode 100644 index 0000000000..5a85e8a742 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-multiple-time-zone.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.calendar.prototype.daysinweek +description: More than one time zone annotation is not syntactical +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[UTC][UTC]", + "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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.daysInWeek(arg), + `reject more than one time zone annotation: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-time-separators.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-time-separators.js new file mode 100644 index 0000000000..9940f445d2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/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.calendar.prototype.daysinweek +description: Time separator in string argument can vary +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02T15:23", "uppercase T"], + ["2000-05-02t15:23", "lowercase T"], + ["2000-05-02 15:23", "space between date and time"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.daysInWeek(arg); + + assert.sameValue( + result, + 7, + `variant time separators (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-time-zone-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-time-zone-annotation.js new file mode 100644 index 0000000000..0bdb791abd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-time-zone-annotation.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.calendar.prototype.daysinweek +description: Various forms of time zone annotation; critical flag has no effect +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02[Asia/Kolkata]", "named, with no time"], + ["2000-05-02[!Europe/Vienna]", "named, with ! and no time"], + ["2000-05-02[+00:00]", "numeric, with no time"], + ["2000-05-02[!-02:30]", "numeric, with ! and no time"], + ["2000-05-02T15:23[America/Sao_Paulo]", "named, with no offset"], + ["2000-05-02T15:23[!Asia/Tokyo]", "named, with ! and no offset"], + ["2000-05-02T15:23[-02:30]", "numeric, with no offset"], + ["2000-05-02T15:23[!+00:00]", "numeric, with ! and no offset"], + ["2000-05-02T15:23+00:00[America/New_York]", "named, with offset"], + ["2000-05-02T15:23+00:00[!UTC]", "named, with offset and !"], + ["2000-05-02T15:23+00:00[+01:00]", "numeric, with offset"], + ["2000-05-02T15:23+00:00[!-08:00]", "numeric, with offset and !"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.daysInWeek(arg); + + assert.sameValue( + result, + 7, + `time zone annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-unknown-annotation.js new file mode 100644 index 0000000000..1463a7da77 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/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.calendar.prototype.daysinweek +description: Various forms of unknown annotation +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02[foo=bar]", "without time"], + ["2000-05-02T15:23[foo=bar]", "alone"], + ["2000-05-02T15:23[UTC][foo=bar]", "with time zone"], + ["2000-05-02T15:23[u-ca=iso8601][foo=bar]", "with calendar"], + ["2000-05-02T15:23[UTC][foo=bar][u-ca=iso8601]", "with time zone and calendar"], + ["2000-05-02T15:23[foo=bar][_foo-bar0=Ignore-This-999999999999]", "with another unknown annotation"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.daysInWeek(arg); + + assert.sameValue( + result, + 7, + `unknown annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-with-utc-designator.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-with-utc-designator.js new file mode 100644 index 0000000000..819baf1222 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/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.calendar.prototype.daysinweek +description: RangeError thrown if a string with UTC designator is used as a PlainDate +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "2019-10-01T09:00:00Z", + "2019-10-01T09:00:00Z[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.daysInWeek(arg), + "String with UTC designator should not be valid as a PlainDate" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-wrong-type.js new file mode 100644 index 0000000000..81ece23888 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/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.calendar.prototype.daysinweek +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +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.daysInWeek(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.daysInWeek(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/Calendar/prototype/daysInWeek/argument-zoneddatetime-convert.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-zoneddatetime-convert.js new file mode 100644 index 0000000000..ce16779748 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-zoneddatetime-convert.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.calendar.prototype.daysinweek +description: An exception from TimeZone#getOffsetNanosecondsFor() is propagated. +features: [Temporal] +---*/ + +class TZ extends Temporal.TimeZone { + constructor() { super("UTC") } + getOffsetNanosecondsFor() { throw new Test262Error() } +} + +const tz = new TZ(); +const arg = new Temporal.ZonedDateTime(0n, tz); +const instance = new Temporal.Calendar("iso8601"); + +assert.throws(Test262Error, () => instance.daysInWeek(arg)); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-zoneddatetime-slots.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-zoneddatetime-slots.js new file mode 100644 index 0000000000..ab59892a9e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-zoneddatetime-slots.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.calendar.prototype.daysinweek +description: Getters are not called when converting a ZonedDateTime to a PlainDate. +includes: [compareArray.js] +features: [Temporal] +---*/ + +const actual = []; +const prototypeDescrs = Object.getOwnPropertyDescriptors(Temporal.ZonedDateTime.prototype); +const getters = ["year", "month", "monthCode", "day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond", "calendar"]; + +for (const property of getters) { + Object.defineProperty(Temporal.ZonedDateTime.prototype, property, { + get() { + actual.push(`get ${property}`); + const value = prototypeDescrs[property].get.call(this); + return { + toString() { + actual.push(`toString ${property}`); + return value.toString(); + }, + valueOf() { + actual.push(`valueOf ${property}`); + return value; + }, + }; + }, + }); +} + +const arg = new Temporal.ZonedDateTime(0n, "UTC"); +const instance = new Temporal.Calendar("iso8601"); +instance.daysInWeek(arg); +assert.compareArray(actual, []); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js new file mode 100644 index 0000000000..c16a696888 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/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.calendar.prototype.daysinweek +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(RangeError, () => calendar.daysInWeek(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js new file mode 100644 index 0000000000..9483b078d2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/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.calendar.prototype.daysinweek +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + timeZone.getOffsetNanosecondsFor = notCallable; + assert.throws( + TypeError, + () => calendar.daysInWeek(datetime), + `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js new file mode 100644 index 0000000000..f80314f471 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/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.calendar.prototype.daysinweek +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(RangeError, () => calendar.daysInWeek(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js new file mode 100644 index 0000000000..d4219f3bad --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/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.calendar.prototype.daysinweek +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(TypeError, () => calendar.daysInWeek(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/basic.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/basic.js new file mode 100644 index 0000000000..ab30cd5b02 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/basic.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.calendar.prototype.daysinweek +description: Basic tests for daysInWeek(). +features: [Temporal] +---*/ + +const iso = Temporal.Calendar.from("iso8601"); +const res = 7; +assert.sameValue(iso.daysInWeek(Temporal.PlainDate.from("1994-11-05")), res, "PlainDate"); +assert.sameValue(iso.daysInWeek(Temporal.PlainDateTime.from("1994-11-05T08:15:30")), res, "PlainDateTime"); +assert.sameValue(iso.daysInWeek({ year: 1994, month: 11, day: 5 }), res, "property bag"); +assert.sameValue(iso.daysInWeek("1994-11-05"), res, "string"); +assert.throws(TypeError, () => iso.daysInWeek({ year: 2000 }), "property bag with missing properties"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/branding.js new file mode 100644 index 0000000000..ef16b220e6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/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.calendar.prototype.daysinweek +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const daysInWeek = Temporal.Calendar.prototype.daysInWeek; + +assert.sameValue(typeof daysInWeek, "function"); + +const args = [new Temporal.PlainDate(2000, 1, 1)]; + +assert.throws(TypeError, () => daysInWeek.apply(undefined, args), "undefined"); +assert.throws(TypeError, () => daysInWeek.apply(null, args), "null"); +assert.throws(TypeError, () => daysInWeek.apply(true, args), "true"); +assert.throws(TypeError, () => daysInWeek.apply("", args), "empty string"); +assert.throws(TypeError, () => daysInWeek.apply(Symbol(), args), "symbol"); +assert.throws(TypeError, () => daysInWeek.apply(1, args), "1"); +assert.throws(TypeError, () => daysInWeek.apply({}, args), "plain object"); +assert.throws(TypeError, () => daysInWeek.apply(Temporal.Calendar, args), "Temporal.Calendar"); +assert.throws(TypeError, () => daysInWeek.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/builtin.js new file mode 100644 index 0000000000..2132e3beaf --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/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.calendar.prototype.daysinweek +description: > + Tests that Temporal.Calendar.prototype.daysInWeek + 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.Calendar.prototype.daysInWeek), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.daysInWeek), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.daysInWeek), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.Calendar.prototype.daysInWeek.hasOwnProperty("prototype"), + false, "prototype property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/calendar-datefromfields-called-with-options-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/calendar-datefromfields-called-with-options-undefined.js new file mode 100644 index 0000000000..1c6aa70726 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/calendar-datefromfields-called-with-options-undefined.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.calendar.prototype.daysinweek +description: > + Calendar.dateFromFields method is called with undefined as the options value + when call originates internally +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = TemporalHelpers.calendarFromFieldsUndefinedOptions(); +calendar.daysInWeek({ year: 2000, month: 5, day: 3, calendar }); +assert.sameValue(calendar.dateFromFieldsCallCount, 1); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/calendar-fields-iterable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/calendar-fields-iterable.js new file mode 100644 index 0000000000..a3524e383e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/calendar-fields-iterable.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.calendar.prototype.daysinweek +description: Verify the result of calendar.fields() is treated correctly. +info: | + sec-temporal.calendar.prototype.daysinweek step 4: + 4. Perform ? ToTemporalDate(_dateOrDateTime_). + sec-temporal-totemporaldate step 2.c: + c. Let _fieldNames_ be ? CalendarFields(_calendar_, « *"day"*, *"month"*, *"monthCode"*, *"year"* »). + sec-temporal-calendarfields step 4: + 4. Let _result_ be ? IterableToListOfType(_fieldsArray_, « String »). +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + "day", + "month", + "monthCode", + "year", +]; + +const calendar1 = TemporalHelpers.calendarFieldsIterable(); +const calendar2 = TemporalHelpers.calendarFieldsIterable(); +calendar1.daysInWeek({ year: 2000, month: 5, day: 2, calendar: calendar2 }); + +assert.sameValue(calendar1.fieldsCallCount, 0, "fields() method not called"); +assert.sameValue(calendar2.fieldsCallCount, 1, "fields() method called once"); +assert.compareArray(calendar2.fieldsCalledWith[0], expected, "fields() method called with correct args"); +assert(calendar2.iteratorExhausted[0], "iterated through the whole iterable"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/calendar-temporal-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/calendar-temporal-object.js new file mode 100644 index 0000000000..5bf65e14c1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/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.calendar.prototype.daysinweek +description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots +info: | + sec-temporal.calendar.prototype.daysinweek step 4: + 4. Perform ? ToTemporalDate(_dateOrDateTime_). + sec-temporal-totemporaldate 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 calendar = new Temporal.Calendar("iso8601"); + calendar.daysInWeek({ year: 2000, month: 5, day: 2, calendar: temporalObject }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/date-time.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/date-time.js new file mode 100644 index 0000000000..f09c35cd28 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/date-time.js @@ -0,0 +1,21 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-temporal.calendar.prototype.daysinweeks +description: Temporal.Calendar.prototype.daysInWeek will take PlainDateTime and return 7. +info: | + 4. Perform ? ToTemporalDate(temporalDateLike). + 5. Return 7𝔽. +features: [Temporal] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +let dt = new Temporal.PlainDateTime(1997, 8, 23, 5, 30, 13); +assert.sameValue( + cal.daysInWeek(dt), + 7, + 'cal.daysInWeek(new Temporal.PlainDateTime(1997, 8, 23, 5, 30, 13)) must return 7' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/date.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/date.js new file mode 100644 index 0000000000..aaff6236b8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/date.js @@ -0,0 +1,16 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-temporal.calendar.prototype.daysinweeks +description: Temporal.Calendar.prototype.daysInWeek will take PlainDate and return 7. +info: | + 5. Return 7𝔽. +features: [Temporal] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +let d = new Temporal.PlainDate(2021, 7, 15); +assert.sameValue(cal.daysInWeek(d), 7, 'cal.daysInWeek(new Temporal.PlainDate(2021, 7, 15)) must return 7'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/infinity-throws-rangeerror.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/infinity-throws-rangeerror.js new file mode 100644 index 0000000000..9725ae948d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/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.calendar.prototype.daysinweek +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); +const base = { year: 2000, month: 5, day: 2 }; + +[Infinity, -Infinity].forEach((inf) => { + ["year", "month", "day"].forEach((prop) => { + assert.throws(RangeError, () => instance.daysInWeek({ ...base, [prop]: inf }), `${prop} property cannot be ${inf}`); + + const calls = []; + const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop); + assert.throws(RangeError, () => instance.daysInWeek({ ...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/Calendar/prototype/daysInWeek/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/length.js new file mode 100644 index 0000000000..3467236572 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/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.calendar.prototype.daysinweek +description: Temporal.Calendar.prototype.daysInWeek.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.Calendar.prototype.daysInWeek, "length", { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/name.js new file mode 100644 index 0000000000..404f287f0c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/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.calendar.prototype.daysinweek +description: Temporal.Calendar.prototype.daysInWeek.name is "daysInWeek". +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.Calendar.prototype.daysInWeek, "name", { + value: "daysInWeek", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/not-a-constructor.js new file mode 100644 index 0000000000..9b7a8fb3ea --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/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.calendar.prototype.daysinweek +description: > + Temporal.Calendar.prototype.daysInWeek 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.Calendar.prototype.daysInWeek(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.Calendar.prototype.daysInWeek), false, + "isConstructor(Temporal.Calendar.prototype.daysInWeek)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/prop-desc.js new file mode 100644 index 0000000000..1354d32a7b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/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.calendar.prototype.daysinweek +description: The "daysInWeek" property of Temporal.Calendar.prototype +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.Calendar.prototype.daysInWeek, + "function", + "`typeof Calendar.prototype.daysInWeek` is `function`" +); + +verifyProperty(Temporal.Calendar.prototype, "daysInWeek", { + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/shell.js new file mode 100644 index 0000000000..eda1477282 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/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/Calendar/prototype/daysInWeek/string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/string.js new file mode 100644 index 0000000000..1ad83b4e57 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/string.js @@ -0,0 +1,17 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-temporal.calendar.prototype.daysinweeks +description: > + Temporal.Calendar.prototype.daysInWeek will take valid ISO8601 string + and return 7. +info: | + 4. Perform ? ToTemporalDate(temporalDateLike). + 5. Return 7𝔽. +features: [Temporal] +---*/ +let cal = new Temporal.Calendar("iso8601"); +assert.sameValue(cal.daysInWeek("2019-03-18"), 7, 'cal.daysInWeek("2019-03-18") must return 7'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/throw-range-error-ToTemporalDate.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/throw-range-error-ToTemporalDate.js new file mode 100644 index 0000000000..def7d2aa74 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/throw-range-error-ToTemporalDate.js @@ -0,0 +1,18 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-temporal.calendar.prototype.daysInWeek +description: > + Temporal.Calendar.prototype.daysInWeek throws RangeError on + ToTemporalDate when temporalDateLike is invalid string. +info: | + 4. Let temporalDate be ? ToTemporalDate(temporalDateLike). +features: [Temporal, arrow-function] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +assert.throws(RangeError, () => cal.daysInWeek("invalid string"), + 'cal.daysInWeek("invalid string") throws a RangeError exception'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/year-zero.js new file mode 100644 index 0000000000..62970bbb7d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/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.calendar.prototype.daysinweek +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.daysInWeek(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-calendar-datefromfields-called-with-null-prototype-fields.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-calendar-datefromfields-called-with-null-prototype-fields.js new file mode 100644 index 0000000000..37fea2b216 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-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.calendar.prototype.daysinyear +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.Calendar("iso8601"); +const arg = { year: 2000, month: 5, day: 2, calendar }; +instance.daysInYear(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/Calendar/prototype/daysInYear/argument-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-leap-second.js new file mode 100644 index 0000000000..27f3739a8f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-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.calendar.prototype.daysinyear +description: Leap second is a valid ISO string for PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.daysInYear(arg); +assert.sameValue( + result1, + 366, + "leap second is a valid ISO string for PlainDate" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.daysInYear(arg); +assert.sameValue( + result2, + 366, + "second: 60 is ignored in property bag for PlainDate" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-number.js new file mode 100644 index 0000000000..51b3bb26ac --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/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.calendar.prototype.daysinyear +description: A number is converted to a string, then to Temporal.PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const arg = 19761118; + +const result = instance.daysInYear(arg); +assert.sameValue(result, 366, "19761118 is a valid ISO string for PlainDate"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.daysInYear(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-case-insensitive.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-case-insensitive.js new file mode 100644 index 0000000000..e8c14ce5d4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/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.calendar.prototype.daysinyear +description: The calendar name is case-insensitive +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "IsO8601"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.daysInYear(arg); +assert.sameValue(result1, 366, "Calendar is case-insensitive"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.daysInYear(arg); +assert.sameValue(result2, 366, "Calendar is case-insensitive (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js new file mode 100644 index 0000000000..76aa5f4fd7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/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.calendar.prototype.daysinyear +description: > + A Temporal.Calendar instance passed to daysInYear() in a property bag does + not have its 'calendar' property observably checked +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +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.daysInYear(arg); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +instance.daysInYear(arg); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-leap-second.js new file mode 100644 index 0000000000..8ff437c8a8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/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.calendar.prototype.daysinyear +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.daysInYear(arg); +assert.sameValue( + result1, + 366, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.daysInYear(arg); +assert.sameValue( + result2, + 366, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-number.js new file mode 100644 index 0000000000..2c0fe356db --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/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.calendar.prototype.daysinyear +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.daysInYear(arg); +assert.sameValue(result1, 366, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.daysInYear(arg); +assert.sameValue(result2, 366, "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.daysInYear(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.daysInYear(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/Calendar/prototype/daysInYear/argument-propertybag-calendar-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-string.js new file mode 100644 index 0000000000..50164d30a5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/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.calendar.prototype.daysinyear +description: A calendar ID is valid input for Calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "iso8601"; + +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.daysInYear(arg); +assert.sameValue(result, 366, `Calendar created from string "${calendar}"`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 0000000000..37330243ae --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/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.calendar.prototype.daysinyear +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.Calendar("iso8601"); + +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.daysInYear(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.daysInYear(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.daysInYear(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.daysInYear(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.daysInYear(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-year-zero.js new file mode 100644 index 0000000000..f8ef34a4db --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/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.calendar.prototype.daysinyear +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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.daysInYear(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-calendar-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-calendar-annotation.js new file mode 100644 index 0000000000..925e106698 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/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.calendar.prototype.daysinyear +description: Various forms of calendar annotation; critical flag has no effect +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02[u-ca=iso8601]", "without time or time zone"], + ["2000-05-02[UTC][u-ca=iso8601]", "with time zone and no time"], + ["2000-05-02T15:23[u-ca=iso8601]", "without time zone"], + ["2000-05-02T15:23[UTC][u-ca=iso8601]", "with time zone"], + ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], + ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], + ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], + ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.daysInYear(arg); + + assert.sameValue( + result, + 366, + `calendar annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-critical-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-critical-unknown-annotation.js new file mode 100644 index 0000000000..7ef473b90d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-critical-unknown-annotation.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.calendar.prototype.daysinyear +description: Unknown annotations with critical flag are rejected +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[!foo=bar]", + "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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.daysInYear(arg), + `reject unknown annotation with critical flag: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-date-with-utc-offset.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-date-with-utc-offset.js new file mode 100644 index 0000000000..31f95c2150 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/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.calendar.prototype.daysinyear +description: UTC offset not valid with format that does not include a time +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const validStrings = [ + "2000-05-02T00+00:00", + "2000-05-02T00+00:00[UTC]", + "2000-05-02T00+00:00[!UTC]", + "2000-05-02T00-02:30[America/St_Johns]", +]; + +for (const arg of validStrings) { + const result = instance.daysInYear(arg); + + assert.sameValue( + result, + 366, + `"${arg}" is a valid UTC offset with time for PlainDate` + ); +} + +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.daysInYear(arg), + `"${arg}" UTC offset without time is not valid for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-invalid.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-invalid.js new file mode 100644 index 0000000000..99b391d430 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-invalid.js @@ -0,0 +1,64 @@ +// |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.calendar.prototype.daysinyear +description: > + RangeError thrown if an invalid ISO string (or syntactically valid ISO string + that is not supported) is used as a PlainDate +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + // invalid ISO strings: + "", + "invalid iso8601", + "2020-01-00", + "2020-01-32", + "2020-02-30", + "2021-02-29", + "2020-00-01", + "2020-13-01", + "2020-01-01T", + "2020-01-01T25:00:00", + "2020-01-01T01:60:00", + "2020-01-01T01:60:61", + "2020-01-01junk", + "2020-01-01T00:00:00junk", + "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-01", + "2020-001-01", + "2020-01-001", + "2020-01-01T001", + "2020-01-01T01:001", + "2020-01-01T01:01:001", + // valid, but forms not supported in Temporal: + "2020-W01-1", + "2020-001", + "+0002020-01-01", + // valid, but this calendar must not exist: + "2020-01-01[u-ca=notexist]", + // may be valid in other contexts, but insufficient information for PlainDate: + "2020-01", + "+002020-01", + "01-01", + "2020-W01", + "P1Y", + "-P12Y", + // valid, but outside the supported range: + "-999999-01-01", + "+999999-01-01", +]; +const instance = new Temporal.Calendar("iso8601"); +for (const arg of invalidStrings) { + assert.throws( + RangeError, + () => instance.daysInYear(arg), + `"${arg}" should not be a valid ISO string for a PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-multiple-time-zone.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-multiple-time-zone.js new file mode 100644 index 0000000000..8ca31dfca0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-multiple-time-zone.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.calendar.prototype.daysinyear +description: More than one time zone annotation is not syntactical +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[UTC][UTC]", + "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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.daysInYear(arg), + `reject more than one time zone annotation: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-time-separators.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-time-separators.js new file mode 100644 index 0000000000..a50fc2459b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/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.calendar.prototype.daysinyear +description: Time separator in string argument can vary +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02T15:23", "uppercase T"], + ["2000-05-02t15:23", "lowercase T"], + ["2000-05-02 15:23", "space between date and time"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.daysInYear(arg); + + assert.sameValue( + result, + 366, + `variant time separators (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-time-zone-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-time-zone-annotation.js new file mode 100644 index 0000000000..3bd4e7a0ef --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-time-zone-annotation.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.calendar.prototype.daysinyear +description: Various forms of time zone annotation; critical flag has no effect +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02[Asia/Kolkata]", "named, with no time"], + ["2000-05-02[!Europe/Vienna]", "named, with ! and no time"], + ["2000-05-02[+00:00]", "numeric, with no time"], + ["2000-05-02[!-02:30]", "numeric, with ! and no time"], + ["2000-05-02T15:23[America/Sao_Paulo]", "named, with no offset"], + ["2000-05-02T15:23[!Asia/Tokyo]", "named, with ! and no offset"], + ["2000-05-02T15:23[-02:30]", "numeric, with no offset"], + ["2000-05-02T15:23[!+00:00]", "numeric, with ! and no offset"], + ["2000-05-02T15:23+00:00[America/New_York]", "named, with offset"], + ["2000-05-02T15:23+00:00[!UTC]", "named, with offset and !"], + ["2000-05-02T15:23+00:00[+01:00]", "numeric, with offset"], + ["2000-05-02T15:23+00:00[!-08:00]", "numeric, with offset and !"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.daysInYear(arg); + + assert.sameValue( + result, + 366, + `time zone annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-unknown-annotation.js new file mode 100644 index 0000000000..795755857e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/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.calendar.prototype.daysinyear +description: Various forms of unknown annotation +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02[foo=bar]", "without time"], + ["2000-05-02T15:23[foo=bar]", "alone"], + ["2000-05-02T15:23[UTC][foo=bar]", "with time zone"], + ["2000-05-02T15:23[u-ca=iso8601][foo=bar]", "with calendar"], + ["2000-05-02T15:23[UTC][foo=bar][u-ca=iso8601]", "with time zone and calendar"], + ["2000-05-02T15:23[foo=bar][_foo-bar0=Ignore-This-999999999999]", "with another unknown annotation"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.daysInYear(arg); + + assert.sameValue( + result, + 366, + `unknown annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-with-utc-designator.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-with-utc-designator.js new file mode 100644 index 0000000000..fb34d2818a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/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.calendar.prototype.daysinyear +description: RangeError thrown if a string with UTC designator is used as a PlainDate +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "2019-10-01T09:00:00Z", + "2019-10-01T09:00:00Z[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.daysInYear(arg), + "String with UTC designator should not be valid as a PlainDate" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-wrong-type.js new file mode 100644 index 0000000000..40900bb96f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/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.calendar.prototype.daysinyear +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +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.daysInYear(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.daysInYear(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/Calendar/prototype/daysInYear/argument-zoneddatetime-convert.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-zoneddatetime-convert.js new file mode 100644 index 0000000000..ce36ebd01a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-zoneddatetime-convert.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.calendar.prototype.daysinyear +description: An exception from TimeZone#getOffsetNanosecondsFor() is propagated. +features: [Temporal] +---*/ + +class TZ extends Temporal.TimeZone { + constructor() { super("UTC") } + getOffsetNanosecondsFor() { throw new Test262Error() } +} + +const tz = new TZ(); +const arg = new Temporal.ZonedDateTime(0n, tz); +const instance = new Temporal.Calendar("iso8601"); + +assert.throws(Test262Error, () => instance.daysInYear(arg)); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-zoneddatetime-slots.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-zoneddatetime-slots.js new file mode 100644 index 0000000000..0ad8f67ee8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-zoneddatetime-slots.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.calendar.prototype.daysinyear +description: Getters are not called when converting a ZonedDateTime to a PlainDate. +includes: [compareArray.js] +features: [Temporal] +---*/ + +const actual = []; +const prototypeDescrs = Object.getOwnPropertyDescriptors(Temporal.ZonedDateTime.prototype); +const getters = ["year", "month", "monthCode", "day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond", "calendar"]; + +for (const property of getters) { + Object.defineProperty(Temporal.ZonedDateTime.prototype, property, { + get() { + actual.push(`get ${property}`); + const value = prototypeDescrs[property].get.call(this); + return { + toString() { + actual.push(`toString ${property}`); + return value.toString(); + }, + valueOf() { + actual.push(`valueOf ${property}`); + return value; + }, + }; + }, + }); +} + +const arg = new Temporal.ZonedDateTime(0n, "UTC"); +const instance = new Temporal.Calendar("iso8601"); +instance.daysInYear(arg); +assert.compareArray(actual, []); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js new file mode 100644 index 0000000000..fd6367a981 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/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.calendar.prototype.daysinyear +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(RangeError, () => calendar.daysInYear(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js new file mode 100644 index 0000000000..009dd8890a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/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.calendar.prototype.daysinyear +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + timeZone.getOffsetNanosecondsFor = notCallable; + assert.throws( + TypeError, + () => calendar.daysInYear(datetime), + `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js new file mode 100644 index 0000000000..a379f15d30 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/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.calendar.prototype.daysinyear +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(RangeError, () => calendar.daysInYear(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js new file mode 100644 index 0000000000..29ed0f857c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/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.calendar.prototype.daysinyear +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(TypeError, () => calendar.daysInYear(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/basic.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/basic.js new file mode 100644 index 0000000000..1513e88bdd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/basic.js @@ -0,0 +1,20 @@ +// |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.calendar.prototype.daysinyear +description: Basic tests for daysInYear(). +features: [Temporal] +---*/ + +const iso = Temporal.Calendar.from("iso8601"); +const res = 365; +assert.sameValue(iso.daysInYear(Temporal.PlainDate.from("1994-11-05")), res, "PlainDate"); +assert.sameValue(iso.daysInYear(Temporal.PlainDateTime.from("1994-11-05T08:15:30")), res, "PlainDateTime"); +assert.sameValue(iso.daysInYear(Temporal.PlainYearMonth.from("1994-11")), res, "PlainYearMonth"); +assert.sameValue(iso.daysInYear({ year: 1994, month: 11, day: 5 }), res, "property bag"); +assert.sameValue(iso.daysInYear("1994-11-05"), res, "string"); +assert.throws(TypeError, () => iso.daysInYear({ year: 2000 }), "property bag with missing properties"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/branding.js new file mode 100644 index 0000000000..1a31ce8cc4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/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.calendar.prototype.daysinyear +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const daysInYear = Temporal.Calendar.prototype.daysInYear; + +assert.sameValue(typeof daysInYear, "function"); + +const args = [new Temporal.PlainDate(2000, 1, 1)]; + +assert.throws(TypeError, () => daysInYear.apply(undefined, args), "undefined"); +assert.throws(TypeError, () => daysInYear.apply(null, args), "null"); +assert.throws(TypeError, () => daysInYear.apply(true, args), "true"); +assert.throws(TypeError, () => daysInYear.apply("", args), "empty string"); +assert.throws(TypeError, () => daysInYear.apply(Symbol(), args), "symbol"); +assert.throws(TypeError, () => daysInYear.apply(1, args), "1"); +assert.throws(TypeError, () => daysInYear.apply({}, args), "plain object"); +assert.throws(TypeError, () => daysInYear.apply(Temporal.Calendar, args), "Temporal.Calendar"); +assert.throws(TypeError, () => daysInYear.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/builtin.js new file mode 100644 index 0000000000..868718c235 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/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.calendar.prototype.daysinyear +description: > + Tests that Temporal.Calendar.prototype.daysInYear + 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.Calendar.prototype.daysInYear), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.daysInYear), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.daysInYear), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.Calendar.prototype.daysInYear.hasOwnProperty("prototype"), + false, "prototype property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/calendar-datefromfields-called-with-options-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/calendar-datefromfields-called-with-options-undefined.js new file mode 100644 index 0000000000..0e827bd72a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/calendar-datefromfields-called-with-options-undefined.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.calendar.prototype.daysinyear +description: > + Calendar.dateFromFields method is called with undefined as the options value + when call originates internally +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = TemporalHelpers.calendarFromFieldsUndefinedOptions(); +calendar.daysInYear({ year: 2000, month: 5, day: 3, calendar }); +assert.sameValue(calendar.dateFromFieldsCallCount, 1); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/calendar-fields-iterable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/calendar-fields-iterable.js new file mode 100644 index 0000000000..55ced1ad7f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/calendar-fields-iterable.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.calendar.prototype.daysinyear +description: Verify the result of calendar.fields() is treated correctly. +info: | + sec-temporal.calendar.prototype.daysinyear step 4: + 4. Let _year_ be ? ISOYear(_dateOrDateTime_). + sec-temporal-isoyear step 1.a: + a. Set _dateOrDateTime_ to ? ToTemporalDate(_dateOrDateTime_). + sec-temporal-totemporaldate step 2.c: + c. Let _fieldNames_ be ? CalendarFields(_calendar_, « *"day"*, *"month"*, *"monthCode"*, *"year"* »). + sec-temporal-calendarfields step 4: + 4. Let _result_ be ? IterableToListOfType(_fieldsArray_, « String »). +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + "day", + "month", + "monthCode", + "year", +]; + +const calendar1 = TemporalHelpers.calendarFieldsIterable(); +const calendar2 = TemporalHelpers.calendarFieldsIterable(); +calendar1.daysInYear({ year: 2000, month: 5, day: 2, calendar: calendar2 }); + +assert.sameValue(calendar1.fieldsCallCount, 0, "fields() method not called"); +assert.sameValue(calendar2.fieldsCallCount, 1, "fields() method called once"); +assert.compareArray(calendar2.fieldsCalledWith[0], expected, "fields() method called with correct args"); +assert(calendar2.iteratorExhausted[0], "iterated through the whole iterable"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/calendar-temporal-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/calendar-temporal-object.js new file mode 100644 index 0000000000..dc8e34d663 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/calendar-temporal-object.js @@ -0,0 +1,31 @@ +// |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.calendar.prototype.daysinyear +description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots +info: | + sec-temporal.calendar.prototype.daysinyear step 4: + 4. Let _year_ be ? ISOYear(_dateOrDateTime_). + sec-temporal-isoyear step 1.a: + a. Set _dateOrDateTime_ to ? ToTemporalDate(_dateOrDateTime_). + sec-temporal-totemporaldate 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 calendar = new Temporal.Calendar("iso8601"); + calendar.daysInYear({ year: 2000, month: 5, day: 2, calendar: temporalObject }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/infinity-throws-rangeerror.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/infinity-throws-rangeerror.js new file mode 100644 index 0000000000..3338d8dd6d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/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.calendar.prototype.daysinyear +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); +const base = { year: 2000, month: 5, day: 2 }; + +[Infinity, -Infinity].forEach((inf) => { + ["year", "month", "day"].forEach((prop) => { + assert.throws(RangeError, () => instance.daysInYear({ ...base, [prop]: inf }), `${prop} property cannot be ${inf}`); + + const calls = []; + const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop); + assert.throws(RangeError, () => instance.daysInYear({ ...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/Calendar/prototype/daysInYear/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/length.js new file mode 100644 index 0000000000..a201a6f092 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/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.calendar.prototype.daysinyear +description: Temporal.Calendar.prototype.daysInYear.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.Calendar.prototype.daysInYear, "length", { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/name.js new file mode 100644 index 0000000000..228cb06951 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/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.calendar.prototype.daysinyear +description: Temporal.Calendar.prototype.daysInYear.name is "daysInYear". +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.Calendar.prototype.daysInYear, "name", { + value: "daysInYear", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/not-a-constructor.js new file mode 100644 index 0000000000..c6137982b6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/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.calendar.prototype.daysinyear +description: > + Temporal.Calendar.prototype.daysInYear 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.Calendar.prototype.daysInYear(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.Calendar.prototype.daysInYear), false, + "isConstructor(Temporal.Calendar.prototype.daysInYear)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/plain-date-time.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/plain-date-time.js new file mode 100644 index 0000000000..d5392a82e1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/plain-date-time.js @@ -0,0 +1,94 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-temporal.calendar.prototype.daysinyear +description: > + Temporal.Calendar.prototype.daysInYear will take PlainDateTime and return + the number of days in a year. +info: | + 4. If Type(temporalDateLike) is not Object or temporalDateLike does not have an [[InitializedTemporalDate]] or [[InitializedTemporalYearMonth]] internal slot, then + a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike). + 5. Return 𝔽(! ISODaysInYear(temporalDateLike.[[ISOYear]])). +features: [Temporal] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +let dt = new Temporal.PlainDateTime(1995, 8, 23, 5, 30, 13); +assert.sameValue( + cal.daysInYear(dt), + 365, + 'cal.daysInYear(new Temporal.PlainDateTime(1995, 8, 23, 5, 30, 13)) must return 365' +); + +dt = new Temporal.PlainDateTime(1996, 8, 23, 5, 30, 13); +assert.sameValue( + cal.daysInYear(dt), + 366, + 'cal.daysInYear(new Temporal.PlainDateTime(1996, 8, 23, 5, 30, 13)) must return 366' +); + +dt = new Temporal.PlainDateTime(1997, 8, 23, 5, 30, 13); +assert.sameValue( + cal.daysInYear(dt), + 365, + 'cal.daysInYear(new Temporal.PlainDateTime(1997, 8, 23, 5, 30, 13)) must return 365' +); + +dt = new Temporal.PlainDateTime(1998, 8, 23, 5, 30, 13); +assert.sameValue( + cal.daysInYear(dt), + 365, + 'cal.daysInYear(new Temporal.PlainDateTime(1998, 8, 23, 5, 30, 13)) must return 365' +); + +dt = new Temporal.PlainDateTime(1999, 8, 23, 5, 30, 13); +assert.sameValue( + cal.daysInYear(dt), + 365, + 'cal.daysInYear(new Temporal.PlainDateTime(1999, 8, 23, 5, 30, 13)) must return 365' +); + +dt = new Temporal.PlainDateTime(2000, 8, 23, 5, 30, 13); +assert.sameValue( + cal.daysInYear(dt), + 366, + 'cal.daysInYear(new Temporal.PlainDateTime(2000, 8, 23, 5, 30, 13)) must return 366' +); + +dt = new Temporal.PlainDateTime(2001, 8, 23, 5, 30, 13); +assert.sameValue( + cal.daysInYear(dt), + 365, + 'cal.daysInYear(new Temporal.PlainDateTime(2001, 8, 23, 5, 30, 13)) must return 365' +); + +dt = new Temporal.PlainDateTime(2002, 8, 23, 5, 30, 13); +assert.sameValue( + cal.daysInYear(dt), + 365, + 'cal.daysInYear(new Temporal.PlainDateTime(2002, 8, 23, 5, 30, 13)) must return 365' +); + +dt = new Temporal.PlainDateTime(2003, 8, 23, 5, 30, 13); +assert.sameValue( + cal.daysInYear(dt), + 365, + 'cal.daysInYear(new Temporal.PlainDateTime(2003, 8, 23, 5, 30, 13)) must return 365' +); + +dt = new Temporal.PlainDateTime(2004, 8, 23, 5, 30, 13); +assert.sameValue( + cal.daysInYear(dt), + 366, + 'cal.daysInYear(new Temporal.PlainDateTime(2004, 8, 23, 5, 30, 13)) must return 366' +); + +dt = new Temporal.PlainDateTime(2005, 8, 23, 5, 30, 13); +assert.sameValue( + cal.daysInYear(dt), + 365, + 'cal.daysInYear(new Temporal.PlainDateTime(2005, 8, 23, 5, 30, 13)) must return 365' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/plain-date.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/plain-date.js new file mode 100644 index 0000000000..ce27f54362 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/plain-date.js @@ -0,0 +1,48 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-temporal.calendar.prototype.daysinyear +description: > + Temporal.Calendar.prototype.daysInYear will take PlainDate and return + the number of days in a year. +info: | + 5. Return 𝔽(! ISODaysInYear(temporalDateLike.[[ISOYear]])). +features: [Temporal] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +let d = new Temporal.PlainDate(1995, 7, 15); +assert.sameValue(cal.daysInYear(d), 365, 'cal.daysInYear(new Temporal.PlainDate(1995, 7, 15)) must return 365'); + +d = new Temporal.PlainDate(1996, 7, 15); +assert.sameValue(cal.daysInYear(d), 366, 'cal.daysInYear(new Temporal.PlainDate(1996, 7, 15)) must return 366'); + +d = new Temporal.PlainDate(1997, 7, 15); +assert.sameValue(cal.daysInYear(d), 365, 'cal.daysInYear(new Temporal.PlainDate(1997, 7, 15)) must return 365'); + +d = new Temporal.PlainDate(1998, 7, 15); +assert.sameValue(cal.daysInYear(d), 365, 'cal.daysInYear(new Temporal.PlainDate(1998, 7, 15)) must return 365'); + +d = new Temporal.PlainDate(1999, 7, 15); +assert.sameValue(cal.daysInYear(d), 365, 'cal.daysInYear(new Temporal.PlainDate(1999, 7, 15)) must return 365'); + +d = new Temporal.PlainDate(2000, 7, 15); +assert.sameValue(cal.daysInYear(d), 366, 'cal.daysInYear(new Temporal.PlainDate(2000, 7, 15)) must return 366'); + +d = new Temporal.PlainDate(2001, 7, 15); +assert.sameValue(cal.daysInYear(d), 365, 'cal.daysInYear(new Temporal.PlainDate(2001, 7, 15)) must return 365'); + +d = new Temporal.PlainDate(2002, 7, 15); +assert.sameValue(cal.daysInYear(d), 365, 'cal.daysInYear(new Temporal.PlainDate(2002, 7, 15)) must return 365'); + +d = new Temporal.PlainDate(2003, 7, 15); +assert.sameValue(cal.daysInYear(d), 365, 'cal.daysInYear(new Temporal.PlainDate(2003, 7, 15)) must return 365'); + +d = new Temporal.PlainDate(2004, 7, 15); +assert.sameValue(cal.daysInYear(d), 366, 'cal.daysInYear(new Temporal.PlainDate(2004, 7, 15)) must return 366'); + +d = new Temporal.PlainDate(2005, 7, 15); +assert.sameValue(cal.daysInYear(d), 365, 'cal.daysInYear(new Temporal.PlainDate(2005, 7, 15)) must return 365'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/prop-desc.js new file mode 100644 index 0000000000..0d6402f3f5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/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.calendar.prototype.daysinyear +description: The "daysInYear" property of Temporal.Calendar.prototype +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.Calendar.prototype.daysInYear, + "function", + "`typeof Calendar.prototype.daysInYear` is `function`" +); + +verifyProperty(Temporal.Calendar.prototype, "daysInYear", { + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/shell.js new file mode 100644 index 0000000000..eda1477282 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/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/Calendar/prototype/daysInYear/string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/string.js new file mode 100644 index 0000000000..28dd13f9f2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/string.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-temporal.calendar.prototype.daysinyear +description: > + Temporal.Calendar.prototype.daysInYear will take PlainDate and return + the number of days in a year. +info: | + 4. If Type(temporalDateLike) is not Object or temporalDateLike does not have an [[InitializedTemporalDate]] or [[InitializedTemporalYearMonth]] internal slot, then + a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike). + 5. Return 𝔽(! ISODaysInYear(temporalDateLike.[[ISOYear]])). +features: [Temporal] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +assert.sameValue(cal.daysInYear("2019-03-18"), 365, 'cal.daysInYear("2019-03-18") must return 365'); +assert.sameValue(cal.daysInYear("2020-03-18"), 366, 'cal.daysInYear("2020-03-18") must return 366'); +assert.sameValue(cal.daysInYear("2021-03-18"), 365, 'cal.daysInYear("2021-03-18") must return 365'); +assert.sameValue(cal.daysInYear("2022-03-18"), 365, 'cal.daysInYear("2022-03-18") must return 365'); +assert.sameValue(cal.daysInYear("2023-03-18"), 365, 'cal.daysInYear("2023-03-18") must return 365'); +assert.sameValue(cal.daysInYear("2024-03-18"), 366, 'cal.daysInYear("2024-03-18") must return 366'); +assert.sameValue(cal.daysInYear("2025-03-18"), 365, 'cal.daysInYear("2025-03-18") must return 365'); +assert.sameValue(cal.daysInYear("2026-03-18"), 365, 'cal.daysInYear("2026-03-18") must return 365'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/throw-range-error-ToTemporalDate.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/throw-range-error-ToTemporalDate.js new file mode 100644 index 0000000000..4d92876969 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/throw-range-error-ToTemporalDate.js @@ -0,0 +1,21 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-temporal.calendar.prototype.daysInYear +description: > + Temporal.Calendar.prototype.daysInYear throws RangeError on + ToTemporalDate when temporalDateLike is invalid string. +info: | + 4. If Type(temporalDateLike) is not Object or temporalDateLike does + not have an [[InitializedTemporalDate]] or [[InitializedTemporalYearMonth]] + internal slot, then + a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike). +features: [Temporal, arrow-function] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +assert.throws(RangeError, () => cal.daysInYear("invalid string"), + 'cal.daysInYear("invalid string") throws a RangeError exception'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/year-zero.js new file mode 100644 index 0000000000..89d87d7882 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/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.calendar.prototype.daysinyear +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.daysInYear(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/argument-iterable-not-array.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/argument-iterable-not-array.js new file mode 100644 index 0000000000..069ea56dfa --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/argument-iterable-not-array.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.calendar.prototype.fields +description: A non-Array iterable passed as the argument is exhausted +info: | + sec-temporal.calendar.prototype.fields step 4: + 4. Let _fieldNames_ be ? IterableToList(_fields_). +includes: [compareArray.js] +features: [Temporal] +---*/ + +const fieldNames = ["day", "month", "monthCode", "year"]; +const iterable = { + iteratorExhausted: false, + *[Symbol.iterator]() { + yield* fieldNames; + this.iteratorExhausted = true; + }, +}; + +const calendar = new Temporal.Calendar("iso8601"); +const result = calendar.fields(iterable); + +assert.compareArray(result, fieldNames); +assert(iterable.iteratorExhausted); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/argument-throws-duplicate-keys.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/argument-throws-duplicate-keys.js new file mode 100644 index 0000000000..9f9df6d105 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/argument-throws-duplicate-keys.js @@ -0,0 +1,31 @@ +// |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.calendar.prototype.fields +description: Duplicate fields are not allowed in the argument to Calendar.prototype.fields +info: | + sec-temporal.calendar.prototype.fields step 7.b.iii: + iii. If _fieldNames_ contains _nextValue_, then + 1. Let _completion_ be ThrowCompletion(a newly created *RangeError* object). + 2. Return ? IteratorClose(_iteratorRecord_, _completion_). +features: [Temporal] +---*/ + +const calendar = new Temporal.Calendar("iso8601"); +assert.throws(RangeError, () => calendar.fields(["day", "month", "day"])); +assert.throws(RangeError, () => calendar.fields(["year", "month", "monthCode", "day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond", "year"])); + +const manyFields = { + count: 0 +}; + +manyFields[Symbol.iterator] = function*() { + while (this.count++ < 100) yield "year"; +}; + +assert.throws(RangeError, () => calendar.fields(manyFields), "Rejected duplicate values"); +assert.sameValue(manyFields.count, 2, "Rejected first duplicate value"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/argument-throws-invalid-keys.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/argument-throws-invalid-keys.js new file mode 100644 index 0000000000..96ff63c8b7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/argument-throws-invalid-keys.js @@ -0,0 +1,38 @@ +// |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.calendar.prototype.fields +description: Calendar.prototype.fields rejects input field names that are not singular names of temporal units +info: | + sec-temporal.calendar.prototype.fields step 7.b.ii: + 7. Repeat, while next is not false, + a. Set next to ? IteratorStep(iteratorRecord). + b. If next is not false, then + i. Let nextValue be ? IteratorValue(next). + ii. If Type(nextValue) is not String, then + 1. Let completion be ThrowCompletion(a newly created TypeError object). + 2. Return ? IteratorClose(iteratorRecord, completion). + sec-temporal.calendar.prototype.fields step 7.b.iv: + iv. If _nextValue_ is not one of *"year"*, *"month"*, *"monthCode"*, *"day"*, *"hour"*, *"minute"*, *"second"*, *"millisecond"*, *"microsecond"*, *"nanosecond"*, then + 1. Let _completion_ be ThrowCompletion(a newly created *RangeError* object). + 2. Return ? IteratorClose(_iteratorRecord_, _completion_). + +features: [Temporal] +---*/ + +const calendar = new Temporal.Calendar("iso8601"); +assert.throws(TypeError, () => calendar.fields([1])); +assert.throws(TypeError, () => calendar.fields([1n])); +assert.throws(TypeError, () => calendar.fields([Symbol('foo')])); +assert.throws(TypeError, () => calendar.fields([true])); +assert.throws(TypeError, () => calendar.fields([null])); +assert.throws(TypeError, () => calendar.fields([{}])); +assert.throws(TypeError, () => calendar.fields([undefined])); +assert.throws(TypeError, () => calendar.fields(["day", 1])); +assert.throws(RangeError, () => calendar.fields(["month", "days"])); +assert.throws(RangeError, () => calendar.fields(["days"])); +assert.throws(RangeError, () => calendar.fields(["people"])); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/branding.js new file mode 100644 index 0000000000..c4a52ed5ff --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/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.calendar.prototype.fields +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const fields = Temporal.Calendar.prototype.fields; + +assert.sameValue(typeof fields, "function"); + +const args = [[]]; + +assert.throws(TypeError, () => fields.apply(undefined, args), "undefined"); +assert.throws(TypeError, () => fields.apply(null, args), "null"); +assert.throws(TypeError, () => fields.apply(true, args), "true"); +assert.throws(TypeError, () => fields.apply("", args), "empty string"); +assert.throws(TypeError, () => fields.apply(Symbol(), args), "symbol"); +assert.throws(TypeError, () => fields.apply(1, args), "1"); +assert.throws(TypeError, () => fields.apply({}, args), "plain object"); +assert.throws(TypeError, () => fields.apply(Temporal.Calendar, args), "Temporal.Calendar"); +assert.throws(TypeError, () => fields.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/builtin.js new file mode 100644 index 0000000000..1f9afa6b20 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/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.calendar.prototype.fields +description: > + Tests that Temporal.Calendar.prototype.fields + 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.Calendar.prototype.fields), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.fields), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.fields), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.Calendar.prototype.fields.hasOwnProperty("prototype"), + false, "prototype property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/length.js new file mode 100644 index 0000000000..5c91ef0639 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/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.calendar.prototype.fields +description: Temporal.Calendar.prototype.fields.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.Calendar.prototype.fields, "length", { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/long-input.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/long-input.js new file mode 100644 index 0000000000..34567efc8c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/long-input.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.fields +description: > + Temporal.Calendar.prototype.fields will throw when its input iterable yields an + invalid field. +info: | + ## 12.4.21 Temporal.Calendar.prototype.fields ( fields ) + 1. Let calendar be the this value. + 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]). + 4. Let iteratorRecord be ? Getiterator(fields, sync). + 5. Let fieldNames be a new empty List. + 6. Let next be true. + 7. Repeat, while next is not false, + a. Set next to ? IteratorStep(iteratorRecord). + b. If next is not false, then + i. Let nextValue be ? IteratorValue(next). + iv. If nextValue is not one of "year", "month", "monthCode", "day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond", then + 1. Let completion be ThrowCompletion(a newly created RangeError object). + 2. Return ? IteratorClose(iteratorRecord, completion). +features: [Symbol, Symbol.iterator, Temporal, computed-property-names, generators] +---*/ +let cal = new Temporal.Calendar("iso8601") +let i = 0; +const fields = { + *[Symbol.iterator]() { + // The first three are valid values + yield "year"; + i++; + yield "month"; + i++; + yield "monthCode"; + i++; + // The fourth one is wrong and should throw after the next line. + yield "garbage"; + // The following three lines should not be reached if the implemention + // correctly check the previous line. + i++; + yield "hour"; + i++; + } +} +assert.throws(RangeError, () => cal.fields(fields), "Garbage content"); +// stop after the third one. +assert.sameValue(i, 3); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/name.js new file mode 100644 index 0000000000..241eafa9de --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/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.calendar.prototype.fields +description: Temporal.Calendar.prototype.fields.name is "fields". +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.Calendar.prototype.fields, "name", { + value: "fields", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/non-string-element-throws.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/non-string-element-throws.js new file mode 100644 index 0000000000..2ebacd53dc --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/non-string-element-throws.js @@ -0,0 +1,20 @@ +// |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.calendar.prototype.fields +description: TypeError thrown if the input iterable yields a non-String value +info: | + sec-temporal.calendar.prototype.fields step 5: + 5. For each element _fieldName_ of _fieldNames_, do + a. If Type(_fieldName_) is not String, throw a *TypeError* exception. +features: [Temporal] +---*/ + +const calendar = new Temporal.Calendar("iso8601"); +[true, 3, 3n, {}, () => {}, Symbol(), undefined, null].forEach((element) => { + assert.throws(TypeError, () => calendar.fields([element]), "bad input to calendar.fields()"); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/not-a-constructor.js new file mode 100644 index 0000000000..12bb2629fa --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/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.calendar.prototype.fields +description: > + Temporal.Calendar.prototype.fields 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.Calendar.prototype.fields(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.Calendar.prototype.fields), false, + "isConstructor(Temporal.Calendar.prototype.fields)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/prop-desc.js new file mode 100644 index 0000000000..6f370b544e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/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.calendar.prototype.fields +description: The "fields" property of Temporal.Calendar.prototype +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.Calendar.prototype.fields, + "function", + "`typeof Calendar.prototype.fields` is `function`" +); + +verifyProperty(Temporal.Calendar.prototype, "fields", { + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/repeated-throw.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/repeated-throw.js new file mode 100644 index 0000000000..015ce35d5a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/repeated-throw.js @@ -0,0 +1,59 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.fields +description: > + Temporal.Calendar.prototype.fields will throw if its input iterable yields + the same value twice. +info: | + ## 12.4.21 Temporal.Calendar.prototype.fields ( fields ) + 1. Let calendar be the this value. + 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]). + 4. Let iteratorRecord be ? Getiterator(fields, sync). + 5. Let fieldNames be a new empty List. + 6. Let next be true. + 7. Repeat, while next is not false, + a. Set next to ? IteratorStep(iteratorRecord). + b. If next is not false, then + i. Let nextValue be ? IteratorValue(next). + iii. If fieldNames contains nextValue, then + 1. Let completion be ThrowCompletion(a newly created RangeError object). + 2. Return ? IteratorClose(iteratorRecord, completion). +features: [Symbol, Symbol.iterator, Temporal, computed-property-names, generators] +---*/ +let cal = new Temporal.Calendar("iso8601") +let i = 0; +const fields = { + *[Symbol.iterator]() { + yield "month"; + i++; + yield "year"; + i++; + yield "year"; + i++; + } +} +assert.throws( + RangeError, () => cal.fields(fields), "repeated valid value should throw"); +assert.sameValue(i, 2, "Should stop at 2"); + +// Test all valid value will throw while repeate +[ "nanosecond", "microsecond", "millisecond", "second", + "minute", "hour", "day", "monthCode", "month", "year" ].forEach((f) => { + i = 0; + const fields2 = { + *[Symbol.iterator]() { + yield f; + i++; + yield f; + i++; + } + } + assert.throws( + RangeError, () => cal.fields(fields2), "repeated valid value should throw"); + assert.sameValue(i, 1, "Should stop at 1"); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/reverse.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/reverse.js new file mode 100644 index 0000000000..4e2b1bbb83 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/reverse.js @@ -0,0 +1,45 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.fields +description: > + Temporal.Calendar.prototype.fields will return the iterable in array if all + input are valid regardless of it's order. +info: | + ## 12.4.21 Temporal.Calendar.prototype.fields ( fields ) + 1. Let calendar be the this value. + 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]). + 4. Let iteratorRecord be ? Getiterator(fields, sync). + 5. Let fieldNames be a new empty List. + 6. Let next be true. + 7. Repeat, while next is not false, + a. Set next to ? IteratorStep(iteratorRecord). + b. If next is not false, then + i. Let nextValue be ? IteratorValue(next). + iv. If nextValue is not one of "year", "month", "monthCode", "day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond", then + 1. Let completion be ThrowCompletion(a newly created RangeError object). + 2. Return ? IteratorClose(iteratorRecord, completion). +features: [Symbol, Symbol.iterator, Temporal, computed-property-names, generators] +includes: [compareArray.js] +---*/ +let cal = new Temporal.Calendar("iso8601") +const fields = { + *[Symbol.iterator]() { + yield "nanosecond"; + yield "microsecond"; + yield "millisecond"; + yield "second"; + yield "minute"; + yield "hour"; + yield "day"; + yield "monthCode"; + yield "month"; + yield "year"; + } +} +assert.compareArray(cal.fields(fields), Array.from(fields), + 'valid fields should be supported even if they are in reversed order of the spec'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/shell.js new file mode 100644 index 0000000000..eda1477282 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/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/Calendar/prototype/id/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/branding.js new file mode 100644 index 0000000000..60f44f3cf3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/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.calendar.prototype.id +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const descriptor = Object.getOwnPropertyDescriptor(Temporal.Calendar.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.Calendar), "Temporal.Calendar"); +assert.throws(TypeError, () => id.call(Temporal.Calendar.prototype), "Temporal.Calendar.prototype"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/custom-calendar.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/custom-calendar.js new file mode 100644 index 0000000000..c7699def08 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/custom-calendar.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-get-temporal.calendar.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 calendar = new Temporal.Calendar("iso8601"); +TemporalHelpers.observeProperty(actual, calendar, Symbol.toPrimitive, undefined); +TemporalHelpers.observeProperty(actual, calendar, "toString", function () { + actual.push("call calendar.toString"); + return "calendar ID"; +}); + +const result = calendar.id; +assert.compareArray(actual, expected); +assert.sameValue(result, "iso8601"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/prop-desc.js new file mode 100644 index 0000000000..82f37250bf --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/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.calendar.prototype.id +description: The "id" property of Temporal.Calendar.prototype +features: [Temporal] +---*/ + +const descriptor = Object.getOwnPropertyDescriptor(Temporal.Calendar.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/Calendar/prototype/id/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/shell.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/shell.js diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-calendar-datefromfields-called-with-null-prototype-fields.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-calendar-datefromfields-called-with-null-prototype-fields.js new file mode 100644 index 0000000000..3002443a00 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-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.calendar.prototype.inleapyear +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.Calendar("iso8601"); +const arg = { year: 2000, month: 5, day: 2, calendar }; +instance.inLeapYear(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/Calendar/prototype/inLeapYear/argument-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-leap-second.js new file mode 100644 index 0000000000..dc4638be2b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-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.calendar.prototype.inleapyear +description: Leap second is a valid ISO string for PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.inLeapYear(arg); +assert.sameValue( + result1, + true, + "leap second is a valid ISO string for PlainDate" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.inLeapYear(arg); +assert.sameValue( + result2, + true, + "second: 60 is ignored in property bag for PlainDate" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-number.js new file mode 100644 index 0000000000..b95b289ba7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/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.calendar.prototype.inleapyear +description: A number is converted to a string, then to Temporal.PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const arg = 19761118; + +const result = instance.inLeapYear(arg); +assert.sameValue(result, true, "19761118 is a valid ISO string for PlainDate"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.inLeapYear(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-case-insensitive.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-case-insensitive.js new file mode 100644 index 0000000000..4ab29f5c1f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/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.calendar.prototype.inleapyear +description: The calendar name is case-insensitive +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "IsO8601"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.inLeapYear(arg); +assert.sameValue(result1, true, "Calendar is case-insensitive"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.inLeapYear(arg); +assert.sameValue(result2, true, "Calendar is case-insensitive (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js new file mode 100644 index 0000000000..76ae4fa343 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/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.calendar.prototype.inleapyear +description: > + A Temporal.Calendar instance passed to inLeapYear() in a property bag does + not have its 'calendar' property observably checked +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +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.inLeapYear(arg); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +instance.inLeapYear(arg); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-leap-second.js new file mode 100644 index 0000000000..ca9eaef006 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/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.calendar.prototype.inleapyear +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.inLeapYear(arg); +assert.sameValue( + result1, + true, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.inLeapYear(arg); +assert.sameValue( + result2, + true, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-number.js new file mode 100644 index 0000000000..59e1116e19 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/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.calendar.prototype.inleapyear +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.inLeapYear(arg); +assert.sameValue(result1, true, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.inLeapYear(arg); +assert.sameValue(result2, true, "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.inLeapYear(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.inLeapYear(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/Calendar/prototype/inLeapYear/argument-propertybag-calendar-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-string.js new file mode 100644 index 0000000000..108987157d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/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.calendar.prototype.inleapyear +description: A calendar ID is valid input for Calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "iso8601"; + +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.inLeapYear(arg); +assert.sameValue(result, true, `Calendar created from string "${calendar}"`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 0000000000..c2dccc6440 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/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.calendar.prototype.inleapyear +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.Calendar("iso8601"); + +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.inLeapYear(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.inLeapYear(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.inLeapYear(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.inLeapYear(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.inLeapYear(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-year-zero.js new file mode 100644 index 0000000000..8117471211 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/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.calendar.prototype.inleapyear +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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.inLeapYear(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-calendar-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-calendar-annotation.js new file mode 100644 index 0000000000..83713222db --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/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.calendar.prototype.inleapyear +description: Various forms of calendar annotation; critical flag has no effect +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02[u-ca=iso8601]", "without time or time zone"], + ["2000-05-02[UTC][u-ca=iso8601]", "with time zone and no time"], + ["2000-05-02T15:23[u-ca=iso8601]", "without time zone"], + ["2000-05-02T15:23[UTC][u-ca=iso8601]", "with time zone"], + ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], + ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], + ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], + ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.inLeapYear(arg); + + assert.sameValue( + result, + true, + `calendar annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-critical-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-critical-unknown-annotation.js new file mode 100644 index 0000000000..ca8d69760a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-critical-unknown-annotation.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.calendar.prototype.inleapyear +description: Unknown annotations with critical flag are rejected +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[!foo=bar]", + "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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.inLeapYear(arg), + `reject unknown annotation with critical flag: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-date-with-utc-offset.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-date-with-utc-offset.js new file mode 100644 index 0000000000..fea5657692 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/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.calendar.prototype.inleapyear +description: UTC offset not valid with format that does not include a time +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const validStrings = [ + "2000-05-02T00+00:00", + "2000-05-02T00+00:00[UTC]", + "2000-05-02T00+00:00[!UTC]", + "2000-05-02T00-02:30[America/St_Johns]", +]; + +for (const arg of validStrings) { + const result = instance.inLeapYear(arg); + + assert.sameValue( + result, + true, + `"${arg}" is a valid UTC offset with time for PlainDate` + ); +} + +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.inLeapYear(arg), + `"${arg}" UTC offset without time is not valid for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-invalid.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-invalid.js new file mode 100644 index 0000000000..b07659dee4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-invalid.js @@ -0,0 +1,64 @@ +// |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.calendar.prototype.inleapyear +description: > + RangeError thrown if an invalid ISO string (or syntactically valid ISO string + that is not supported) is used as a PlainDate +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + // invalid ISO strings: + "", + "invalid iso8601", + "2020-01-00", + "2020-01-32", + "2020-02-30", + "2021-02-29", + "2020-00-01", + "2020-13-01", + "2020-01-01T", + "2020-01-01T25:00:00", + "2020-01-01T01:60:00", + "2020-01-01T01:60:61", + "2020-01-01junk", + "2020-01-01T00:00:00junk", + "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-01", + "2020-001-01", + "2020-01-001", + "2020-01-01T001", + "2020-01-01T01:001", + "2020-01-01T01:01:001", + // valid, but forms not supported in Temporal: + "2020-W01-1", + "2020-001", + "+0002020-01-01", + // valid, but this calendar must not exist: + "2020-01-01[u-ca=notexist]", + // may be valid in other contexts, but insufficient information for PlainDate: + "2020-01", + "+002020-01", + "01-01", + "2020-W01", + "P1Y", + "-P12Y", + // valid, but outside the supported range: + "-999999-01-01", + "+999999-01-01", +]; +const instance = new Temporal.Calendar("iso8601"); +for (const arg of invalidStrings) { + assert.throws( + RangeError, + () => instance.inLeapYear(arg), + `"${arg}" should not be a valid ISO string for a PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-multiple-time-zone.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-multiple-time-zone.js new file mode 100644 index 0000000000..85ca965624 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-multiple-time-zone.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.calendar.prototype.inleapyear +description: More than one time zone annotation is not syntactical +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[UTC][UTC]", + "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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.inLeapYear(arg), + `reject more than one time zone annotation: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-time-separators.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-time-separators.js new file mode 100644 index 0000000000..41396a090c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/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.calendar.prototype.inleapyear +description: Time separator in string argument can vary +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02T15:23", "uppercase T"], + ["2000-05-02t15:23", "lowercase T"], + ["2000-05-02 15:23", "space between date and time"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.inLeapYear(arg); + + assert.sameValue( + result, + true, + `variant time separators (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-time-zone-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-time-zone-annotation.js new file mode 100644 index 0000000000..daa318ca01 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-time-zone-annotation.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.calendar.prototype.inleapyear +description: Various forms of time zone annotation; critical flag has no effect +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02[Asia/Kolkata]", "named, with no time"], + ["2000-05-02[!Europe/Vienna]", "named, with ! and no time"], + ["2000-05-02[+00:00]", "numeric, with no time"], + ["2000-05-02[!-02:30]", "numeric, with ! and no time"], + ["2000-05-02T15:23[America/Sao_Paulo]", "named, with no offset"], + ["2000-05-02T15:23[!Asia/Tokyo]", "named, with ! and no offset"], + ["2000-05-02T15:23[-02:30]", "numeric, with no offset"], + ["2000-05-02T15:23[!+00:00]", "numeric, with ! and no offset"], + ["2000-05-02T15:23+00:00[America/New_York]", "named, with offset"], + ["2000-05-02T15:23+00:00[!UTC]", "named, with offset and !"], + ["2000-05-02T15:23+00:00[+01:00]", "numeric, with offset"], + ["2000-05-02T15:23+00:00[!-08:00]", "numeric, with offset and !"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.inLeapYear(arg); + + assert.sameValue( + result, + true, + `time zone annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-unknown-annotation.js new file mode 100644 index 0000000000..a518c7c07e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/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.calendar.prototype.inleapyear +description: Various forms of unknown annotation +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02[foo=bar]", "without time"], + ["2000-05-02T15:23[foo=bar]", "alone"], + ["2000-05-02T15:23[UTC][foo=bar]", "with time zone"], + ["2000-05-02T15:23[u-ca=iso8601][foo=bar]", "with calendar"], + ["2000-05-02T15:23[UTC][foo=bar][u-ca=iso8601]", "with time zone and calendar"], + ["2000-05-02T15:23[foo=bar][_foo-bar0=Ignore-This-999999999999]", "with another unknown annotation"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.inLeapYear(arg); + + assert.sameValue( + result, + true, + `unknown annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-with-utc-designator.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-with-utc-designator.js new file mode 100644 index 0000000000..0e221b58ac --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/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.calendar.prototype.inleapyear +description: RangeError thrown if a string with UTC designator is used as a PlainDate +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "2019-10-01T09:00:00Z", + "2019-10-01T09:00:00Z[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.inLeapYear(arg), + "String with UTC designator should not be valid as a PlainDate" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string.js new file mode 100644 index 0000000000..c161951158 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.inleapyear +description: An ISO 8601 date string should be converted as input +info: | + 4. If Type(temporalDateLike) is not Object or temporalDateLike does not have an [[InitializedTemporalDate]] or [[InitializedTemporalYearMonth]] internal slot, then + a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike). + 5. Return ! IsISOLeapYear(temporalDateLike.[[ISOYear]]). +features: [Temporal] +---*/ + +const cal = new Temporal.Calendar("iso8601"); + +assert.sameValue(cal.inLeapYear("2019-03-18"), false); +assert.sameValue(cal.inLeapYear("2020-03-18"), true); + +assert.sameValue(cal.inLeapYear("+002023-03-18"), false); +assert.sameValue(cal.inLeapYear("+002024-03-18"), true); + +assert.sameValue(cal.inLeapYear("2019-03-18T13:00:00+00:00[UTC]"), false); +assert.sameValue(cal.inLeapYear("2020-12-31T23:59:59+00:00[UTC]"), true); + +assert.sameValue(cal.inLeapYear("+002023-03-18T13:00:00+00:00[UTC]"), false); +assert.sameValue(cal.inLeapYear("+002024-03-18T13:00:00+00:00[UTC]"), true); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-wrong-type.js new file mode 100644 index 0000000000..730c318839 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/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.calendar.prototype.inleapyear +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +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.inLeapYear(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.inLeapYear(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/Calendar/prototype/inLeapYear/argument-zoneddatetime-convert.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-zoneddatetime-convert.js new file mode 100644 index 0000000000..1c6c8de764 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-zoneddatetime-convert.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.calendar.prototype.inleapyear +description: An exception from TimeZone#getOffsetNanosecondsFor() is propagated. +features: [Temporal] +---*/ + +class TZ extends Temporal.TimeZone { + constructor() { super("UTC") } + getOffsetNanosecondsFor() { throw new Test262Error() } +} + +const tz = new TZ(); +const arg = new Temporal.ZonedDateTime(0n, tz); +const instance = new Temporal.Calendar("iso8601"); + +assert.throws(Test262Error, () => instance.inLeapYear(arg)); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-zoneddatetime-slots.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-zoneddatetime-slots.js new file mode 100644 index 0000000000..a5e63cbad2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-zoneddatetime-slots.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.calendar.prototype.inleapyear +description: Getters are not called when converting a ZonedDateTime to a PlainDate. +includes: [compareArray.js] +features: [Temporal] +---*/ + +const actual = []; +const prototypeDescrs = Object.getOwnPropertyDescriptors(Temporal.ZonedDateTime.prototype); +const getters = ["year", "month", "monthCode", "day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond", "calendar"]; + +for (const property of getters) { + Object.defineProperty(Temporal.ZonedDateTime.prototype, property, { + get() { + actual.push(`get ${property}`); + const value = prototypeDescrs[property].get.call(this); + return { + toString() { + actual.push(`toString ${property}`); + return value.toString(); + }, + valueOf() { + actual.push(`valueOf ${property}`); + return value; + }, + }; + }, + }); +} + +const arg = new Temporal.ZonedDateTime(0n, "UTC"); +const instance = new Temporal.Calendar("iso8601"); +instance.inLeapYear(arg); +assert.compareArray(actual, []); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js new file mode 100644 index 0000000000..cb35c7857a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/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.calendar.prototype.inleapyear +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(RangeError, () => calendar.inLeapYear(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js new file mode 100644 index 0000000000..2fc9efa399 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/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.calendar.prototype.inleapyear +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + timeZone.getOffsetNanosecondsFor = notCallable; + assert.throws( + TypeError, + () => calendar.inLeapYear(datetime), + `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js new file mode 100644 index 0000000000..591b684f29 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/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.calendar.prototype.inleapyear +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(RangeError, () => calendar.inLeapYear(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js new file mode 100644 index 0000000000..93ef2a19de --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/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.calendar.prototype.inleapyear +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(TypeError, () => calendar.inLeapYear(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/basic.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/basic.js new file mode 100644 index 0000000000..0053728046 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/basic.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.calendar.prototype.inleapyear +description: Basic tests for inLeapYear(). +features: [Temporal] +---*/ + +const iso = Temporal.Calendar.from("iso8601"); +let res = false; + +assert.sameValue(iso.inLeapYear(new Temporal.PlainDate(1994, 11, 5)), res, "PlainDate"); +assert.sameValue(iso.inLeapYear(new Temporal.PlainDateTime(1994, 11, 5, 8, 15, 30)), res, "PlainDateTime"); +assert.sameValue(iso.inLeapYear(new Temporal.PlainYearMonth(1994, 11)), res, "PlainYearMonth"); +assert.sameValue(iso.inLeapYear({ year: 1994, month: 11, day: 5 }), res, "property bag"); +assert.sameValue(iso.inLeapYear("1994-11-05"), res, "string"); + +res = true; +assert.sameValue(iso.inLeapYear(new Temporal.PlainDate(1996, 7, 15)), res, "PlainDate in leap year"); +assert.sameValue(iso.inLeapYear(new Temporal.PlainDateTime(1996, 7, 15, 5, 30, 13)), res, "PlainDateTime in leap year"); +assert.sameValue(iso.inLeapYear(new Temporal.PlainYearMonth(1996, 7)), res, "PlainYearMonth in leap year"); +assert.sameValue(iso.inLeapYear({ year: 1996, month: 7, day: 15 }), res, "property bag in leap year"); +assert.sameValue(iso.inLeapYear("1996-07-15"), res, "string in leap year"); + +assert.throws(TypeError, () => iso.inLeapYear({ year: 2000 }), "property bag with missing properties"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/branding.js new file mode 100644 index 0000000000..8dd3ee6702 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/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.calendar.prototype.inleapyear +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const inLeapYear = Temporal.Calendar.prototype.inLeapYear; + +assert.sameValue(typeof inLeapYear, "function"); + +const args = [new Temporal.PlainDate(2021, 3, 4)]; + +assert.throws(TypeError, () => inLeapYear.apply(undefined, args), "undefined"); +assert.throws(TypeError, () => inLeapYear.apply(null, args), "null"); +assert.throws(TypeError, () => inLeapYear.apply(true, args), "true"); +assert.throws(TypeError, () => inLeapYear.apply("", args), "empty string"); +assert.throws(TypeError, () => inLeapYear.apply(Symbol(), args), "symbol"); +assert.throws(TypeError, () => inLeapYear.apply(1, args), "1"); +assert.throws(TypeError, () => inLeapYear.apply({}, args), "plain object"); +assert.throws(TypeError, () => inLeapYear.apply(Temporal.Calendar, args), "Temporal.Calendar"); +assert.throws(TypeError, () => inLeapYear.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/builtin.js new file mode 100644 index 0000000000..3c47c3413f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/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.calendar.prototype.inleapyear +description: > + Tests that Temporal.Calendar.prototype.inLeapYear + 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.Calendar.prototype.inLeapYear), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.inLeapYear), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.inLeapYear), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.Calendar.prototype.inLeapYear.hasOwnProperty("prototype"), + false, "prototype property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/calendar-datefromfields-called-with-options-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/calendar-datefromfields-called-with-options-undefined.js new file mode 100644 index 0000000000..e88db6758f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/calendar-datefromfields-called-with-options-undefined.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.calendar.prototype.inleapyear +description: > + Calendar.dateFromFields method is called with undefined as the options value + when call originates internally +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = TemporalHelpers.calendarFromFieldsUndefinedOptions(); +calendar.inLeapYear({ year: 2000, month: 5, day: 3, calendar }); +assert.sameValue(calendar.dateFromFieldsCallCount, 1); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/calendar-fields-iterable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/calendar-fields-iterable.js new file mode 100644 index 0000000000..fba76ddb5a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/calendar-fields-iterable.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.calendar.prototype.inleapyear +description: Verify the result of calendar.fields() is treated correctly. +info: | + sec-temporal.calendar.prototype.inleapyear step 4: + 4. Let _year_ be ? ISOYear(_dateOrDateTime_). + sec-temporal-isoyear step 1.a: + a. Set _dateOrDateTime_ to ? ToTemporalDate(_dateOrDateTime_). + sec-temporal-totemporaldate step 2.c: + c. Let _fieldNames_ be ? CalendarFields(_calendar_, « *"day"*, *"month"*, *"monthCode"*, *"year"* »). + sec-temporal-calendarfields step 4: + 4. Let _result_ be ? IterableToListOfType(_fieldsArray_, « String »). +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + "day", + "month", + "monthCode", + "year", +]; + +const calendar1 = TemporalHelpers.calendarFieldsIterable(); +const calendar2 = TemporalHelpers.calendarFieldsIterable(); +calendar1.inLeapYear({ year: 2000, month: 5, day: 2, calendar: calendar2 }); + +assert.sameValue(calendar1.fieldsCallCount, 0, "fields() method not called"); +assert.sameValue(calendar2.fieldsCallCount, 1, "fields() method called once"); +assert.compareArray(calendar2.fieldsCalledWith[0], expected, "fields() method called with correct args"); +assert(calendar2.iteratorExhausted[0], "iterated through the whole iterable"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/calendar-temporal-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/calendar-temporal-object.js new file mode 100644 index 0000000000..926ff10079 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/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.calendar.prototype.inleapyear +description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots +info: | + sec-temporal.calendar.prototype.inleapyear step 4: + 4. Let _year_ be ? ISOYear(_dateOrDateTime_). + sec-temporal-totemporaldate 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 calendar = new Temporal.Calendar("iso8601"); + calendar.inLeapYear({ year: 2000, month: 5, day: 2, calendar: temporalObject }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/infinity-throws-rangeerror.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/infinity-throws-rangeerror.js new file mode 100644 index 0000000000..f208b176b0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/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.calendar.prototype.inleapyear +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); +const base = { year: 2000, month: 5, day: 2 }; + +[Infinity, -Infinity].forEach((inf) => { + ["year", "month", "day"].forEach((prop) => { + assert.throws(RangeError, () => instance.inLeapYear({ ...base, [prop]: inf }), `${prop} property cannot be ${inf}`); + + const calls = []; + const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop); + assert.throws(RangeError, () => instance.inLeapYear({ ...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/Calendar/prototype/inLeapYear/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/length.js new file mode 100644 index 0000000000..9ce01a8d9c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/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.calendar.prototype.inleapyear +description: Temporal.Calendar.prototype.inLeapYear.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.Calendar.prototype.inLeapYear, "length", { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/name.js new file mode 100644 index 0000000000..c2ea4e6443 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/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.calendar.prototype.inleapyear +description: Temporal.Calendar.prototype.inLeapYear.name is "inLeapYear". +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.Calendar.prototype.inLeapYear, "name", { + value: "inLeapYear", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/not-a-constructor.js new file mode 100644 index 0000000000..df370ec207 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/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.calendar.prototype.inleapyear +description: > + Temporal.Calendar.prototype.inLeapYear 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.Calendar.prototype.inLeapYear(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.Calendar.prototype.inLeapYear), false, + "isConstructor(Temporal.Calendar.prototype.inLeapYear)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/prop-desc.js new file mode 100644 index 0000000000..471fc0bf64 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/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.calendar.prototype.inleapyear +description: The "inLeapYear" property of Temporal.Calendar.prototype +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.Calendar.prototype.inLeapYear, + "function", + "`typeof Calendar.prototype.inLeapYear` is `function`" +); + +verifyProperty(Temporal.Calendar.prototype, "inLeapYear", { + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/shell.js new file mode 100644 index 0000000000..eda1477282 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/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/Calendar/prototype/inLeapYear/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/year-zero.js new file mode 100644 index 0000000000..4706173e16 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/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.calendar.prototype.inleapyear +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.inLeapYear(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/arguments-empty-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/arguments-empty-object.js new file mode 100644 index 0000000000..1e1f99c5ba --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/arguments-empty-object.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.calendar.prototype.mergefields +description: Either argument being an empty object should result in a copy of the other object +includes: [compareArray.js] +features: [Temporal] +---*/ + +const calendar = new Temporal.Calendar("iso8601"); + +let calls = 0; +const yearObserver = { + get year() { + calls++; + return 2021; + } +}; + +const result1 = calendar.mergeFields(yearObserver, {}); +assert.sameValue(calls, 1, "property copied"); +assert.compareArray(Object.keys(result1), ["year"]); +assert.sameValue(result1.year, 2021); +assert.sameValue(calls, 1, "result has a data property"); + +calls = 0; +const result2 = calendar.mergeFields({}, yearObserver); +assert.sameValue(calls, 1, "property copied"); +assert.compareArray(Object.keys(result2), ["year"]); +assert.sameValue(result2.year, 2021); +assert.sameValue(calls, 1, "result has a data property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/arguments-not-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/arguments-not-object.js new file mode 100644 index 0000000000..d2a8dd4b42 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/arguments-not-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.calendar.prototype.mergefields +description: Non-object arguments are converted with ToObject and merge their [[OwnPropertyKeys]] onto a new object +includes: [compareArray.js] +features: [Temporal] +---*/ + +const calendar = new Temporal.Calendar("iso8601"); + +assert.throws(TypeError, () => calendar.mergeFields(undefined, {})); +assert.throws(TypeError, () => calendar.mergeFields({}, undefined)); + +assert.throws(TypeError, () => calendar.mergeFields(null, {})); +assert.throws(TypeError, () => calendar.mergeFields({}, null)); + +const boolResult = calendar.mergeFields(true, false); +assert.compareArray(Object.keys(boolResult), [], "Boolean objects have no own property keys"); +assert.sameValue(Object.getPrototypeOf(boolResult), null, "null-prototype object returned"); + +const numResult = calendar.mergeFields(3, 4); +assert.compareArray(Object.keys(numResult), [], "Number objects have no own property keys"); +assert.sameValue(Object.getPrototypeOf(boolResult), null, "null-prototype object returned"); + +const strResult = calendar.mergeFields("abc", "de"); +assert.compareArray(Object.keys(strResult), ["0", "1", "2"], "String objects have integer indices as own property keys"); +assert.sameValue(strResult["0"], "d"); +assert.sameValue(strResult["1"], "e"); +assert.sameValue(strResult["2"], "c"); +assert.sameValue(Object.getPrototypeOf(boolResult), null, "null-prototype object returned"); + +const symResult = calendar.mergeFields(Symbol("foo"), Symbol("bar")); +assert.compareArray(Object.keys(symResult), [], "Symbol objects have no own property keys"); +assert.sameValue(Object.getPrototypeOf(symResult), null, "null-prototype object returned"); + +const bigintResult = calendar.mergeFields(3n, 4n); +assert.compareArray(Object.keys(bigintResult), [], "BigInt objects have no own property keys"); +assert.sameValue(Object.getPrototypeOf(bigintResult), null, "null-prototype object returned"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/basic.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/basic.js new file mode 100644 index 0000000000..8ef4a061c5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/basic.js @@ -0,0 +1,36 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// 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.calendar.prototype.mergefields +description: > + Temporal.Calendar.prototype.mergeFields will merge own data properties on its + arguments +info: | + 1. Let calendar be the this value. + 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]). + 3. Assert: calendar.[[Identifier]] is "iso8601". + 4. Set fields to ? ToObject(fields). + 5. Set additionalFields to ? ToObject(additionalFields). + 6. Return ? DefaultMergeFields(fields, additionalFields). +features: [Temporal] +includes: [deepEqual.js] +---*/ + +const cal = new Temporal.Calendar("iso8601"); + +assert.deepEqual( + cal.mergeFields({ a: 1, b: 2 }, { c: 3, d: 4 }), + { a: 1, b: 2, c: 3, d: 4 }, + "properties are merged" +); + +assert.deepEqual( + cal.mergeFields({ a: 1, b: 2 }, { b: 3, c: 4 }), + { a: 1, b: 3, c: 4 }, + "property in additionalFields should overwrite one in fields" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/branding.js new file mode 100644 index 0000000000..e52af9bcb1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/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.calendar.prototype.mergefields +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const mergeFields = Temporal.Calendar.prototype.mergeFields; + +assert.sameValue(typeof mergeFields, "function"); + +const args = [{}, {}]; + +assert.throws(TypeError, () => mergeFields.apply(undefined, args), "undefined"); +assert.throws(TypeError, () => mergeFields.apply(null, args), "null"); +assert.throws(TypeError, () => mergeFields.apply(true, args), "true"); +assert.throws(TypeError, () => mergeFields.apply("", args), "empty string"); +assert.throws(TypeError, () => mergeFields.apply(Symbol(), args), "symbol"); +assert.throws(TypeError, () => mergeFields.apply(1, args), "1"); +assert.throws(TypeError, () => mergeFields.apply({}, args), "plain object"); +assert.throws(TypeError, () => mergeFields.apply(Temporal.Calendar, args), "Temporal.Calendar"); +assert.throws(TypeError, () => mergeFields.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/builtin.js new file mode 100644 index 0000000000..06eaef9d4f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/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.calendar.prototype.mergefields +description: > + Tests that Temporal.Calendar.prototype.mergeFields + 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.Calendar.prototype.mergeFields), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.mergeFields), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.mergeFields), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.Calendar.prototype.mergeFields.hasOwnProperty("prototype"), + false, "prototype property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/iso8601-calendar-month-monthCode.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/iso8601-calendar-month-monthCode.js new file mode 100644 index 0000000000..2c6a1ac6fc --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/iso8601-calendar-month-monthCode.js @@ -0,0 +1,102 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.mergefields +description: > + The default mergeFields algorithm from the ISO 8601 calendar should correctly + merge the month and monthCode properties +info: | + 1. Let calendar be the this value. + 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]). + 3. Assert: calendar.[[Identifier]] is "iso8601". + 4. Set fields to ? ToObject(fields). + 5. Set additionalFields to ? ToObject(additionalFields). + 6. Return ? DefaultMergeFields(fields, additionalFields). +features: [Temporal] +includes: [deepEqual.js] +---*/ + +const cal = new Temporal.Calendar("iso8601"); + +assert.deepEqual( + cal.mergeFields({ a: 1, b: 2, month: 7 }, { b: 3, c: 4 }), + { a: 1, b: 3, c: 4, month: 7 }, + "month is copied from fields" +); +assert.deepEqual( + cal.mergeFields({ a: 1, b: 2, monthCode: "M08" }, { b: 3, c: 4 }), + { a: 1, b: 3, c: 4, monthCode: "M08" }, + "monthCode is copied from fields" +); +assert.deepEqual( + cal.mergeFields({ a: 1, b: 2, month: 7, monthCode: "M08" }, { b: 3, c: 4 }), + { a: 1, b: 3, c: 4, month: 7, monthCode: "M08" }, + "both month and monthCode are copied from fields, no validation is performed" +); + +assert.deepEqual( + cal.mergeFields({ a: 1, b: 2 }, { b: 3, c: 4, month: 5 }), + { a: 1, b: 3, c: 4, month: 5 }, + "month is copied from additionalFields" +); +assert.deepEqual( + cal.mergeFields({ a: 1, b: 2 }, { b: 3, c: 4, monthCode: "M06" }), + { a: 1, b: 3, c: 4, monthCode: "M06" }, + "monthCode is copied from additionalFields" +); +assert.deepEqual( + cal.mergeFields({ a: 1, b: 2 }, { b: 3, c: 4, month: 5, monthCode: "M06" }), + { a: 1, b: 3, c: 4, month: 5, monthCode: "M06" }, + "both month and monthCode are copied from additionalFields, no validation is performed" +); + +assert.deepEqual( + cal.mergeFields({ a: 1, b: 2, month: 7 }, { b: 3, c: 4, month: 5 }), + { a: 1, b: 3, c: 4, month: 5 }, + "month from additionalFields overrides month from fields" +); +assert.deepEqual( + cal.mergeFields({ a: 1, b: 2, monthCode: "M07" }, { b: 3, c: 4, monthCode: "M05" }), + { a: 1, b: 3, c: 4, monthCode: "M05" }, + "monthCode from additionalFields overrides monthCode from fields" +); +assert.deepEqual( + cal.mergeFields({ a: 1, b: 2, monthCode: "M07" }, { b: 3, c: 4, month: 6 }), + { a: 1, b: 3, c: 4, month: 6 }, + "month's presence on additionalFields blocks monthCode from fields" +); +assert.deepEqual( + cal.mergeFields({ a: 1, b: 2, month: 7 }, { b: 3, c: 4, monthCode: "M06" }), + { a: 1, b: 3, c: 4, monthCode: "M06"}, + "monthCode's presence on additionalFields blocks month from fields" +); +assert.deepEqual( + cal.mergeFields({ a: 1, b: 2, month: 7, monthCode: "M08" },{ b: 3, c: 4, month: 5 }), + { a: 1, b: 3, c: 4, month: 5 }, + "month's presence on additionalFields blocks both month and monthCode from fields" +); +assert.deepEqual( + cal.mergeFields({ a: 1, b: 2, month: 7, monthCode: "M08" }, { b: 3, c: 4, monthCode: "M06" }), + { a: 1, b: 3, c: 4, monthCode: "M06" }, + "monthCode's presence on additionalFields blocks both month and monthCode from fields" +); + +assert.deepEqual( + cal.mergeFields({ a: 1, b: 2, month: 7 }, { b: 3, c: 4, month: 5, monthCode: "M06" }), + { a: 1, b: 3, c: 4, month: 5, monthCode: "M06" }, + "both month and monthCode are copied from additionalFields even when fields has month" +); +assert.deepEqual( + cal.mergeFields({ a: 1, b: 2, monthCode: "M07" }, { b: 3, c: 4, month: 5, monthCode: "M06" }), + { a: 1, b: 3, c: 4, month: 5, monthCode: "M06" }, + "both month and monthCode are copied from additionalFields even when fields has monthCode" +); +assert.deepEqual( + cal.mergeFields({ a: 1, b: 2, month: 7, monthCode: "M08" }, { b: 3, c: 4, month: 5, monthCode: "M06" }), + { a: 1, b: 3, c: 4, month: 5, monthCode: "M06" }, + "both month and monthCode are copied from additionalFields even when fields has both month and monthCode" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/length.js new file mode 100644 index 0000000000..5745e5707e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/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.calendar.prototype.mergefields +description: Temporal.Calendar.prototype.mergeFields.length is 2 +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.Calendar.prototype.mergeFields, "length", { + value: 2, + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/name.js new file mode 100644 index 0000000000..72aa903d84 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/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.calendar.prototype.mergefields +description: Temporal.Calendar.prototype.mergeFields.name is "mergeFields". +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.Calendar.prototype.mergeFields, "name", { + value: "mergeFields", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/non-string-properties.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/non-string-properties.js new file mode 100644 index 0000000000..a7b49ce3a8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/non-string-properties.js @@ -0,0 +1,58 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// 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.calendar.prototype.mergefields +description: Both string and symbol keys from the arguments are merged +info: | + 1. Let calendar be the this value. + 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]). + 3. Assert: calendar.[[Identifier]] is "iso8601". + 4. Set fields to ? ToObject(fields). + 5. Set additionalFields to ? ToObject(additionalFields). + 6. Return ? DefaultMergeFields(fields, additionalFields). +features: [Temporal] +---*/ + +function assertEntriesEqual(actual, expectedEntries, message) { + const names = Object.getOwnPropertyNames(actual); + const symbols = Object.getOwnPropertySymbols(actual); + const actualKeys = names.concat(symbols); + assert.sameValue( + actualKeys.length, + expectedEntries.length, + `${message}: expected object to have ${expectedEntries.length} properties, not ${actualKeys.length}:` + ); + for (var index = 0; index < actualKeys.length; index++) { + const actualKey = actualKeys[index]; + const expectedKey = expectedEntries[index][0]; + const expectedValue = expectedEntries[index][1]; + assert.sameValue(actualKey, expectedKey, `${message}: key ${index}:`); + assert.sameValue(actual[actualKey], expectedValue, `${message}: value ${index}:`); + } +} + +const cal = new Temporal.Calendar("iso8601"); + +assertEntriesEqual( + cal.mergeFields({ 1: 2 }, { 3: 4 }), + [["1", 2], ["3", 4]], + "number keys are actually string keys and are merged as such" +); +assertEntriesEqual( + cal.mergeFields({ 1n: 2 }, { 2n: 4 }), + [["1", 2], ["2", 4]], + "bigint keys are actually string keys and are merged as such" +); + +const foo = Symbol("foo"); +const bar = Symbol("bar"); +assertEntriesEqual( + cal.mergeFields({ [foo]: 1 }, { [bar]: 2 }), + [[foo, 1], [bar, 2]], + "symbol keys are also merged" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/not-a-constructor.js new file mode 100644 index 0000000000..278131dceb --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/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.calendar.prototype.mergefields +description: > + Temporal.Calendar.prototype.mergeFields 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.Calendar.prototype.mergeFields(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.Calendar.prototype.mergeFields), false, + "isConstructor(Temporal.Calendar.prototype.mergeFields)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/order-of-operations.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/order-of-operations.js new file mode 100644 index 0000000000..aaefb3f15f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/order-of-operations.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.calendar.prototype.mergefields +description: Properties on objects passed to mergeFields() are accessed in the correct order +features: [Temporal] +includes: [compareArray.js, temporalHelpers.js] +---*/ + +const expected = [ + // CopyDataProperties on fields + "ownKeys fields", + "getOwnPropertyDescriptor fields.year", + "get fields.year", + "getOwnPropertyDescriptor fields.month", + "get fields.month", + "getOwnPropertyDescriptor fields.day", + "get fields.day", + "getOwnPropertyDescriptor fields.extra", + "get fields.extra", + // CopyDataProperties on additionalFields + "ownKeys additionalFields", + "getOwnPropertyDescriptor additionalFields.3", + "get additionalFields.3", + "getOwnPropertyDescriptor additionalFields.monthCode", + "get additionalFields.monthCode", + "getOwnPropertyDescriptor additionalFields[Symbol('extra')]", + "get additionalFields[Symbol('extra')]", +]; +const actual = []; + +const fields = TemporalHelpers.propertyBagObserver(actual, { + year: 2022, + month: 10, + day: 17, + extra: "extra property", +}, "fields"); +const additionalFields = TemporalHelpers.propertyBagObserver(actual, { + [Symbol("extra")]: "extra symbol property", + monthCode: "M10", + 3: "extra array index property", +}, "additionalFields"); + +const instance = new Temporal.Calendar("iso8601"); +instance.mergeFields(fields, additionalFields); +assert.compareArray(actual, expected, "order of observable operations"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/prop-desc.js new file mode 100644 index 0000000000..dc0ec20df3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/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.calendar.prototype.mergefields +description: The "mergeFields" property of Temporal.Calendar.prototype +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.Calendar.prototype.mergeFields, + "function", + "`typeof Calendar.prototype.mergeFields` is `function`" +); + +verifyProperty(Temporal.Calendar.prototype, "mergeFields", { + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/shell.js new file mode 100644 index 0000000000..346758ebd5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/shell.js @@ -0,0 +1,353 @@ +// GENERATED, DO NOT EDIT +// file: deepEqual.js +// Copyright 2019 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: > + Compare two values structurally +defines: [assert.deepEqual] +---*/ + +assert.deepEqual = function(actual, expected, message) { + var format = assert.deepEqual.format; + assert( + assert.deepEqual._compare(actual, expected), + `Expected ${format(actual)} to be structurally equal to ${format(expected)}. ${(message || '')}` + ); +}; + +assert.deepEqual.format = function(value, seen) { + switch (typeof value) { + case 'string': + return typeof JSON !== "undefined" ? JSON.stringify(value) : `"${value}"`; + case 'number': + case 'boolean': + case 'symbol': + case 'bigint': + return value.toString(); + case 'undefined': + return 'undefined'; + case 'function': + return `[Function${value.name ? `: ${value.name}` : ''}]`; + case 'object': + if (value === null) return 'null'; + if (value instanceof Date) return `Date "${value.toISOString()}"`; + if (value instanceof RegExp) return value.toString(); + if (!seen) { + seen = { + counter: 0, + map: new Map() + }; + } + + let usage = seen.map.get(value); + if (usage) { + usage.used = true; + return `[Ref: #${usage.id}]`; + } + + usage = { id: ++seen.counter, used: false }; + seen.map.set(value, usage); + + if (typeof Set !== "undefined" && value instanceof Set) { + return `Set {${Array.from(value).map(value => assert.deepEqual.format(value, seen)).join(', ')}}${usage.used ? ` as #${usage.id}` : ''}`; + } + if (typeof Map !== "undefined" && value instanceof Map) { + return `Map {${Array.from(value).map(pair => `${assert.deepEqual.format(pair[0], seen)} => ${assert.deepEqual.format(pair[1], seen)}}`).join(', ')}}${usage.used ? ` as #${usage.id}` : ''}`; + } + if (Array.isArray ? Array.isArray(value) : value instanceof Array) { + return `[${value.map(value => assert.deepEqual.format(value, seen)).join(', ')}]${usage.used ? ` as #${usage.id}` : ''}`; + } + let tag = Symbol.toStringTag in value ? value[Symbol.toStringTag] : 'Object'; + if (tag === 'Object' && Object.getPrototypeOf(value) === null) { + tag = '[Object: null prototype]'; + } + return `${tag ? `${tag} ` : ''}{ ${Object.keys(value).map(key => `${key.toString()}: ${assert.deepEqual.format(value[key], seen)}`).join(', ')} }${usage.used ? ` as #${usage.id}` : ''}`; + default: + return typeof value; + } +}; + +assert.deepEqual._compare = (function () { + var EQUAL = 1; + var NOT_EQUAL = -1; + var UNKNOWN = 0; + + function deepEqual(a, b) { + return compareEquality(a, b) === EQUAL; + } + + function compareEquality(a, b, cache) { + return compareIf(a, b, isOptional, compareOptionality) + || compareIf(a, b, isPrimitiveEquatable, comparePrimitiveEquality) + || compareIf(a, b, isObjectEquatable, compareObjectEquality, cache) + || NOT_EQUAL; + } + + function compareIf(a, b, test, compare, cache) { + return !test(a) + ? !test(b) ? UNKNOWN : NOT_EQUAL + : !test(b) ? NOT_EQUAL : cacheComparison(a, b, compare, cache); + } + + function tryCompareStrictEquality(a, b) { + return a === b ? EQUAL : UNKNOWN; + } + + function tryCompareTypeOfEquality(a, b) { + return typeof a !== typeof b ? NOT_EQUAL : UNKNOWN; + } + + function tryCompareToStringTagEquality(a, b) { + var aTag = Symbol.toStringTag in a ? a[Symbol.toStringTag] : undefined; + var bTag = Symbol.toStringTag in b ? b[Symbol.toStringTag] : undefined; + return aTag !== bTag ? NOT_EQUAL : UNKNOWN; + } + + function isOptional(value) { + return value === undefined + || value === null; + } + + function compareOptionality(a, b) { + return tryCompareStrictEquality(a, b) + || NOT_EQUAL; + } + + function isPrimitiveEquatable(value) { + switch (typeof value) { + case 'string': + case 'number': + case 'bigint': + case 'boolean': + case 'symbol': + return true; + default: + return isBoxed(value); + } + } + + function comparePrimitiveEquality(a, b) { + if (isBoxed(a)) a = a.valueOf(); + if (isBoxed(b)) b = b.valueOf(); + return tryCompareStrictEquality(a, b) + || tryCompareTypeOfEquality(a, b) + || compareIf(a, b, isNaNEquatable, compareNaNEquality) + || NOT_EQUAL; + } + + function isNaNEquatable(value) { + return typeof value === 'number'; + } + + function compareNaNEquality(a, b) { + return isNaN(a) && isNaN(b) ? EQUAL : NOT_EQUAL; + } + + function isObjectEquatable(value) { + return typeof value === 'object'; + } + + function compareObjectEquality(a, b, cache) { + if (!cache) cache = new Map(); + return getCache(cache, a, b) + || setCache(cache, a, b, EQUAL) // consider equal for now + || cacheComparison(a, b, tryCompareStrictEquality, cache) + || cacheComparison(a, b, tryCompareToStringTagEquality, cache) + || compareIf(a, b, isValueOfEquatable, compareValueOfEquality) + || compareIf(a, b, isToStringEquatable, compareToStringEquality) + || compareIf(a, b, isArrayLikeEquatable, compareArrayLikeEquality, cache) + || compareIf(a, b, isStructurallyEquatable, compareStructuralEquality, cache) + || compareIf(a, b, isIterableEquatable, compareIterableEquality, cache) + || cacheComparison(a, b, fail, cache); + } + + function isBoxed(value) { + return value instanceof String + || value instanceof Number + || value instanceof Boolean + || typeof Symbol === 'function' && value instanceof Symbol + || typeof BigInt === 'function' && value instanceof BigInt; + } + + function isValueOfEquatable(value) { + return value instanceof Date; + } + + function compareValueOfEquality(a, b) { + return compareIf(a.valueOf(), b.valueOf(), isPrimitiveEquatable, comparePrimitiveEquality) + || NOT_EQUAL; + } + + function isToStringEquatable(value) { + return value instanceof RegExp; + } + + function compareToStringEquality(a, b) { + return compareIf(a.toString(), b.toString(), isPrimitiveEquatable, comparePrimitiveEquality) + || NOT_EQUAL; + } + + function isArrayLikeEquatable(value) { + return (Array.isArray ? Array.isArray(value) : value instanceof Array) + || (typeof Uint8Array === 'function' && value instanceof Uint8Array) + || (typeof Uint8ClampedArray === 'function' && value instanceof Uint8ClampedArray) + || (typeof Uint16Array === 'function' && value instanceof Uint16Array) + || (typeof Uint32Array === 'function' && value instanceof Uint32Array) + || (typeof Int8Array === 'function' && value instanceof Int8Array) + || (typeof Int16Array === 'function' && value instanceof Int16Array) + || (typeof Int32Array === 'function' && value instanceof Int32Array) + || (typeof Float32Array === 'function' && value instanceof Float32Array) + || (typeof Float64Array === 'function' && value instanceof Float64Array) + || (typeof BigUint64Array === 'function' && value instanceof BigUint64Array) + || (typeof BigInt64Array === 'function' && value instanceof BigInt64Array); + } + + function compareArrayLikeEquality(a, b, cache) { + if (a.length !== b.length) return NOT_EQUAL; + for (var i = 0; i < a.length; i++) { + if (compareEquality(a[i], b[i], cache) === NOT_EQUAL) { + return NOT_EQUAL; + } + } + return EQUAL; + } + + function isStructurallyEquatable(value) { + return !(typeof Promise === 'function' && value instanceof Promise // only comparable by reference + || typeof WeakMap === 'function' && value instanceof WeakMap // only comparable by reference + || typeof WeakSet === 'function' && value instanceof WeakSet // only comparable by reference + || typeof Map === 'function' && value instanceof Map // comparable via @@iterator + || typeof Set === 'function' && value instanceof Set); // comparable via @@iterator + } + + function compareStructuralEquality(a, b, cache) { + var aKeys = []; + for (var key in a) aKeys.push(key); + + var bKeys = []; + for (var key in b) bKeys.push(key); + + if (aKeys.length !== bKeys.length) { + return NOT_EQUAL; + } + + aKeys.sort(); + bKeys.sort(); + + for (var i = 0; i < aKeys.length; i++) { + var aKey = aKeys[i]; + var bKey = bKeys[i]; + if (compareEquality(aKey, bKey, cache) === NOT_EQUAL) { + return NOT_EQUAL; + } + if (compareEquality(a[aKey], b[bKey], cache) === NOT_EQUAL) { + return NOT_EQUAL; + } + } + + return compareIf(a, b, isIterableEquatable, compareIterableEquality, cache) + || EQUAL; + } + + function isIterableEquatable(value) { + return typeof Symbol === 'function' + && typeof value[Symbol.iterator] === 'function'; + } + + function compareIteratorEquality(a, b, cache) { + if (typeof Map === 'function' && a instanceof Map && b instanceof Map || + typeof Set === 'function' && a instanceof Set && b instanceof Set) { + if (a.size !== b.size) return NOT_EQUAL; // exit early if we detect a difference in size + } + + var ar, br; + while (true) { + ar = a.next(); + br = b.next(); + if (ar.done) { + if (br.done) return EQUAL; + if (b.return) b.return(); + return NOT_EQUAL; + } + if (br.done) { + if (a.return) a.return(); + return NOT_EQUAL; + } + if (compareEquality(ar.value, br.value, cache) === NOT_EQUAL) { + if (a.return) a.return(); + if (b.return) b.return(); + return NOT_EQUAL; + } + } + } + + function compareIterableEquality(a, b, cache) { + return compareIteratorEquality(a[Symbol.iterator](), b[Symbol.iterator](), cache); + } + + function cacheComparison(a, b, compare, cache) { + var result = compare(a, b, cache); + if (cache && (result === EQUAL || result === NOT_EQUAL)) { + setCache(cache, a, b, /** @type {EQUAL | NOT_EQUAL} */(result)); + } + return result; + } + + function fail() { + return NOT_EQUAL; + } + + function setCache(cache, left, right, result) { + var otherCache; + + otherCache = cache.get(left); + if (!otherCache) cache.set(left, otherCache = new Map()); + otherCache.set(right, result); + + otherCache = cache.get(right); + if (!otherCache) cache.set(right, otherCache = new Map()); + otherCache.set(left, result); + } + + function getCache(cache, left, right) { + var otherCache; + var result; + + otherCache = cache.get(left); + result = otherCache && otherCache.get(right); + if (result) return result; + + otherCache = cache.get(right); + result = otherCache && otherCache.get(left); + if (result) return result; + + return UNKNOWN; + } + + return deepEqual; +})(); + +// 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/Calendar/prototype/month/argument-calendar-datefromfields-called-with-null-prototype-fields.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-calendar-datefromfields-called-with-null-prototype-fields.js new file mode 100644 index 0000000000..612ae7ef22 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-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.calendar.prototype.month +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.Calendar("iso8601"); +const arg = { year: 2000, month: 5, day: 2, calendar }; +instance.month(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/Calendar/prototype/month/argument-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-leap-second.js new file mode 100644 index 0000000000..9be9b828c3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-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.calendar.prototype.month +description: Leap second is a valid ISO string for PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.month(arg); +assert.sameValue( + result1, + 12, + "leap second is a valid ISO string for PlainDate" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.month(arg); +assert.sameValue( + result2, + 12, + "second: 60 is ignored in property bag for PlainDate" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-number.js new file mode 100644 index 0000000000..83810e8a23 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/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.calendar.prototype.month +description: A number is converted to a string, then to Temporal.PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const arg = 19761118; + +const result = instance.month(arg); +assert.sameValue(result, 11, "19761118 is a valid ISO string for PlainDate"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.month(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-case-insensitive.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-case-insensitive.js new file mode 100644 index 0000000000..14ae69223d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/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.calendar.prototype.month +description: The calendar name is case-insensitive +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "IsO8601"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.month(arg); +assert.sameValue(result1, 11, "Calendar is case-insensitive"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.month(arg); +assert.sameValue(result2, 11, "Calendar is case-insensitive (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-instance-does-not-get-calendar-property.js new file mode 100644 index 0000000000..88403d070f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/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.calendar.prototype.month +description: > + A Temporal.Calendar instance passed to month() in a property bag does + not have its 'calendar' property observably checked +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +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.month(arg); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +instance.month(arg); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-leap-second.js new file mode 100644 index 0000000000..35f6ed0d42 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/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.calendar.prototype.month +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.month(arg); +assert.sameValue( + result1, + 11, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.month(arg); +assert.sameValue( + result2, + 11, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-number.js new file mode 100644 index 0000000000..53398e531b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/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.calendar.prototype.month +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.month(arg); +assert.sameValue(result1, 11, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.month(arg); +assert.sameValue(result2, 11, "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.month(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.month(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/Calendar/prototype/month/argument-propertybag-calendar-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-string.js new file mode 100644 index 0000000000..23a19f3cd4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/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.calendar.prototype.month +description: A calendar ID is valid input for Calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "iso8601"; + +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.month(arg); +assert.sameValue(result, 11, `Calendar created from string "${calendar}"`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 0000000000..102d2f20e3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/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.calendar.prototype.month +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.Calendar("iso8601"); + +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.month(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.month(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.month(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.month(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.month(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-year-zero.js new file mode 100644 index 0000000000..f5741c4283 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/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.calendar.prototype.month +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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.month(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-calendar-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-calendar-annotation.js new file mode 100644 index 0000000000..4bb9c95cf2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/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.calendar.prototype.month +description: Various forms of calendar annotation; critical flag has no effect +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02[u-ca=iso8601]", "without time or time zone"], + ["2000-05-02[UTC][u-ca=iso8601]", "with time zone and no time"], + ["2000-05-02T15:23[u-ca=iso8601]", "without time zone"], + ["2000-05-02T15:23[UTC][u-ca=iso8601]", "with time zone"], + ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], + ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], + ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], + ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.month(arg); + + assert.sameValue( + result, + 5, + `calendar annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-critical-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-critical-unknown-annotation.js new file mode 100644 index 0000000000..26e93335d0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-critical-unknown-annotation.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.calendar.prototype.month +description: Unknown annotations with critical flag are rejected +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[!foo=bar]", + "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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.month(arg), + `reject unknown annotation with critical flag: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-date-with-utc-offset.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-date-with-utc-offset.js new file mode 100644 index 0000000000..6b81b678f2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/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.calendar.prototype.month +description: UTC offset not valid with format that does not include a time +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const validStrings = [ + "2000-05-02T00+00:00", + "2000-05-02T00+00:00[UTC]", + "2000-05-02T00+00:00[!UTC]", + "2000-05-02T00-02:30[America/St_Johns]", +]; + +for (const arg of validStrings) { + const result = instance.month(arg); + + assert.sameValue( + result, + 5, + `"${arg}" is a valid UTC offset with time for PlainDate` + ); +} + +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.month(arg), + `"${arg}" UTC offset without time is not valid for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-invalid.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-invalid.js new file mode 100644 index 0000000000..c6fd9cd2a2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-invalid.js @@ -0,0 +1,64 @@ +// |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.calendar.prototype.month +description: > + RangeError thrown if an invalid ISO string (or syntactically valid ISO string + that is not supported) is used as a PlainDate +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + // invalid ISO strings: + "", + "invalid iso8601", + "2020-01-00", + "2020-01-32", + "2020-02-30", + "2021-02-29", + "2020-00-01", + "2020-13-01", + "2020-01-01T", + "2020-01-01T25:00:00", + "2020-01-01T01:60:00", + "2020-01-01T01:60:61", + "2020-01-01junk", + "2020-01-01T00:00:00junk", + "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-01", + "2020-001-01", + "2020-01-001", + "2020-01-01T001", + "2020-01-01T01:001", + "2020-01-01T01:01:001", + // valid, but forms not supported in Temporal: + "2020-W01-1", + "2020-001", + "+0002020-01-01", + // valid, but this calendar must not exist: + "2020-01-01[u-ca=notexist]", + // may be valid in other contexts, but insufficient information for PlainDate: + "2020-01", + "+002020-01", + "01-01", + "2020-W01", + "P1Y", + "-P12Y", + // valid, but outside the supported range: + "-999999-01-01", + "+999999-01-01", +]; +const instance = new Temporal.Calendar("iso8601"); +for (const arg of invalidStrings) { + assert.throws( + RangeError, + () => instance.month(arg), + `"${arg}" should not be a valid ISO string for a PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-multiple-time-zone.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-multiple-time-zone.js new file mode 100644 index 0000000000..8306245e57 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-multiple-time-zone.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.calendar.prototype.month +description: More than one time zone annotation is not syntactical +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[UTC][UTC]", + "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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.month(arg), + `reject more than one time zone annotation: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-time-separators.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-time-separators.js new file mode 100644 index 0000000000..69ae55a3d2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/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.calendar.prototype.month +description: Time separator in string argument can vary +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02T15:23", "uppercase T"], + ["2000-05-02t15:23", "lowercase T"], + ["2000-05-02 15:23", "space between date and time"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.month(arg); + + assert.sameValue( + result, + 5, + `variant time separators (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-time-zone-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-time-zone-annotation.js new file mode 100644 index 0000000000..7b4e81adf8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-time-zone-annotation.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.calendar.prototype.month +description: Various forms of time zone annotation; critical flag has no effect +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02[Asia/Kolkata]", "named, with no time"], + ["2000-05-02[!Europe/Vienna]", "named, with ! and no time"], + ["2000-05-02[+00:00]", "numeric, with no time"], + ["2000-05-02[!-02:30]", "numeric, with ! and no time"], + ["2000-05-02T15:23[America/Sao_Paulo]", "named, with no offset"], + ["2000-05-02T15:23[!Asia/Tokyo]", "named, with ! and no offset"], + ["2000-05-02T15:23[-02:30]", "numeric, with no offset"], + ["2000-05-02T15:23[!+00:00]", "numeric, with ! and no offset"], + ["2000-05-02T15:23+00:00[America/New_York]", "named, with offset"], + ["2000-05-02T15:23+00:00[!UTC]", "named, with offset and !"], + ["2000-05-02T15:23+00:00[+01:00]", "numeric, with offset"], + ["2000-05-02T15:23+00:00[!-08:00]", "numeric, with offset and !"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.month(arg); + + assert.sameValue( + result, + 5, + `time zone annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-unknown-annotation.js new file mode 100644 index 0000000000..cff47cb874 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/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.calendar.prototype.month +description: Various forms of unknown annotation +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02[foo=bar]", "without time"], + ["2000-05-02T15:23[foo=bar]", "alone"], + ["2000-05-02T15:23[UTC][foo=bar]", "with time zone"], + ["2000-05-02T15:23[u-ca=iso8601][foo=bar]", "with calendar"], + ["2000-05-02T15:23[UTC][foo=bar][u-ca=iso8601]", "with time zone and calendar"], + ["2000-05-02T15:23[foo=bar][_foo-bar0=Ignore-This-999999999999]", "with another unknown annotation"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.month(arg); + + assert.sameValue( + result, + 5, + `unknown annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-with-utc-designator.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-with-utc-designator.js new file mode 100644 index 0000000000..8e1458706c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/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.calendar.prototype.month +description: RangeError thrown if a string with UTC designator is used as a PlainDate +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "2019-10-01T09:00:00Z", + "2019-10-01T09:00:00Z[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.month(arg), + "String with UTC designator should not be valid as a PlainDate" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-wrong-type.js new file mode 100644 index 0000000000..679b695387 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/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.calendar.prototype.month +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +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.month(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.month(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/Calendar/prototype/month/argument-zoneddatetime-convert.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-zoneddatetime-convert.js new file mode 100644 index 0000000000..56a3af5b15 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-zoneddatetime-convert.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.calendar.prototype.month +description: An exception from TimeZone#getOffsetNanosecondsFor() is propagated. +features: [Temporal] +---*/ + +class TZ extends Temporal.TimeZone { + constructor() { super("UTC") } + getOffsetNanosecondsFor() { throw new Test262Error() } +} + +const tz = new TZ(); +const arg = new Temporal.ZonedDateTime(0n, tz); +const instance = new Temporal.Calendar("iso8601"); + +assert.throws(Test262Error, () => instance.month(arg)); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-zoneddatetime-slots.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-zoneddatetime-slots.js new file mode 100644 index 0000000000..504c1d2dad --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-zoneddatetime-slots.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.calendar.prototype.month +description: Getters are not called when converting a ZonedDateTime to a PlainDate. +includes: [compareArray.js] +features: [Temporal] +---*/ + +const actual = []; +const prototypeDescrs = Object.getOwnPropertyDescriptors(Temporal.ZonedDateTime.prototype); +const getters = ["year", "month", "monthCode", "day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond", "calendar"]; + +for (const property of getters) { + Object.defineProperty(Temporal.ZonedDateTime.prototype, property, { + get() { + actual.push(`get ${property}`); + const value = prototypeDescrs[property].get.call(this); + return { + toString() { + actual.push(`toString ${property}`); + return value.toString(); + }, + valueOf() { + actual.push(`valueOf ${property}`); + return value; + }, + }; + }, + }); +} + +const arg = new Temporal.ZonedDateTime(0n, "UTC"); +const instance = new Temporal.Calendar("iso8601"); +instance.month(arg); +assert.compareArray(actual, []); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js new file mode 100644 index 0000000000..27660266a2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/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.calendar.prototype.month +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(RangeError, () => calendar.month(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js new file mode 100644 index 0000000000..da3ae3d28b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/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.calendar.prototype.month +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + timeZone.getOffsetNanosecondsFor = notCallable; + assert.throws( + TypeError, + () => calendar.month(datetime), + `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js new file mode 100644 index 0000000000..70d830d29c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/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.calendar.prototype.month +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(RangeError, () => calendar.month(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js new file mode 100644 index 0000000000..dee10750c4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/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.calendar.prototype.month +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(TypeError, () => calendar.month(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/basic.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/basic.js new file mode 100644 index 0000000000..36580f5c82 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/basic.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.calendar.prototype.month +description: Basic tests for month(). +features: [Temporal] +---*/ + +const iso = Temporal.Calendar.from("iso8601"); +const res = 11; +assert.sameValue(iso.month(Temporal.PlainDate.from("1994-11-05")), res, "PlainDate"); +assert.sameValue(iso.month(Temporal.PlainDateTime.from("1994-11-05T08:15:30")), res, "PlainDateTime"); +assert.sameValue(iso.month(Temporal.PlainYearMonth.from("1994-11")), res, "PlainYearMonth"); +assert.sameValue(iso.month({ year: 1994, month: 11, day: 5 }), res, "property bag"); +assert.sameValue(iso.month("1994-11-05"), res, "string"); +assert.throws(TypeError, () => iso.month({ year: 2000 }), "property bag with missing properties"); +assert.throws(TypeError, () => iso.month(Temporal.PlainMonthDay.from("11-05")), "PlainMonthDay"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/branding.js new file mode 100644 index 0000000000..45b529d18e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/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.calendar.prototype.month +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const month = Temporal.Calendar.prototype.month; + +assert.sameValue(typeof month, "function"); + +const args = [new Temporal.PlainDate(2000, 1, 1)]; + +assert.throws(TypeError, () => month.apply(undefined, args), "undefined"); +assert.throws(TypeError, () => month.apply(null, args), "null"); +assert.throws(TypeError, () => month.apply(true, args), "true"); +assert.throws(TypeError, () => month.apply("", args), "empty string"); +assert.throws(TypeError, () => month.apply(Symbol(), args), "symbol"); +assert.throws(TypeError, () => month.apply(1, args), "1"); +assert.throws(TypeError, () => month.apply({}, args), "plain object"); +assert.throws(TypeError, () => month.apply(Temporal.Calendar, args), "Temporal.Calendar"); +assert.throws(TypeError, () => month.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/builtin.js new file mode 100644 index 0000000000..b99d76febd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/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.calendar.prototype.month +description: > + Tests that Temporal.Calendar.prototype.month + 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.Calendar.prototype.month), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.month), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.month), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.Calendar.prototype.month.hasOwnProperty("prototype"), + false, "prototype property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/calendar-datefromfields-called-with-options-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/calendar-datefromfields-called-with-options-undefined.js new file mode 100644 index 0000000000..7921f038fb --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/calendar-datefromfields-called-with-options-undefined.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.calendar.prototype.month +description: > + Calendar.dateFromFields method is called with undefined as the options value + when call originates internally +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = TemporalHelpers.calendarFromFieldsUndefinedOptions(); +calendar.month({ year: 2000, month: 5, day: 3, calendar }); +assert.sameValue(calendar.dateFromFieldsCallCount, 1); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/calendar-fields-iterable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/calendar-fields-iterable.js new file mode 100644 index 0000000000..f6d983a50e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/calendar-fields-iterable.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.calendar.prototype.month +description: Verify the result of calendar.fields() is treated correctly. +info: | + sec-temporal.calendar.prototype.month step 4: + 4. Return ? ISOMonth(_dateOrDateTime_). + sec-temporal-isomonth step 1.a: + a. Set _dateOrDateTime_ to ? ToTemporalDate(_dateOrDateTime_). + sec-temporal-totemporaldate step 2.c: + c. Let _fieldNames_ be ? CalendarFields(_calendar_, « *"day"*, *"month"*, *"monthCode"*, *"year"* »). + sec-temporal-calendarfields step 4: + 4. Let _result_ be ? IterableToListOfType(_fieldsArray_, « String »). +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + "day", + "month", + "monthCode", + "year", +]; + +const calendar1 = TemporalHelpers.calendarFieldsIterable(); +const calendar2 = TemporalHelpers.calendarFieldsIterable(); +calendar1.month({ year: 2000, month: 5, day: 2, calendar: calendar2 }); + +assert.sameValue(calendar1.fieldsCallCount, 0, "fields() method not called"); +assert.sameValue(calendar2.fieldsCallCount, 1, "fields() method called once"); +assert.compareArray(calendar2.fieldsCalledWith[0], expected, "fields() method called with correct args"); +assert(calendar2.iteratorExhausted[0], "iterated through the whole iterable"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/calendar-temporal-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/calendar-temporal-object.js new file mode 100644 index 0000000000..a2b6b1e4a7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/calendar-temporal-object.js @@ -0,0 +1,31 @@ +// |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.calendar.prototype.month +description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots +info: | + sec-temporal.calendar.prototype.month step 4: + 4. Return ? ISOMonth(_dateOrDateTime_). + sec-temporal-isomonth step 1.a: + a. Set _dateOrDateTime_ to ? ToTemporalDate(_dateOrDateTime_). + sec-temporal-totemporaldate 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 calendar = new Temporal.Calendar("iso8601"); + calendar.month({ year: 2000, month: 5, day: 2, calendar: temporalObject }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/date-time.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/date-time.js new file mode 100644 index 0000000000..f4f6589547 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/date-time.js @@ -0,0 +1,23 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.month +description: > + Temporal.Calendar.prototype.month will take PlainDateTime and return + the value of the month. +info: | + 5. If Type(temporalDateLike) is not Object or temporalDateLike does not have + an [[InitializedTemporalDate]] or [[InitializedTemporalYearMonth]] + internal slot, then + a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike). + 6. Return ! ISOMonth(temporalDateLike). +features: [Temporal] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +let dateTime = new Temporal.PlainDateTime(1997, 8, 23, 5, 30, 13) +assert.sameValue(cal.month(dateTime), 8, 'cal.month(new Temporal.PlainDateTime(1997, 8, 23, 5, 30, 13)) must return 8'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/date.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/date.js new file mode 100644 index 0000000000..a2a7ece2b9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/date.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.month +description: > + Temporal.Calendar.prototype.month will take PlainDate and return + the value of the month. +info: | + 1. Let calendar be the this value. + 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]). + 3. Assert: calendar.[[Identifier]] is "iso8601". + 4. If Type(temporalDateLike) is Object and temporalDateLike has an + [[InitializedTemporalMonthDay]] internal slot, then + a. Throw a TypeError exception. + 5. If Type(temporalDateLike) is not Object or temporalDateLike does not have + an [[InitializedTemporalDate]] or [[InitializedTemporalYearMonth]] + internal slot, then + a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike). + 6. Return ! ISOMonth(temporalDateLike). +features: [Temporal] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +let date = new Temporal.PlainDate(2021, 7, 15); +assert.sameValue(cal.month(date), 7, 'cal.month(new Temporal.PlainDate(2021, 7, 15)) must return 7'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/infinity-throws-rangeerror.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/infinity-throws-rangeerror.js new file mode 100644 index 0000000000..c6af471ade --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/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.calendar.prototype.month +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); +const base = { year: 2000, month: 5, day: 2 }; + +[Infinity, -Infinity].forEach((inf) => { + ["year", "month", "day"].forEach((prop) => { + assert.throws(RangeError, () => instance.month({ ...base, [prop]: inf }), `${prop} property cannot be ${inf}`); + + const calls = []; + const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop); + assert.throws(RangeError, () => instance.month({ ...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/Calendar/prototype/month/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/length.js new file mode 100644 index 0000000000..899dd6d074 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/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.calendar.prototype.month +description: Temporal.Calendar.prototype.month.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.Calendar.prototype.month, "length", { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/month-day-throw-type-error.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/month-day-throw-type-error.js new file mode 100644 index 0000000000..2c118fd786 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/month-day-throw-type-error.js @@ -0,0 +1,23 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.month +description: > + Temporal.Calendar.prototype.month throws TypeError if temporalDateLike + is a PlainMonthDay object. + ToTemporalDate when temporalDateLike is invalid string. +info: | + 4. If Type(temporalDateLike) is Object and temporalDateLike has an + [[InitializedTemporalMonthDay]] internal slot, then + a. Throw a TypeError exception. +features: [Temporal, arrow-function] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +let monthDay = new Temporal.PlainMonthDay(12, 25); +assert.throws(TypeError, () => cal.month(monthDay), + 'cal.month(monthDay) throws a TypeError exception'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/name.js new file mode 100644 index 0000000000..6d53b382ec --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/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.calendar.prototype.month +description: Temporal.Calendar.prototype.month.name is "month". +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.Calendar.prototype.month, "name", { + value: "month", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/not-a-constructor.js new file mode 100644 index 0000000000..a22c3e0e42 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/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.calendar.prototype.month +description: > + Temporal.Calendar.prototype.month 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.Calendar.prototype.month(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.Calendar.prototype.month), false, + "isConstructor(Temporal.Calendar.prototype.month)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/prop-desc.js new file mode 100644 index 0000000000..0c9d7c4c94 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/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.calendar.prototype.month +description: The "month" property of Temporal.Calendar.prototype +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.Calendar.prototype.month, + "function", + "`typeof Calendar.prototype.month` is `function`" +); + +verifyProperty(Temporal.Calendar.prototype, "month", { + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/shell.js new file mode 100644 index 0000000000..eda1477282 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/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/Calendar/prototype/month/string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/string.js new file mode 100644 index 0000000000..16ee97a8e1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/string.js @@ -0,0 +1,22 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.month +description: > + Temporal.Calendar.prototype.month will take ISO8601 string and return + the value of the month. +info: | + 5. If Type(temporalDateLike) is not Object or temporalDateLike does not have + an [[InitializedTemporalDate]] or [[InitializedTemporalYearMonth]] internal + slot, then + a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike). + 6. Return ! ISOMonth(temporalDateLike). +features: [Temporal] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +assert.sameValue(cal.month("2019-03-15"), 3, 'cal.month("2019-03-15") must return 3'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/throw-range-error-ToTemporalDate.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/throw-range-error-ToTemporalDate.js new file mode 100644 index 0000000000..195dabce0a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/throw-range-error-ToTemporalDate.js @@ -0,0 +1,22 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.month +description: > + Temporal.Calendar.prototype.month throws RangeError on + ToTemporalDate when temporalDateLike is invalid string. +info: | + 5. If Type(temporalDateLike) is not Object or temporalDateLike + does not have an [[InitializedTemporalDate]] or + [[InitializedTemporalYearMonth]] internal slot, then + a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike). +features: [Temporal, arrow-function] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +assert.throws(RangeError, () => cal.month("invalid string"), + 'cal.month("invalid string") throws a RangeError exception'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/year-month.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/year-month.js new file mode 100644 index 0000000000..1083b6de99 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/year-month.js @@ -0,0 +1,19 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.month +description: > + Temporal.Calendar.prototype.month will take PlainYearMonth and return + the value of the month. +info: | + 6. Return ! ISOMonth(temporalDateLike). +features: [Temporal] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +let yearMonth = new Temporal.PlainYearMonth(1999, 6); +assert.sameValue(cal.month(yearMonth), 6, 'cal.month(new Temporal.PlainYearMonth(1999, 6)) must return 6'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/year-zero.js new file mode 100644 index 0000000000..928e40d6f4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/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.calendar.prototype.month +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.month(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-calendar-datefromfields-called-with-null-prototype-fields.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-calendar-datefromfields-called-with-null-prototype-fields.js new file mode 100644 index 0000000000..8737cb344a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-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.calendar.prototype.monthcode +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.Calendar("iso8601"); +const arg = { year: 2000, month: 5, day: 2, calendar }; +instance.monthCode(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/Calendar/prototype/monthCode/argument-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-leap-second.js new file mode 100644 index 0000000000..5dd69d7cdb --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-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.calendar.prototype.monthcode +description: Leap second is a valid ISO string for PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.monthCode(arg); +assert.sameValue( + result1, + "M12", + "leap second is a valid ISO string for PlainDate" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.monthCode(arg); +assert.sameValue( + result2, + "M12", + "second: 60 is ignored in property bag for PlainDate" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-number.js new file mode 100644 index 0000000000..9a49756189 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/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.calendar.prototype.monthcode +description: A number is converted to a string, then to Temporal.PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const arg = 19761118; + +const result = instance.monthCode(arg); +assert.sameValue(result, "M11", "19761118 is a valid ISO string for PlainDate"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.monthCode(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-case-insensitive.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-case-insensitive.js new file mode 100644 index 0000000000..d10b7cef78 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/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.calendar.prototype.monthcode +description: The calendar name is case-insensitive +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "IsO8601"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.monthCode(arg); +assert.sameValue(result1, "M11", "Calendar is case-insensitive"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.monthCode(arg); +assert.sameValue(result2, "M11", "Calendar is case-insensitive (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-instance-does-not-get-calendar-property.js new file mode 100644 index 0000000000..64b1c06894 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/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.calendar.prototype.monthcode +description: > + A Temporal.Calendar instance passed to monthCode() in a property bag does + not have its 'calendar' property observably checked +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +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.monthCode(arg); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +instance.monthCode(arg); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-leap-second.js new file mode 100644 index 0000000000..3c4d18bd60 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/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.calendar.prototype.monthcode +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.monthCode(arg); +assert.sameValue( + result1, + "M11", + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.monthCode(arg); +assert.sameValue( + result2, + "M11", + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-number.js new file mode 100644 index 0000000000..7a6a41b459 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/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.calendar.prototype.monthcode +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.monthCode(arg); +assert.sameValue(result1, "M11", "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.monthCode(arg); +assert.sameValue(result2, "M11", "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.monthCode(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.monthCode(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/Calendar/prototype/monthCode/argument-propertybag-calendar-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-string.js new file mode 100644 index 0000000000..0e0e7000f6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/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.calendar.prototype.monthcode +description: A calendar ID is valid input for Calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "iso8601"; + +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.monthCode(arg); +assert.sameValue(result, "M11", `Calendar created from string "${calendar}"`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 0000000000..0cd0de20b1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/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.calendar.prototype.monthcode +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.Calendar("iso8601"); + +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.monthCode(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.monthCode(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.monthCode(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.monthCode(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.monthCode(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-year-zero.js new file mode 100644 index 0000000000..e79fc0f846 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/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.calendar.prototype.monthcode +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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.monthCode(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-calendar-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-calendar-annotation.js new file mode 100644 index 0000000000..952a754586 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/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.calendar.prototype.monthcode +description: Various forms of calendar annotation; critical flag has no effect +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02[u-ca=iso8601]", "without time or time zone"], + ["2000-05-02[UTC][u-ca=iso8601]", "with time zone and no time"], + ["2000-05-02T15:23[u-ca=iso8601]", "without time zone"], + ["2000-05-02T15:23[UTC][u-ca=iso8601]", "with time zone"], + ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], + ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], + ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], + ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.monthCode(arg); + + assert.sameValue( + result, + "M05", + `calendar annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-critical-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-critical-unknown-annotation.js new file mode 100644 index 0000000000..62df7a9b2b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-critical-unknown-annotation.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.calendar.prototype.monthcode +description: Unknown annotations with critical flag are rejected +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[!foo=bar]", + "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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.monthCode(arg), + `reject unknown annotation with critical flag: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-date-with-utc-offset.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-date-with-utc-offset.js new file mode 100644 index 0000000000..a8b5b96e52 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/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.calendar.prototype.monthcode +description: UTC offset not valid with format that does not include a time +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const validStrings = [ + "2000-05-02T00+00:00", + "2000-05-02T00+00:00[UTC]", + "2000-05-02T00+00:00[!UTC]", + "2000-05-02T00-02:30[America/St_Johns]", +]; + +for (const arg of validStrings) { + const result = instance.monthCode(arg); + + assert.sameValue( + result, + "M05", + `"${arg}" is a valid UTC offset with time for PlainDate` + ); +} + +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.monthCode(arg), + `"${arg}" UTC offset without time is not valid for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-invalid.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-invalid.js new file mode 100644 index 0000000000..8f7dc62a4f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-invalid.js @@ -0,0 +1,64 @@ +// |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.calendar.prototype.monthcode +description: > + RangeError thrown if an invalid ISO string (or syntactically valid ISO string + that is not supported) is used as a PlainDate +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + // invalid ISO strings: + "", + "invalid iso8601", + "2020-01-00", + "2020-01-32", + "2020-02-30", + "2021-02-29", + "2020-00-01", + "2020-13-01", + "2020-01-01T", + "2020-01-01T25:00:00", + "2020-01-01T01:60:00", + "2020-01-01T01:60:61", + "2020-01-01junk", + "2020-01-01T00:00:00junk", + "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-01", + "2020-001-01", + "2020-01-001", + "2020-01-01T001", + "2020-01-01T01:001", + "2020-01-01T01:01:001", + // valid, but forms not supported in Temporal: + "2020-W01-1", + "2020-001", + "+0002020-01-01", + // valid, but this calendar must not exist: + "2020-01-01[u-ca=notexist]", + // may be valid in other contexts, but insufficient information for PlainDate: + "2020-01", + "+002020-01", + "01-01", + "2020-W01", + "P1Y", + "-P12Y", + // valid, but outside the supported range: + "-999999-01-01", + "+999999-01-01", +]; +const instance = new Temporal.Calendar("iso8601"); +for (const arg of invalidStrings) { + assert.throws( + RangeError, + () => instance.monthCode(arg), + `"${arg}" should not be a valid ISO string for a PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-multiple-time-zone.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-multiple-time-zone.js new file mode 100644 index 0000000000..6c36a8df20 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-multiple-time-zone.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.calendar.prototype.monthcode +description: More than one time zone annotation is not syntactical +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[UTC][UTC]", + "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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.monthCode(arg), + `reject more than one time zone annotation: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-time-separators.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-time-separators.js new file mode 100644 index 0000000000..60c9826cec --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/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.calendar.prototype.monthcode +description: Time separator in string argument can vary +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02T15:23", "uppercase T"], + ["2000-05-02t15:23", "lowercase T"], + ["2000-05-02 15:23", "space between date and time"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.monthCode(arg); + + assert.sameValue( + result, + "M05", + `variant time separators (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-time-zone-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-time-zone-annotation.js new file mode 100644 index 0000000000..6ac0263b0b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-time-zone-annotation.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.calendar.prototype.monthcode +description: Various forms of time zone annotation; critical flag has no effect +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02[Asia/Kolkata]", "named, with no time"], + ["2000-05-02[!Europe/Vienna]", "named, with ! and no time"], + ["2000-05-02[+00:00]", "numeric, with no time"], + ["2000-05-02[!-02:30]", "numeric, with ! and no time"], + ["2000-05-02T15:23[America/Sao_Paulo]", "named, with no offset"], + ["2000-05-02T15:23[!Asia/Tokyo]", "named, with ! and no offset"], + ["2000-05-02T15:23[-02:30]", "numeric, with no offset"], + ["2000-05-02T15:23[!+00:00]", "numeric, with ! and no offset"], + ["2000-05-02T15:23+00:00[America/New_York]", "named, with offset"], + ["2000-05-02T15:23+00:00[!UTC]", "named, with offset and !"], + ["2000-05-02T15:23+00:00[+01:00]", "numeric, with offset"], + ["2000-05-02T15:23+00:00[!-08:00]", "numeric, with offset and !"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.monthCode(arg); + + assert.sameValue( + result, + "M05", + `time zone annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-unknown-annotation.js new file mode 100644 index 0000000000..7552daa1a8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/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.calendar.prototype.monthcode +description: Various forms of unknown annotation +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02[foo=bar]", "without time"], + ["2000-05-02T15:23[foo=bar]", "alone"], + ["2000-05-02T15:23[UTC][foo=bar]", "with time zone"], + ["2000-05-02T15:23[u-ca=iso8601][foo=bar]", "with calendar"], + ["2000-05-02T15:23[UTC][foo=bar][u-ca=iso8601]", "with time zone and calendar"], + ["2000-05-02T15:23[foo=bar][_foo-bar0=Ignore-This-999999999999]", "with another unknown annotation"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.monthCode(arg); + + assert.sameValue( + result, + "M05", + `unknown annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-with-utc-designator.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-with-utc-designator.js new file mode 100644 index 0000000000..0eef9fc638 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/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.calendar.prototype.monthcode +description: RangeError thrown if a string with UTC designator is used as a PlainDate +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "2019-10-01T09:00:00Z", + "2019-10-01T09:00:00Z[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.monthCode(arg), + "String with UTC designator should not be valid as a PlainDate" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-wrong-type.js new file mode 100644 index 0000000000..36deb691ed --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/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.calendar.prototype.monthcode +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +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.monthCode(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.monthCode(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/Calendar/prototype/monthCode/argument-zoneddatetime-convert.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-zoneddatetime-convert.js new file mode 100644 index 0000000000..ac5a85b492 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-zoneddatetime-convert.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.calendar.prototype.monthcode +description: An exception from TimeZone#getOffsetNanosecondsFor() is propagated. +features: [Temporal] +---*/ + +class TZ extends Temporal.TimeZone { + constructor() { super("UTC") } + getOffsetNanosecondsFor() { throw new Test262Error() } +} + +const tz = new TZ(); +const arg = new Temporal.ZonedDateTime(0n, tz); +const instance = new Temporal.Calendar("iso8601"); + +assert.throws(Test262Error, () => instance.monthCode(arg)); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-zoneddatetime-slots.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-zoneddatetime-slots.js new file mode 100644 index 0000000000..b4d379d4c5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-zoneddatetime-slots.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.calendar.prototype.monthcode +description: Getters are not called when converting a ZonedDateTime to a PlainDate. +includes: [compareArray.js] +features: [Temporal] +---*/ + +const actual = []; +const prototypeDescrs = Object.getOwnPropertyDescriptors(Temporal.ZonedDateTime.prototype); +const getters = ["year", "month", "monthCode", "day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond", "calendar"]; + +for (const property of getters) { + Object.defineProperty(Temporal.ZonedDateTime.prototype, property, { + get() { + actual.push(`get ${property}`); + const value = prototypeDescrs[property].get.call(this); + return { + toString() { + actual.push(`toString ${property}`); + return value.toString(); + }, + valueOf() { + actual.push(`valueOf ${property}`); + return value; + }, + }; + }, + }); +} + +const arg = new Temporal.ZonedDateTime(0n, "UTC"); +const instance = new Temporal.Calendar("iso8601"); +instance.monthCode(arg); +assert.compareArray(actual, []); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js new file mode 100644 index 0000000000..dd9c5f20d2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/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.calendar.prototype.monthcode +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(RangeError, () => calendar.monthCode(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js new file mode 100644 index 0000000000..5c8f7322e4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/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.calendar.prototype.monthcode +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + timeZone.getOffsetNanosecondsFor = notCallable; + assert.throws( + TypeError, + () => calendar.monthCode(datetime), + `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js new file mode 100644 index 0000000000..aa3ed0686c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/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.calendar.prototype.monthcode +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(RangeError, () => calendar.monthCode(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js new file mode 100644 index 0000000000..863a82875c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/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.calendar.prototype.monthcode +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(TypeError, () => calendar.monthCode(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/basic.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/basic.js new file mode 100644 index 0000000000..720f375fce --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/basic.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.calendar.prototype.monthcode +description: Basic tests for monthCode(). +features: [Temporal] +---*/ + +const iso = Temporal.Calendar.from("iso8601"); +const res = "M11"; +assert.sameValue(iso.monthCode(Temporal.PlainDate.from("1994-11-05")), res, "PlainDate"); +assert.sameValue(iso.monthCode(Temporal.PlainDateTime.from("1994-11-05T08:15:30")), res, "PlainDateTime"); +assert.sameValue(iso.monthCode(Temporal.PlainYearMonth.from("1994-11")), res, "PlainYearMonth"); +assert.sameValue(iso.monthCode(Temporal.PlainMonthDay.from("11-05")), res, "PlainMonthDay"); +assert.sameValue(iso.monthCode({ year: 1994, month: 11, day: 5 }), res, "property bag"); +assert.sameValue(iso.monthCode("1994-11-05"), res, "string"); +assert.throws(TypeError, () => iso.monthCode({ year: 2000 }), "property bag with missing properties"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/branding.js new file mode 100644 index 0000000000..c2b1822155 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/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.calendar.prototype.monthcode +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const monthCode = Temporal.Calendar.prototype.monthCode; + +assert.sameValue(typeof monthCode, "function"); + +const args = [new Temporal.PlainDate(2000, 1, 1)]; + +assert.throws(TypeError, () => monthCode.apply(undefined, args), "undefined"); +assert.throws(TypeError, () => monthCode.apply(null, args), "null"); +assert.throws(TypeError, () => monthCode.apply(true, args), "true"); +assert.throws(TypeError, () => monthCode.apply("", args), "empty string"); +assert.throws(TypeError, () => monthCode.apply(Symbol(), args), "symbol"); +assert.throws(TypeError, () => monthCode.apply(1, args), "1"); +assert.throws(TypeError, () => monthCode.apply({}, args), "plain object"); +assert.throws(TypeError, () => monthCode.apply(Temporal.Calendar, args), "Temporal.Calendar"); +assert.throws(TypeError, () => monthCode.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/builtin.js new file mode 100644 index 0000000000..17ff14fe99 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/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.calendar.prototype.monthcode +description: > + Tests that Temporal.Calendar.prototype.monthCode + 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.Calendar.prototype.monthCode), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.monthCode), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.monthCode), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.Calendar.prototype.monthCode.hasOwnProperty("prototype"), + false, "prototype property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/calendar-datefromfields-called-with-options-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/calendar-datefromfields-called-with-options-undefined.js new file mode 100644 index 0000000000..c4a0e003d0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/calendar-datefromfields-called-with-options-undefined.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.calendar.prototype.monthcode +description: > + Calendar.dateFromFields method is called with undefined as the options value + when call originates internally +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = TemporalHelpers.calendarFromFieldsUndefinedOptions(); +calendar.monthCode({ year: 2000, month: 5, day: 3, calendar }); +assert.sameValue(calendar.dateFromFieldsCallCount, 1); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/calendar-fields-iterable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/calendar-fields-iterable.js new file mode 100644 index 0000000000..e35c2dc02b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/calendar-fields-iterable.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.calendar.prototype.monthcode +description: Verify the result of calendar.fields() is treated correctly. +info: | + sec-temporal.calendar.prototype.monthcode step 4: + 4. Return ? ISOMonthCode(_dateOrDateTime_). + sec-temporal-isomonthcode step 1.a: + a. Set _dateOrDateTime_ to ? ToTemporalDate(_dateOrDateTime_). + sec-temporal-totemporaldate step 2.c: + c. Let _fieldNames_ be ? CalendarFields(_calendar_, « *"day"*, *"month"*, *"monthCode"*, *"year"* »). + sec-temporal-calendarfields step 4: + 4. Let _result_ be ? IterableToListOfType(_fieldsArray_, « String »). +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + "day", + "month", + "monthCode", + "year", +]; + +const calendar1 = TemporalHelpers.calendarFieldsIterable(); +const calendar2 = TemporalHelpers.calendarFieldsIterable(); +calendar1.monthCode({ year: 2000, month: 5, day: 2, calendar: calendar2 }); + +assert.sameValue(calendar1.fieldsCallCount, 0, "fields() method not called"); +assert.sameValue(calendar2.fieldsCallCount, 1, "fields() method called once"); +assert.compareArray(calendar2.fieldsCalledWith[0], expected, "fields() method called with correct args"); +assert(calendar2.iteratorExhausted[0], "iterated through the whole iterable"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/calendar-temporal-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/calendar-temporal-object.js new file mode 100644 index 0000000000..46d93110e9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/calendar-temporal-object.js @@ -0,0 +1,31 @@ +// |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.calendar.prototype.monthcode +description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots +info: | + sec-temporal.calendar.prototype.monthcode step 4: + 4. Return ? ISOMonthCode(_dateOrDateTime_). + sec-temporal-isomonthcode step 1.a: + a. Set _dateOrDateTime_ to ? ToTemporalDate(_dateOrDateTime_). + sec-temporal-totemporaldate 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 calendar = new Temporal.Calendar("iso8601"); + calendar.monthCode({ year: 2000, month: 5, day: 2, calendar: temporalObject }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/date-time.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/date-time.js new file mode 100644 index 0000000000..4ebe8409d4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/date-time.js @@ -0,0 +1,23 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.monthCode +description: > + Temporal.Calendar.prototype.month will take PlainDateTime and return + the value of the monthCode. +info: | + 6. Return ! ISOMonthCode(temporalDateLike). +features: [Temporal] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +let dateTime = new Temporal.PlainDateTime(1997, 8, 23, 5, 30, 13) +assert.sameValue( + cal.monthCode(dateTime), + "M08", + 'cal.monthCode(new Temporal.PlainDateTime(1997, 8, 23, 5, 30, 13)) must return "M08"' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/date.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/date.js new file mode 100644 index 0000000000..77c6135495 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/date.js @@ -0,0 +1,19 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.monthCode +description: > + Temporal.Calendar.prototype.monthCode will take PlainDate and return + the value of the monthCode. +info: | + 5. Return ! ISOMonthCode(temporalDateLike). +features: [Temporal] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +let date = new Temporal.PlainDate(2021, 7, 15); +assert.sameValue(cal.monthCode(date), "M07", 'cal.monthCode(new Temporal.PlainDate(2021, 7, 15)) must return "M07"'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/infinity-throws-rangeerror.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/infinity-throws-rangeerror.js new file mode 100644 index 0000000000..10ad2754ed --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/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.calendar.prototype.monthcode +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); +const base = { year: 2000, month: 5, day: 2 }; + +[Infinity, -Infinity].forEach((inf) => { + ["year", "month", "day"].forEach((prop) => { + assert.throws(RangeError, () => instance.monthCode({ ...base, [prop]: inf }), `${prop} property cannot be ${inf}`); + + const calls = []; + const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop); + assert.throws(RangeError, () => instance.monthCode({ ...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/Calendar/prototype/monthCode/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/length.js new file mode 100644 index 0000000000..d3604d8d8d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/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.calendar.prototype.monthcode +description: Temporal.Calendar.prototype.monthCode.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.Calendar.prototype.monthCode, "length", { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/month-day.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/month-day.js new file mode 100644 index 0000000000..4ec5588002 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/month-day.js @@ -0,0 +1,23 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.monthCode +description: > + Temporal.Calendar.prototype.monthCode will take PlainMonthDay and return + the value of the monthCode. +info: | + 6. Return ! ISOMonthCode(temporalDateLike). +features: [Temporal] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +let monthDay = new Temporal.PlainMonthDay(12, 25); +assert.sameValue( + cal.monthCode(monthDay), + "M12", + 'cal.monthCode(new Temporal.PlainMonthDay(12, 25)) must return "M12"' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/name.js new file mode 100644 index 0000000000..90bcd956d0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/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.calendar.prototype.monthcode +description: Temporal.Calendar.prototype.monthCode.name is "monthCode". +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.Calendar.prototype.monthCode, "name", { + value: "monthCode", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/not-a-constructor.js new file mode 100644 index 0000000000..726c6fff07 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/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.calendar.prototype.monthcode +description: > + Temporal.Calendar.prototype.monthCode 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.Calendar.prototype.monthCode(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.Calendar.prototype.monthCode), false, + "isConstructor(Temporal.Calendar.prototype.monthCode)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/prop-desc.js new file mode 100644 index 0000000000..b172e55645 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/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.calendar.prototype.monthcode +description: The "monthCode" property of Temporal.Calendar.prototype +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.Calendar.prototype.monthCode, + "function", + "`typeof Calendar.prototype.monthCode` is `function`" +); + +verifyProperty(Temporal.Calendar.prototype, "monthCode", { + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/shell.js new file mode 100644 index 0000000000..eda1477282 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/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/Calendar/prototype/monthCode/string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/string.js new file mode 100644 index 0000000000..3d7945be8a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/string.js @@ -0,0 +1,25 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.monthCode +description: > + Temporal.Calendar.prototype.monthCode will take ISO8601 string and return + the value of the monthCode. +info: | + 5. If Type(temporalDateLike) is not Object or temporalDateLike does not have + an [[InitializedTemporalDate]] or [[InitializedTemporalYearMonth]] internal + slot, then + a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike). + 6. Return ! ISOYear(temporalDateLike). +features: [Temporal] +---*/ +let cal = new Temporal.Calendar("iso8601"); +assert.sameValue( + cal.monthCode("2019-03-15"), + "M03", + 'cal.monthCode("2019-03-15") must return "M03"' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/throw-range-error-ToTemporalDate.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/throw-range-error-ToTemporalDate.js new file mode 100644 index 0000000000..8fc5af5eed --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/throw-range-error-ToTemporalDate.js @@ -0,0 +1,22 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.monthCode +description: > + Temporal.Calendar.prototype.monthCode throws RangeError on + ToTemporalDate when temporalDateLike is invalid string. +info: | + 4. If Type(temporalDateLike) is not Object or temporalDateLike + does not have an [[InitializedTemporalDate]] or + [[InitializedTemporalYearMonth]] internal slot, then + a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike). +features: [Temporal, arrow-function] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +assert.throws(RangeError, () => cal.monthCode("invalid string"), + 'cal.monthCode("invalid string") throws a RangeError exception'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/year-month.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/year-month.js new file mode 100644 index 0000000000..8c70484e06 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/year-month.js @@ -0,0 +1,23 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.monthCode +description: > + Temporal.Calendar.prototype.monthCode will take PlainYearMonth and return + the value of the monthCode. +info: | + 6. Return ! ISOMonthCode(temporalDateLike). +features: [Temporal] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +let yearMonth = new Temporal.PlainYearMonth(1999, 6); +assert.sameValue( + cal.monthCode(yearMonth), + "M06", + 'cal.monthCode(new Temporal.PlainYearMonth(1999, 6)) must return "M06"' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/year-zero.js new file mode 100644 index 0000000000..24a0423c9a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/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.calendar.prototype.monthcode +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.monthCode(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/basic.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/basic.js new file mode 100644 index 0000000000..dfbe948d82 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/basic.js @@ -0,0 +1,43 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.monthdayfromfields +description: Temporal.Calendar.prototype.monthDayFromFields will return correctly with valid data. +info: | + 1. Let calendar be the this value. + 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]). + 3. Assert: calendar.[[Identifier]] is "iso8601". + 4. If Type(fields) is not Object, throw a TypeError exception. + 5. Set options to ? GetOptionsObject(options). + 6. Let result be ? ISOMonthDayFromFields(fields, options). + 7. Return ? CreateTemporalMonthDay(result.[[Month]], result.[[Day]], calendar, result.[[ReferenceISOYear]]). +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const cal = new Temporal.Calendar("iso8601"); + +let result = cal.monthDayFromFields({ year: 2021, month: 7, day: 3 }); +TemporalHelpers.assertPlainMonthDay(result, "M07", 3, "month 7, day 3, with year"); +result = cal.monthDayFromFields({ year: 2021, month: 12, day: 31 }); +TemporalHelpers.assertPlainMonthDay(result, "M12", 31, "month 12, day 31, with year"); +result = cal.monthDayFromFields({ monthCode: "M07", day: 3 }); +TemporalHelpers.assertPlainMonthDay(result, "M07", 3, "monthCode M07, day 3"); +result = cal.monthDayFromFields({ monthCode: "M12", day: 31 }); +TemporalHelpers.assertPlainMonthDay(result, "M12", 31, "monthCode M12, day 31"); + +["constrain", "reject"].forEach(function (overflow) { + const opt = { overflow }; + result = cal.monthDayFromFields({ year: 2021, month: 7, day: 3 }, opt); + TemporalHelpers.assertPlainMonthDay(result, "M07", 3, "month 7, day 3, with year"); + result = cal.monthDayFromFields({ year: 2021, month: 12, day: 31 }, opt); + TemporalHelpers.assertPlainMonthDay(result, "M12", 31, "month 12, day 31, with year"); + result = cal.monthDayFromFields({ monthCode: "M07", day: 3 }, opt); + TemporalHelpers.assertPlainMonthDay(result, "M07", 3, "monthCode M07, day 3"); + result = cal.monthDayFromFields({ monthCode: "M12", day: 31 }, opt); + TemporalHelpers.assertPlainMonthDay(result, "M12", 31, "monthCode M12, day 31"); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/branding.js new file mode 100644 index 0000000000..6d589858ce --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/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.calendar.prototype.monthdayfromfields +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const monthDayFromFields = Temporal.Calendar.prototype.monthDayFromFields; + +assert.sameValue(typeof monthDayFromFields, "function"); + +const args = [{ monthCode: "M01", day: 1 }]; + +assert.throws(TypeError, () => monthDayFromFields.apply(undefined, args), "undefined"); +assert.throws(TypeError, () => monthDayFromFields.apply(null, args), "null"); +assert.throws(TypeError, () => monthDayFromFields.apply(true, args), "true"); +assert.throws(TypeError, () => monthDayFromFields.apply("", args), "empty string"); +assert.throws(TypeError, () => monthDayFromFields.apply(Symbol(), args), "symbol"); +assert.throws(TypeError, () => monthDayFromFields.apply(1, args), "1"); +assert.throws(TypeError, () => monthDayFromFields.apply({}, args), "plain object"); +assert.throws(TypeError, () => monthDayFromFields.apply(Temporal.Calendar, args), "Temporal.Calendar"); +assert.throws(TypeError, () => monthDayFromFields.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/builtin.js new file mode 100644 index 0000000000..62f83b7008 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/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.calendar.prototype.monthdayfromfields +description: > + Tests that Temporal.Calendar.prototype.monthDayFromFields + 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.Calendar.prototype.monthDayFromFields), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.monthDayFromFields), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.monthDayFromFields), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.Calendar.prototype.monthDayFromFields.hasOwnProperty("prototype"), + false, "prototype property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/fields-missing-properties.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/fields-missing-properties.js new file mode 100644 index 0000000000..da738aafec --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/fields-missing-properties.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.monthdayfromfields +description: Temporal.Calendar.prototype.monthDayFromFields will throw TypeError with incorrect input data type. +info: | + 1. Let calendar be the this value. + 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]). + 3. Assert: calendar.[[Identifier]] is "iso8601". + 4. If Type(fields) is not Object, throw a TypeError exception. + 5. Set options to ? GetOptionsObject(options). + 6. Let result be ? ISOMonthDayFromFields(fields, options). + 7. Return ? CreateTemporalMonthDay(result.[[Month]], result.[[Day]], calendar, result.[[ReferenceISOYear]]). +features: [Temporal] +---*/ + +let cal = new Temporal.Calendar("iso8601") + +assert.throws(TypeError, () => cal.monthDayFromFields({}), "at least one correctly spelled property is required"); +assert.throws(TypeError, () => cal.monthDayFromFields({ monthCode: "M12" }), "day is required with monthCode"); +assert.throws(TypeError, () => cal.monthDayFromFields({ year: 2021, month: 12 }), "day is required with year and month"); +assert.throws(TypeError, () => cal.monthDayFromFields({ month: 1, day: 17 }), "year is required if month is present"); +assert.throws(TypeError, () => cal.monthDayFromFields({ year: 2021, day: 17 }), "either month or monthCode is required"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/fields-not-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/fields-not-object.js new file mode 100644 index 0000000000..578f783e3a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/fields-not-object.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-temporal.calendar.prototype.monthdayfromfields +description: Throw a TypeError if the fields is not an object +features: [Symbol, Temporal] +---*/ + +const tests = [undefined, null, true, false, "string", Symbol("sym"), Math.PI, Infinity, NaN, 42n]; +const iso = Temporal.Calendar.from("iso8601"); +for (const fields of tests) { + assert.throws(TypeError, () => iso.monthDayFromFields(fields, {})); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/infinity-throws-rangeerror.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/infinity-throws-rangeerror.js new file mode 100644 index 0000000000..0f4b2b89de --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/infinity-throws-rangeerror.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. + +/*--- +description: Throws if any value in the property bag is Infinity or -Infinity +esid: sec-temporal.calendar.prototype.monthdayfromfields +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); +const base = { year: 2000, month: 5, day: 2 }; + +[Infinity, -Infinity].forEach((inf) => { + ["year", "month", "day"].forEach((prop) => { + ["constrain", "reject"].forEach((overflow) => { + assert.throws(RangeError, () => instance.monthDayFromFields({ ...base, [prop]: inf }, { overflow }), `${prop} property cannot be ${inf} (overflow ${overflow}`); + + const calls = []; + const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop); + assert.throws(RangeError, () => instance.monthDayFromFields({ ...base, [prop]: obj }, { overflow })); + 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/Calendar/prototype/monthDayFromFields/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/length.js new file mode 100644 index 0000000000..4c2bea0540 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/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.calendar.prototype.monthdayfromfields +description: Temporal.Calendar.prototype.monthDayFromFields.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.Calendar.prototype.monthDayFromFields, "length", { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/missing-properties.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/missing-properties.js new file mode 100644 index 0000000000..04eb5f563e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/missing-properties.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.calendar.prototype.monthdayfromfields +description: Errors due to missing properties on fields object are thrown in the correct order +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const missingDay = { + get year() { + TemporalHelpers.assertUnreachable("day should be checked first"); + }, + get month() { + TemporalHelpers.assertUnreachable("day should be checked first"); + }, + get monthCode() { + TemporalHelpers.assertUnreachable("day should be checked first"); + }, +}; +assert.throws(TypeError, () => instance.monthDayFromFields(missingDay), "day should be checked before year and month"); + +let getMonthCode = false; +let getYear = false; +const monthWithoutYear = { + day: 1, + month: 5, + get monthCode() { + getMonthCode = true; + }, + get year() { + getYear = true; + }, +}; +assert.throws(TypeError, () => instance.monthDayFromFields(monthWithoutYear), "year/month should be checked after fetching but before resolving the month code"); +assert(getMonthCode, "year/month is checked after fetching monthCode"); +assert(getYear, "year/month is fetched after fetching month"); + +assert.throws(TypeError, () => instance.monthDayFromFields({ day: 1 }), "month should be resolved last"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/monthcode-invalid.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/monthcode-invalid.js new file mode 100644 index 0000000000..0d299f33b3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/monthcode-invalid.js @@ -0,0 +1,34 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.monthdayfromfields +description: Throw RangeError for an out-of-range, conflicting, or ill-formed monthCode +info: | + 1. Let calendar be the this value. + 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]). + 3. Assert: calendar.[[Identifier]] is "iso8601". + 4. If Type(fields) is not Object, throw a TypeError exception. + 5. Set options to ? GetOptionsObject(options). + 6. Let result be ? ISOMonthDayFromFields(fields, options). + 7. Return ? CreateTemporalMonthDay(result.[[Month]], result.[[Day]], calendar, result.[[ReferenceISOYear]]). +features: [Temporal] +---*/ + +const cal = new Temporal.Calendar("iso8601"); + +["m1", "M1", "m01"].forEach((monthCode) => { + assert.throws(RangeError, () => cal.monthDayFromFields({ monthCode, day: 17 }), + `monthCode '${monthCode}' is not well-formed`); +}); + +assert.throws(RangeError, () => cal.monthDayFromFields({ year: 2021, month: 12, monthCode: "M11", day: 17 }), + "monthCode and month conflict"); + +["M00", "M19", "M99", "M13"].forEach((monthCode) => { + assert.throws(RangeError, () => cal.monthDayFromFields({ monthCode, day: 17 }), + `monthCode '${monthCode}' is not valid for ISO 8601 calendar`); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/name.js new file mode 100644 index 0000000000..cf8618040e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/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.calendar.prototype.monthdayfromfields +description: Temporal.Calendar.prototype.monthDayFromFields.name is "monthDayFromFields". +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.Calendar.prototype.monthDayFromFields, "name", { + value: "monthDayFromFields", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/not-a-constructor.js new file mode 100644 index 0000000000..db01622073 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/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.calendar.prototype.monthdayfromfields +description: > + Temporal.Calendar.prototype.monthDayFromFields 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.Calendar.prototype.monthDayFromFields(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.Calendar.prototype.monthDayFromFields), false, + "isConstructor(Temporal.Calendar.prototype.monthDayFromFields)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/one-of-era-erayear-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/one-of-era-erayear-undefined.js new file mode 100644 index 0000000000..8647afbe9c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/one-of-era-erayear-undefined.js @@ -0,0 +1,19 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.monthDayFromFields +description: Does not throw a RangeError if only one of era/eraYear fields is present +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const base = { year: 2000, month: 5, day: 2, era: 'ce' }; +const instance = new Temporal.Calendar('iso8601'); +TemporalHelpers.assertPlainMonthDay(instance.monthDayFromFields({ ...base }), 'M05', 2); + +const base2 = { year: 2000, month: 5, day: 2, eraYear: 1 }; +TemporalHelpers.assertPlainMonthDay(instance.monthDayFromFields({ ...base }), 'M05', 2); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/options-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/options-object.js new file mode 100644 index 0000000000..3f07708d89 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/options-object.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.calendar.prototype.monthdayfromfields +description: Empty or a function object may be used as options +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const result1 = instance.monthDayFromFields({ monthCode: "M12", day: 15 }, {}); +TemporalHelpers.assertPlainMonthDay( + result1, "M12", 15, + "options may be an empty plain object" +); + +const result2 = instance.monthDayFromFields({ monthCode: "M12", day: 15 }, () => {}); +TemporalHelpers.assertPlainMonthDay( + result2, "M12", 15, + "options may be a function object" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/options-wrong-type.js new file mode 100644 index 0000000000..59b8730d2d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/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.calendar.prototype.monthdayfromfields +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.Calendar("iso8601"); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.monthDayFromFields({ monthCode: "M12", day: 15 }, value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/order-of-operations.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/order-of-operations.js new file mode 100644 index 0000000000..dd882eeeae --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/order-of-operations.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.calendar.prototype.monthdayfromfields +description: Properties on objects passed to monthDayFromFields() are accessed in the correct order +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + "get fields.day", + "get fields.day.valueOf", + "call fields.day.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.year", + "get fields.year.valueOf", + "call fields.year.valueOf", + "get options.overflow", + "get options.overflow.toString", + "call options.overflow.toString", +]; +const actual = []; + +const instance = new Temporal.Calendar("iso8601"); + +const fields = TemporalHelpers.propertyBagObserver(actual, { + year: 1.7, + month: 1.7, + monthCode: "M01", + day: 1.7, +}, "fields"); + +const options = TemporalHelpers.propertyBagObserver(actual, { + overflow: "reject", +}, "options"); + +const result = instance.monthDayFromFields(fields, options); +TemporalHelpers.assertPlainMonthDay(result, "M01", 1, "monthDay result"); +assert.sameValue(result.calendar, instance, "calendar result"); +assert.compareArray(actual, expected, "order of operations"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-constrain.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-constrain.js new file mode 100644 index 0000000000..31d1142817 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-constrain.js @@ -0,0 +1,94 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.monthdayfromfields +description: Temporal.Calendar.prototype.monthDayFromFields will return correctly with data and overflow set to 'constrain'. +info: | + 1. Let calendar be the this value. + 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]). + 3. Assert: calendar.[[Identifier]] is "iso8601". + 4. If Type(fields) is not Object, throw a TypeError exception. + 5. Set options to ? GetOptionsObject(options). + 6. Let result be ? ISOMonthDayFromFields(fields, options). + 7. Return ? CreateTemporalMonthDay(result.[[Month]], result.[[Day]], calendar, result.[[ReferenceISOYear]]). +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const cal = new Temporal.Calendar("iso8601"); +const opt = { overflow: "constrain" }; + +let result = cal.monthDayFromFields({ year: 2021, month: 1, day: 133 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M01", 31, "day is constrained to 31 in month 1"); +result = cal.monthDayFromFields({ year: 2021, month: 2, day: 133 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M02", 28, "day is constrained to 28 in month 2 (year 2021)"); +result = cal.monthDayFromFields({ year: 2021, month: 3, day: 9033 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M03", 31, "day is constrained to 31 in month 3"); +result = cal.monthDayFromFields({ year: 2021, month: 4, day: 50 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M04", 30, "day is constrained to 30 in month 4"); +result = cal.monthDayFromFields({ year: 2021, month: 5, day: 77 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M05", 31, "day is constrained to 31 in month 5"); +result = cal.monthDayFromFields({ year: 2021, month: 6, day: 33 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M06", 30, "day is constrained to 30 in month 6"); +result = cal.monthDayFromFields({ year: 2021, month: 7, day: 33 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M07", 31, "day is constrained to 31 in month 7"); +result = cal.monthDayFromFields({ year: 2021, month: 8, day: 300 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M08", 31, "day is constrained to 31 in month 8"); +result = cal.monthDayFromFields({ year: 2021, month: 9, day: 400 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M09", 30, "day is constrained to 30 in month 9"); +result = cal.monthDayFromFields({ year: 2021, month: 10, day: 400 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M10", 31, "day is constrained to 31 in month 10"); +result = cal.monthDayFromFields({ year: 2021, month: 11, day: 400 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M11", 30, "day is constrained to 30 in month 11"); +result = cal.monthDayFromFields({ year: 2021, month: 12, day: 500 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M12", 31, "day is constrained to 31 in month 12"); + +assert.throws( + RangeError, + () => cal.monthDayFromFields({ year: 2021, month: -99999, day: 1 }, opt), + "negative month -99999 is out of range even with overflow constrain" +) +assert.throws( + RangeError, + () => cal.monthDayFromFields({ year: 2021, month: -1, day: 1 }, opt), + "negative month -1 is out of range even with overflow constrain" +) +assert.throws( + RangeError, + () => cal.monthDayFromFields({ year: 2021, month: 0, day: 1 }, opt), + "month zero is out of range even with overflow constrain" +) + +result = cal.monthDayFromFields({ year: 2021, month: 13, day: 1 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M12", 1, "month 13 is constrained to 12"); +result = cal.monthDayFromFields({ year: 2021, month: 999999, day: 500 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M12", 31, "month 999999 is constrained to 12 and day constrained to 31"); + +result = cal.monthDayFromFields({ monthCode: "M01", day: 133 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M01", 31, "day is constrained to 31 in monthCode M01"); +result = cal.monthDayFromFields({ monthCode: "M02", day: 133 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M02", 29, "day is constrained to 29 in monthCode M02"); +result = cal.monthDayFromFields({ monthCode: "M03", day: 9033 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M03", 31, "day is constrained to 31 in monthCode M03"); +result = cal.monthDayFromFields({ monthCode: "M04", day: 50 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M04", 30, "day is constrained to 30 in monthCode M04"); +result = cal.monthDayFromFields({ monthCode: "M05", day: 77 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M05", 31, "day is constrained to 31 in monthCode M05"); +result = cal.monthDayFromFields({ monthCode: "M06", day: 33 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M06", 30, "day is constrained to 30 in monthCode M06"); +result = cal.monthDayFromFields({ monthCode: "M07", day: 33 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M07", 31, "day is constrained to 31 in monthCode M07"); +result = cal.monthDayFromFields({ monthCode: "M08", day: 300 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M08", 31, "day is constrained to 31 in monthCode M08"); +result = cal.monthDayFromFields({ monthCode: "M09", day: 400 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M09", 30, "day is constrained to 30 in monthCode M09"); +result = cal.monthDayFromFields({ monthCode: "M10", day: 400 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M10", 31, "day is constrained to 31 in monthCode M10"); +result = cal.monthDayFromFields({ monthCode: "M11", day: 400 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M11", 30, "day is constrained to 30 in monthCode M11"); +result = cal.monthDayFromFields({ monthCode: "M12", day: 500 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M12", 31, "day is constrained to 31 in monthCode M12"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-invalid-string.js new file mode 100644 index 0000000000..27761ca46b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-invalid-string.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.calendar.prototype.monthdayfromfields +description: RangeError thrown when overflow 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-totemporaloverflow step 1: + 1. Return ? GetOption(_normalizedOptions_, *"overflow"*, « String », « *"constrain"*, *"reject"* », *"constrain"*). + sec-temporal-isomonthdayfromfields step 2: + 2. Let _overflow_ be ? ToTemporalOverflow(_options_). + sec-temporal.calendar.prototype.monthdayfromfields step 6: + 6. Let _result_ be ? ISOMonthDayFromFields(_fields_, _options_). +features: [Temporal] +---*/ + +const calendar = new Temporal.Calendar("iso8601"); +const badOverflows = ["", "CONSTRAIN", "balance", "other string", "constra\u0131n", "reject\0"]; +for (const overflow of badOverflows) { + assert.throws( + RangeError, + () => calendar.monthDayFromFields({ year: 2000, month: 5, day: 2 }, { overflow }), + `invalid overflow ("${overflow}")` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-reject.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-reject.js new file mode 100644 index 0000000000..bf7f13174b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-reject.js @@ -0,0 +1,67 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.monthdayfromfields +description: Throw RangeError for input data out of range with overflow reject +info: | + 1. Let calendar be the this value. + 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]). + 3. Assert: calendar.[[Identifier]] is "iso8601". + 4. If Type(fields) is not Object, throw a TypeError exception. + 5. Set options to ? GetOptionsObject(options). + 6. Let result be ? ISOMonthDayFromFields(fields, options). + 7. Return ? CreateTemporalMonthDay(result.[[Month]], result.[[Day]], calendar, result.[[ReferenceISOYear]]). +features: [Temporal] +---*/ + +const cal = new Temporal.Calendar("iso8601"); + +[-1, 0, 13, 9995].forEach((month) => { + assert.throws( + RangeError, + () => cal.monthDayFromFields({year: 2021, month, day: 5}, { overflow: "reject" }), + `Month ${month} is out of range for 2021 with overflow: reject` + ); +}); + +[-1, 0, 32, 999].forEach((day) => { + assert.throws( + RangeError, + () => cal.monthDayFromFields({ year: 2021, month: 12, day }, { overflow: "reject" }), + `Day ${day} is out of range for 2021-12 with overflow: reject` + ); + assert.throws( + RangeError, + () => cal.monthDayFromFields({ monthCode: "M12", day }, { overflow: "reject" }), + `Day ${day} is out of range for 2021-M12 with overflow: reject` + ); +}); + +assert.throws(RangeError, () => cal.monthDayFromFields( + { monthCode: "M01", day: 32 }, { overflow: "reject" }), "Day 32 is out of range for monthCode M01"); +assert.throws(RangeError, () => cal.monthDayFromFields( + { monthCode: "M02", day: 30 }, { overflow: "reject" }), "Day 30 is out of range for monthCode M02"); +assert.throws(RangeError, () => cal.monthDayFromFields( + { monthCode: "M03", day: 32 }, { overflow: "reject" }), "Day 32 is out of range for monthCode M03"); +assert.throws(RangeError, () => cal.monthDayFromFields( + { monthCode: "M04", day: 31 }, { overflow: "reject" }), "Day 31 is out of range for monthCode M04"); +assert.throws(RangeError, () => cal.monthDayFromFields( + { monthCode: "M05", day: 32 }, { overflow: "reject" }), "Day 32 is out of range for monthCode M05"); +assert.throws(RangeError, () => cal.monthDayFromFields( + { monthCode: "M06", day: 31 }, { overflow: "reject" }), "Day 31 is out of range for monthCode M06"); +assert.throws(RangeError, () => cal.monthDayFromFields( + { monthCode: "M07", day: 32 }, { overflow: "reject" }), "Day 32 is out of range for monthCode M07"); +assert.throws(RangeError, () => cal.monthDayFromFields( + { monthCode: "M08", day: 32 }, { overflow: "reject" }), "Day 32 is out of range for monthCode M08"); +assert.throws(RangeError, () => cal.monthDayFromFields( + { monthCode: "M09", day: 31 }, { overflow: "reject" }), "Day 31 is out of range for monthCode M09"); +assert.throws(RangeError, () => cal.monthDayFromFields( + { monthCode: "M10", day: 32 }, { overflow: "reject" }), "Day 32 is out of range for monthCode M10"); +assert.throws(RangeError, () => cal.monthDayFromFields( + { monthCode: "M11", day: 31 }, { overflow: "reject" }), "Day 31 is out of range for monthCode M11"); +assert.throws(RangeError, () => cal.monthDayFromFields( + { monthCode: "M12", day: 32 }, { overflow: "reject" }), "Day 32 is out of range for monthCode M12"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-undefined.js new file mode 100644 index 0000000000..d96e3dd205 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-undefined.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.calendar.prototype.monthdayfromfields +description: Fallback value for overflow option +info: | + sec-getoption step 3: + 3. If _value_ is *undefined*, return _fallback_. + sec-temporal-totemporaloverflow step 1: + 1. Return ? GetOption(_normalizedOptions_, *"overflow"*, « String », « *"constrain"*, *"reject"* », *"constrain"*). + sec-temporal-isomonthdayfromfields step 2: + 2. Let _overflow_ be ? ToTemporalOverflow(_options_). + sec-temporal.calendar.prototype.monthdayfromfields step 6: + 6. Let _result_ be ? ISOMonthDayFromFields(_fields_, _options_). +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = new Temporal.Calendar("iso8601"); + +const explicit = calendar.monthDayFromFields({ year: 2000, month: 15, day: 2 }, { overflow: undefined }); +TemporalHelpers.assertPlainMonthDay(explicit, "M12", 2, "default overflow is constrain"); +const implicit = calendar.monthDayFromFields({ year: 2000, month: 15, day: 2 }, {}); +TemporalHelpers.assertPlainMonthDay(implicit, "M12", 2, "default overflow is constrain"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-wrong-type.js new file mode 100644 index 0000000000..e0d5789c4e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-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.calendar.prototype.monthdayfromfields +description: Type conversions for overflow option +info: | + sec-getoption step 9.a: + a. Set _value_ to ? ToString(_value_). + sec-temporal-totemporaloverflow step 1: + 1. Return ? GetOption(_normalizedOptions_, *"overflow"*, « String », « *"constrain"*, *"reject"* », *"constrain"*). + sec-temporal-isomonthdayfromfields step 2: + 2. Let _overflow_ be ? ToTemporalOverflow(_options_). + sec-temporal.calendar.prototype.monthdayfromfields step 6: + 6. Let _result_ be ? ISOMonthDayFromFields(_fields_, _options_). +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = new Temporal.Calendar("iso8601"); +TemporalHelpers.checkStringOptionWrongType("overflow", "constrain", + (overflow) => calendar.monthDayFromFields({ year: 2000, month: 5, day: 2 }, { overflow }), + (result, descr) => TemporalHelpers.assertPlainMonthDay(result, "M05", 2, descr), +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/prop-desc.js new file mode 100644 index 0000000000..09e13e425d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/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.calendar.prototype.monthdayfromfields +description: The "monthDayFromFields" property of Temporal.Calendar.prototype +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.Calendar.prototype.monthDayFromFields, + "function", + "`typeof Calendar.prototype.monthDayFromFields` is `function`" +); + +verifyProperty(Temporal.Calendar.prototype, "monthDayFromFields", { + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/reference-year-1972.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/reference-year-1972.js new file mode 100644 index 0000000000..3b8dc3ac4d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/reference-year-1972.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.monthdayfromfields +description: Use a leap year as the reference year if monthCode is given +info: | + sec-temporal-isomonthdayfromfields: + 12. If _monthCode_ is *undefined*, then + a. Let _result_ be ? RegulateISODate(_year_, _month_, _day_, _overflow_). + 13. Else, + a. Let _result_ be ? RegulateISODate(_referenceISOYear_, _month_, _day_, _overflow_). +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const cal = new Temporal.Calendar("iso8601"); + +let result = cal.monthDayFromFields({ year: 2021, monthCode: "M02", day: 29 }); +TemporalHelpers.assertPlainMonthDay(result, "M02", 29, "year is ignored and reference year should be a leap year if monthCode is given"); + +result = cal.monthDayFromFields({ year: 2021, month: 2, day: 29 }, { overflow: "constrain" }); +TemporalHelpers.assertPlainMonthDay(result, "M02", 28, "year should not be ignored if monthCode is not given (overflow constrain)"); + +assert.throws( + RangeError, + () => cal.monthDayFromFields({ year: 2021, month: 2, day: 29 }, { overflow: "reject" }), + "year should not be ignored if monthCode is not given (overflow reject)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/shell.js new file mode 100644 index 0000000000..eda1477282 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/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/Calendar/prototype/monthsInYear/argument-calendar-datefromfields-called-with-null-prototype-fields.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-calendar-datefromfields-called-with-null-prototype-fields.js new file mode 100644 index 0000000000..b351ebb9c1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-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.calendar.prototype.monthsinyear +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.Calendar("iso8601"); +const arg = { year: 2000, month: 5, day: 2, calendar }; +instance.monthsInYear(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/Calendar/prototype/monthsInYear/argument-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-leap-second.js new file mode 100644 index 0000000000..209c126375 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-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.calendar.prototype.monthsinyear +description: Leap second is a valid ISO string for PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.monthsInYear(arg); +assert.sameValue( + result1, + 12, + "leap second is a valid ISO string for PlainDate" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.monthsInYear(arg); +assert.sameValue( + result2, + 12, + "second: 60 is ignored in property bag for PlainDate" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-number.js new file mode 100644 index 0000000000..c4876c9219 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/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.calendar.prototype.monthsinyear +description: A number is converted to a string, then to Temporal.PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const arg = 19761118; + +const result = instance.monthsInYear(arg); +assert.sameValue(result, 12, "19761118 is a valid ISO string for PlainDate"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.monthsInYear(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-case-insensitive.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-case-insensitive.js new file mode 100644 index 0000000000..a0f9febed8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/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.calendar.prototype.monthsinyear +description: The calendar name is case-insensitive +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "IsO8601"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.monthsInYear(arg); +assert.sameValue(result1, 12, "Calendar is case-insensitive"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.monthsInYear(arg); +assert.sameValue(result2, 12, "Calendar is case-insensitive (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js new file mode 100644 index 0000000000..a06f4cb6ed --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/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.calendar.prototype.monthsinyear +description: > + A Temporal.Calendar instance passed to monthsInYear() in a property bag does + not have its 'calendar' property observably checked +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +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.monthsInYear(arg); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +instance.monthsInYear(arg); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-leap-second.js new file mode 100644 index 0000000000..3f738aa0b9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/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.calendar.prototype.monthsinyear +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.monthsInYear(arg); +assert.sameValue( + result1, + 12, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.monthsInYear(arg); +assert.sameValue( + result2, + 12, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-number.js new file mode 100644 index 0000000000..ae18bd1fb4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/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.calendar.prototype.monthsinyear +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.monthsInYear(arg); +assert.sameValue(result1, 12, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.monthsInYear(arg); +assert.sameValue(result2, 12, "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.monthsInYear(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.monthsInYear(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/Calendar/prototype/monthsInYear/argument-propertybag-calendar-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-string.js new file mode 100644 index 0000000000..ea54a87cbb --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/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.calendar.prototype.monthsinyear +description: A calendar ID is valid input for Calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "iso8601"; + +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.monthsInYear(arg); +assert.sameValue(result, 12, `Calendar created from string "${calendar}"`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 0000000000..a5157d449e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/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.calendar.prototype.monthsinyear +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.Calendar("iso8601"); + +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.monthsInYear(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.monthsInYear(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.monthsInYear(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.monthsInYear(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.monthsInYear(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-year-zero.js new file mode 100644 index 0000000000..d87b04f889 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/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.calendar.prototype.monthsinyear +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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.monthsInYear(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-calendar-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-calendar-annotation.js new file mode 100644 index 0000000000..3909892fd6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/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.calendar.prototype.monthsinyear +description: Various forms of calendar annotation; critical flag has no effect +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02[u-ca=iso8601]", "without time or time zone"], + ["2000-05-02[UTC][u-ca=iso8601]", "with time zone and no time"], + ["2000-05-02T15:23[u-ca=iso8601]", "without time zone"], + ["2000-05-02T15:23[UTC][u-ca=iso8601]", "with time zone"], + ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], + ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], + ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], + ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.monthsInYear(arg); + + assert.sameValue( + result, + 12, + `calendar annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-critical-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-critical-unknown-annotation.js new file mode 100644 index 0000000000..e584b4c3fa --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-critical-unknown-annotation.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.calendar.prototype.monthsinyear +description: Unknown annotations with critical flag are rejected +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[!foo=bar]", + "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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.monthsInYear(arg), + `reject unknown annotation with critical flag: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-date-with-utc-offset.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-date-with-utc-offset.js new file mode 100644 index 0000000000..159c85970f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/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.calendar.prototype.monthsinyear +description: UTC offset not valid with format that does not include a time +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const validStrings = [ + "2000-05-02T00+00:00", + "2000-05-02T00+00:00[UTC]", + "2000-05-02T00+00:00[!UTC]", + "2000-05-02T00-02:30[America/St_Johns]", +]; + +for (const arg of validStrings) { + const result = instance.monthsInYear(arg); + + assert.sameValue( + result, + 12, + `"${arg}" is a valid UTC offset with time for PlainDate` + ); +} + +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.monthsInYear(arg), + `"${arg}" UTC offset without time is not valid for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-invalid.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-invalid.js new file mode 100644 index 0000000000..a4ab4dbccf --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-invalid.js @@ -0,0 +1,64 @@ +// |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.calendar.prototype.monthsinyear +description: > + RangeError thrown if an invalid ISO string (or syntactically valid ISO string + that is not supported) is used as a PlainDate +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + // invalid ISO strings: + "", + "invalid iso8601", + "2020-01-00", + "2020-01-32", + "2020-02-30", + "2021-02-29", + "2020-00-01", + "2020-13-01", + "2020-01-01T", + "2020-01-01T25:00:00", + "2020-01-01T01:60:00", + "2020-01-01T01:60:61", + "2020-01-01junk", + "2020-01-01T00:00:00junk", + "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-01", + "2020-001-01", + "2020-01-001", + "2020-01-01T001", + "2020-01-01T01:001", + "2020-01-01T01:01:001", + // valid, but forms not supported in Temporal: + "2020-W01-1", + "2020-001", + "+0002020-01-01", + // valid, but this calendar must not exist: + "2020-01-01[u-ca=notexist]", + // may be valid in other contexts, but insufficient information for PlainDate: + "2020-01", + "+002020-01", + "01-01", + "2020-W01", + "P1Y", + "-P12Y", + // valid, but outside the supported range: + "-999999-01-01", + "+999999-01-01", +]; +const instance = new Temporal.Calendar("iso8601"); +for (const arg of invalidStrings) { + assert.throws( + RangeError, + () => instance.monthsInYear(arg), + `"${arg}" should not be a valid ISO string for a PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-multiple-time-zone.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-multiple-time-zone.js new file mode 100644 index 0000000000..c0c69f0945 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-multiple-time-zone.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.calendar.prototype.monthsinyear +description: More than one time zone annotation is not syntactical +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[UTC][UTC]", + "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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.monthsInYear(arg), + `reject more than one time zone annotation: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-time-separators.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-time-separators.js new file mode 100644 index 0000000000..a83f9a3910 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/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.calendar.prototype.monthsinyear +description: Time separator in string argument can vary +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02T15:23", "uppercase T"], + ["2000-05-02t15:23", "lowercase T"], + ["2000-05-02 15:23", "space between date and time"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.monthsInYear(arg); + + assert.sameValue( + result, + 12, + `variant time separators (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-time-zone-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-time-zone-annotation.js new file mode 100644 index 0000000000..548ea26d04 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-time-zone-annotation.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.calendar.prototype.monthsinyear +description: Various forms of time zone annotation; critical flag has no effect +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02[Asia/Kolkata]", "named, with no time"], + ["2000-05-02[!Europe/Vienna]", "named, with ! and no time"], + ["2000-05-02[+00:00]", "numeric, with no time"], + ["2000-05-02[!-02:30]", "numeric, with ! and no time"], + ["2000-05-02T15:23[America/Sao_Paulo]", "named, with no offset"], + ["2000-05-02T15:23[!Asia/Tokyo]", "named, with ! and no offset"], + ["2000-05-02T15:23[-02:30]", "numeric, with no offset"], + ["2000-05-02T15:23[!+00:00]", "numeric, with ! and no offset"], + ["2000-05-02T15:23+00:00[America/New_York]", "named, with offset"], + ["2000-05-02T15:23+00:00[!UTC]", "named, with offset and !"], + ["2000-05-02T15:23+00:00[+01:00]", "numeric, with offset"], + ["2000-05-02T15:23+00:00[!-08:00]", "numeric, with offset and !"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.monthsInYear(arg); + + assert.sameValue( + result, + 12, + `time zone annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-unknown-annotation.js new file mode 100644 index 0000000000..c0d1f7a439 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/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.calendar.prototype.monthsinyear +description: Various forms of unknown annotation +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02[foo=bar]", "without time"], + ["2000-05-02T15:23[foo=bar]", "alone"], + ["2000-05-02T15:23[UTC][foo=bar]", "with time zone"], + ["2000-05-02T15:23[u-ca=iso8601][foo=bar]", "with calendar"], + ["2000-05-02T15:23[UTC][foo=bar][u-ca=iso8601]", "with time zone and calendar"], + ["2000-05-02T15:23[foo=bar][_foo-bar0=Ignore-This-999999999999]", "with another unknown annotation"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.monthsInYear(arg); + + assert.sameValue( + result, + 12, + `unknown annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-with-utc-designator.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-with-utc-designator.js new file mode 100644 index 0000000000..c6daca5431 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/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.calendar.prototype.monthsinyear +description: RangeError thrown if a string with UTC designator is used as a PlainDate +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "2019-10-01T09:00:00Z", + "2019-10-01T09:00:00Z[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.monthsInYear(arg), + "String with UTC designator should not be valid as a PlainDate" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string.js new file mode 100644 index 0000000000..a2bc15e1ea --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string.js @@ -0,0 +1,21 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.monthsinyear +description: An ISO 8601 date string should be converted as input +info: | + a. Perform ? ToTemporalDate(temporalDateLike). + 5. Return 12𝔽. +features: [Temporal] +---*/ + +let cal = new Temporal.Calendar("iso8601"); + +assert.sameValue(cal.monthsInYear("3456-12-20"), 12); +assert.sameValue(cal.monthsInYear("+000998-01-28"), 12); +assert.sameValue(cal.monthsInYear("3456-12-20T03:04:05+00:00[UTC]"), 12); +assert.sameValue(cal.monthsInYear("+000998-01-28T03:04:05+00:00[UTC]"), 12); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-wrong-type.js new file mode 100644 index 0000000000..b178789d30 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/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.calendar.prototype.monthsinyear +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +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.monthsInYear(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.monthsInYear(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/Calendar/prototype/monthsInYear/argument-zoneddatetime-convert.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-zoneddatetime-convert.js new file mode 100644 index 0000000000..6491a59eb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-zoneddatetime-convert.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.calendar.prototype.monthsinyear +description: An exception from TimeZone#getOffsetNanosecondsFor() is propagated. +features: [Temporal] +---*/ + +class TZ extends Temporal.TimeZone { + constructor() { super("UTC") } + getOffsetNanosecondsFor() { throw new Test262Error() } +} + +const tz = new TZ(); +const arg = new Temporal.ZonedDateTime(0n, tz); +const instance = new Temporal.Calendar("iso8601"); + +assert.throws(Test262Error, () => instance.monthsInYear(arg)); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-zoneddatetime-slots.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-zoneddatetime-slots.js new file mode 100644 index 0000000000..d16af05c48 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-zoneddatetime-slots.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.calendar.prototype.monthsinyear +description: Getters are not called when converting a ZonedDateTime to a PlainDate. +includes: [compareArray.js] +features: [Temporal] +---*/ + +const actual = []; +const prototypeDescrs = Object.getOwnPropertyDescriptors(Temporal.ZonedDateTime.prototype); +const getters = ["year", "month", "monthCode", "day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond", "calendar"]; + +for (const property of getters) { + Object.defineProperty(Temporal.ZonedDateTime.prototype, property, { + get() { + actual.push(`get ${property}`); + const value = prototypeDescrs[property].get.call(this); + return { + toString() { + actual.push(`toString ${property}`); + return value.toString(); + }, + valueOf() { + actual.push(`valueOf ${property}`); + return value; + }, + }; + }, + }); +} + +const arg = new Temporal.ZonedDateTime(0n, "UTC"); +const instance = new Temporal.Calendar("iso8601"); +instance.monthsInYear(arg); +assert.compareArray(actual, []); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js new file mode 100644 index 0000000000..1089a769ff --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/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.calendar.prototype.monthsinyear +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(RangeError, () => calendar.monthsInYear(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js new file mode 100644 index 0000000000..331787633c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/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.calendar.prototype.monthsinyear +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + timeZone.getOffsetNanosecondsFor = notCallable; + assert.throws( + TypeError, + () => calendar.monthsInYear(datetime), + `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js new file mode 100644 index 0000000000..af60bb38a9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/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.calendar.prototype.monthsinyear +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(RangeError, () => calendar.monthsInYear(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js new file mode 100644 index 0000000000..8f97a60854 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/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.calendar.prototype.monthsinyear +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(TypeError, () => calendar.monthsInYear(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/basic.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/basic.js new file mode 100644 index 0000000000..f651a88f4e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/basic.js @@ -0,0 +1,20 @@ +// |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.calendar.prototype.monthsinyear +description: Basic tests for monthsInYear(). +features: [Temporal] +---*/ + +const iso = Temporal.Calendar.from("iso8601"); +const res = 12; +assert.sameValue(iso.monthsInYear(new Temporal.PlainDate(1994, 11, 5)), res, "PlainDate"); +assert.sameValue(iso.monthsInYear(new Temporal.PlainDateTime(1994, 11, 5, 8, 15, 30)), res, "PlainDateTime"); +assert.sameValue(iso.monthsInYear(new Temporal.PlainYearMonth(1994, 11)), res, "PlainYearMonth"); +assert.sameValue(iso.monthsInYear({ year: 1994, month: 11, day: 5 }), res, "property bag"); +assert.sameValue(iso.monthsInYear("1994-11-05"), res, "string"); +assert.throws(TypeError, () => iso.monthsInYear({ year: 2000 }), "property bag with missing properties"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/branding.js new file mode 100644 index 0000000000..15d9f9c148 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/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.calendar.prototype.monthsinyear +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const monthsInYear = Temporal.Calendar.prototype.monthsInYear; + +assert.sameValue(typeof monthsInYear, "function"); + +const args = [new Temporal.PlainDate(2021, 3, 4)]; + +assert.throws(TypeError, () => monthsInYear.apply(undefined, args), "undefined"); +assert.throws(TypeError, () => monthsInYear.apply(null, args), "null"); +assert.throws(TypeError, () => monthsInYear.apply(true, args), "true"); +assert.throws(TypeError, () => monthsInYear.apply("", args), "empty string"); +assert.throws(TypeError, () => monthsInYear.apply(Symbol(), args), "symbol"); +assert.throws(TypeError, () => monthsInYear.apply(1, args), "1"); +assert.throws(TypeError, () => monthsInYear.apply({}, args), "plain object"); +assert.throws(TypeError, () => monthsInYear.apply(Temporal.Calendar, args), "Temporal.Calendar"); +assert.throws(TypeError, () => monthsInYear.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/builtin.js new file mode 100644 index 0000000000..ea88fbde66 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/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.calendar.prototype.monthsinyear +description: > + Tests that Temporal.Calendar.prototype.monthsInYear + 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.Calendar.prototype.monthsInYear), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.monthsInYear), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.monthsInYear), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.Calendar.prototype.monthsInYear.hasOwnProperty("prototype"), + false, "prototype property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/calendar-datefromfields-called-with-options-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/calendar-datefromfields-called-with-options-undefined.js new file mode 100644 index 0000000000..72dc32cd3f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/calendar-datefromfields-called-with-options-undefined.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.calendar.prototype.monthsinyear +description: > + Calendar.dateFromFields method is called with undefined as the options value + when call originates internally +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = TemporalHelpers.calendarFromFieldsUndefinedOptions(); +calendar.monthsInYear({ year: 2000, month: 5, day: 3, calendar }); +assert.sameValue(calendar.dateFromFieldsCallCount, 1); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/calendar-fields-iterable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/calendar-fields-iterable.js new file mode 100644 index 0000000000..4e7fb97e73 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/calendar-fields-iterable.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.calendar.prototype.monthsinyear +description: Verify the result of calendar.fields() is treated correctly. +info: | + sec-temporal.calendar.prototype.monthsinyear step 4: + 4. Perform ? ToTemporalDate(_dateOrDateTime_). + sec-temporal-totemporaldate step 2.c: + c. Let _fieldNames_ be ? CalendarFields(_calendar_, « *"day"*, *"month"*, *"monthCode"*, *"year"* »). + sec-temporal-calendarfields step 4: + 4. Let _result_ be ? IterableToListOfType(_fieldsArray_, « String »). +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + "day", + "month", + "monthCode", + "year", +]; + +const calendar1 = TemporalHelpers.calendarFieldsIterable(); +const calendar2 = TemporalHelpers.calendarFieldsIterable(); +calendar1.monthsInYear({ year: 2000, month: 5, day: 2, calendar: calendar2 }); + +assert.sameValue(calendar1.fieldsCallCount, 0, "fields() method not called"); +assert.sameValue(calendar2.fieldsCallCount, 1, "fields() method called once"); +assert.compareArray(calendar2.fieldsCalledWith[0], expected, "fields() method called with correct args"); +assert(calendar2.iteratorExhausted[0], "iterated through the whole iterable"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/calendar-temporal-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/calendar-temporal-object.js new file mode 100644 index 0000000000..9fe1a5c778 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/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.calendar.prototype.monthsinyear +description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots +info: | + sec-temporal.calendar.prototype.monthsinyear step 4: + 4. Perform ? ToTemporalDate(_dateOrDateTime_). + sec-temporal-totemporaldate 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 calendar = new Temporal.Calendar("iso8601"); + calendar.monthsInYear({ year: 2000, month: 5, day: 2, calendar: temporalObject }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/infinity-throws-rangeerror.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/infinity-throws-rangeerror.js new file mode 100644 index 0000000000..2e3797081b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/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.calendar.prototype.monthsinyear +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); +const base = { year: 2000, month: 5, day: 2 }; + +[Infinity, -Infinity].forEach((inf) => { + ["year", "month", "day"].forEach((prop) => { + assert.throws(RangeError, () => instance.monthsInYear({ ...base, [prop]: inf }), `${prop} property cannot be ${inf}`); + + const calls = []; + const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop); + assert.throws(RangeError, () => instance.monthsInYear({ ...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/Calendar/prototype/monthsInYear/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/length.js new file mode 100644 index 0000000000..411d74035f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/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.calendar.prototype.monthsinyear +description: Temporal.Calendar.prototype.monthsInYear.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.Calendar.prototype.monthsInYear, "length", { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/name.js new file mode 100644 index 0000000000..7857d6cdac --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/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.calendar.prototype.monthsinyear +description: Temporal.Calendar.prototype.monthsInYear.name is "monthsInYear". +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.Calendar.prototype.monthsInYear, "name", { + value: "monthsInYear", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/not-a-constructor.js new file mode 100644 index 0000000000..03a4b10911 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/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.calendar.prototype.monthsinyear +description: > + Temporal.Calendar.prototype.monthsInYear 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.Calendar.prototype.monthsInYear(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.Calendar.prototype.monthsInYear), false, + "isConstructor(Temporal.Calendar.prototype.monthsInYear)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/prop-desc.js new file mode 100644 index 0000000000..f11b201347 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/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.calendar.prototype.monthsinyear +description: The "monthsInYear" property of Temporal.Calendar.prototype +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.Calendar.prototype.monthsInYear, + "function", + "`typeof Calendar.prototype.monthsInYear` is `function`" +); + +verifyProperty(Temporal.Calendar.prototype, "monthsInYear", { + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/shell.js new file mode 100644 index 0000000000..eda1477282 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/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/Calendar/prototype/monthsInYear/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/year-zero.js new file mode 100644 index 0000000000..9c6e1e7196 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/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.calendar.prototype.monthsinyear +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.monthsInYear(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/prop-desc.js new file mode 100644 index 0000000000..cde159f79b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/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-calendar-prototype +description: The "prototype" property of Temporal.Calendar +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue(typeof Temporal.Calendar.prototype, "object"); +assert.notSameValue(Temporal.Calendar.prototype, null); + +verifyProperty(Temporal.Calendar, "prototype", { + writable: false, + enumerable: false, + configurable: false, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/shell.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/shell.js diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/branding.js new file mode 100644 index 0000000000..c5522bb91a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/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.calendar.prototype.tojson +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const toJSON = Temporal.Calendar.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.Calendar), "Temporal.Calendar"); +assert.throws(TypeError, () => toJSON.call(Temporal.Calendar.prototype), "Temporal.Calendar.prototype"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/builtin.js new file mode 100644 index 0000000000..19d4c36ad9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/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.calendar.prototype.tojson +description: > + Tests that Temporal.Calendar.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.Calendar.prototype.toJSON), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.toJSON), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.toJSON), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.Calendar.prototype.toJSON.hasOwnProperty("prototype"), + false, "prototype property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/length.js new file mode 100644 index 0000000000..87d2890b98 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/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.calendar.prototype.tojson +description: Temporal.Calendar.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.Calendar.prototype.toJSON, "length", { + value: 0, + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/name.js new file mode 100644 index 0000000000..1b10275bef --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/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.calendar.prototype.tojson +description: Temporal.Calendar.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.Calendar.prototype.toJSON, "name", { + value: "toJSON", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/not-a-constructor.js new file mode 100644 index 0000000000..47e4fef393 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/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.calendar.prototype.tojson +description: > + Temporal.Calendar.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.Calendar.prototype.toJSON(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.Calendar.prototype.toJSON), false, + "isConstructor(Temporal.Calendar.prototype.toJSON)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/prop-desc.js new file mode 100644 index 0000000000..39622ea147 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/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.calendar.prototype.tojson +description: The "toJSON" property of Temporal.Calendar.prototype +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.Calendar.prototype.toJSON, + "function", + "`typeof Calendar.prototype.toJSON` is `function`" +); + +verifyProperty(Temporal.Calendar.prototype, "toJSON", { + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/shell.js new file mode 100644 index 0000000000..eda1477282 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/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/Calendar/prototype/toString/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/branding.js new file mode 100644 index 0000000000..a1e6c00e48 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/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.calendar.prototype.tostring +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const toString = Temporal.Calendar.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.Calendar), "Temporal.Calendar"); +assert.throws(TypeError, () => toString.call(Temporal.Calendar.prototype), "Temporal.Calendar.prototype"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/builtin.js new file mode 100644 index 0000000000..09e3e93920 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/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.calendar.prototype.tostring +description: > + Tests that Temporal.Calendar.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.Calendar.prototype.toString), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.toString), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.toString), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.Calendar.prototype.toString.hasOwnProperty("prototype"), + false, "prototype property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/length.js new file mode 100644 index 0000000000..a20bb48c4a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/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.calendar.prototype.tostring +description: Temporal.Calendar.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.Calendar.prototype.toString, "length", { + value: 0, + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/name.js new file mode 100644 index 0000000000..1321b9dc6b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/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.calendar.prototype.tostring +description: Temporal.Calendar.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.Calendar.prototype.toString, "name", { + value: "toString", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/not-a-constructor.js new file mode 100644 index 0000000000..78eb201cd3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/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.calendar.prototype.tostring +description: > + Temporal.Calendar.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.Calendar.prototype.toString(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.Calendar.prototype.toString), false, + "isConstructor(Temporal.Calendar.prototype.toString)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/prop-desc.js new file mode 100644 index 0000000000..1b22dcb683 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/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.calendar.prototype.tostring +description: The "toString" property of Temporal.Calendar.prototype +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.Calendar.prototype.toString, + "function", + "`typeof Calendar.prototype.toString` is `function`" +); + +verifyProperty(Temporal.Calendar.prototype, "toString", { + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/shell.js new file mode 100644 index 0000000000..eda1477282 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/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/Calendar/prototype/toStringTag/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toStringTag/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toStringTag/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toStringTag/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toStringTag/prop-desc.js new file mode 100644 index 0000000000..78cb8eb403 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/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.calendar.prototype-@@tostringtag +description: The @@toStringTag property of Temporal.Calendar +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +verifyProperty(Temporal.Calendar.prototype, Symbol.toStringTag, { + value: "Temporal.Calendar", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toStringTag/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toStringTag/shell.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toStringTag/shell.js diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-calendar-datefromfields-called-with-null-prototype-fields.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-calendar-datefromfields-called-with-null-prototype-fields.js new file mode 100644 index 0000000000..da0e4abd15 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-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.calendar.prototype.weekofyear +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.Calendar("iso8601"); +const arg = { year: 2000, month: 5, day: 2, calendar }; +instance.weekOfYear(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/Calendar/prototype/weekOfYear/argument-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-leap-second.js new file mode 100644 index 0000000000..b740a5f4f0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-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.calendar.prototype.weekofyear +description: Leap second is a valid ISO string for PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.weekOfYear(arg); +assert.sameValue( + result1, + 52, + "leap second is a valid ISO string for PlainDate" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.weekOfYear(arg); +assert.sameValue( + result2, + 52, + "second: 60 is ignored in property bag for PlainDate" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-number.js new file mode 100644 index 0000000000..b9ebf188a7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/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.calendar.prototype.weekofyear +description: A number is converted to a string, then to Temporal.PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const arg = 19761118; + +const result = instance.weekOfYear(arg); +assert.sameValue(result, 47, "19761118 is a valid ISO string for PlainDate"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.weekOfYear(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-plaindate.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-plaindate.js new file mode 100644 index 0000000000..0a31552e4b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-plaindate.js @@ -0,0 +1,79 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.weekofyear +description: > + Temporal.Calendar.prototype.weekOfYear will take Temporal.PlainDate object + and return the week of year of that date. +info: | + 4. Let temporalDate be ? ToTemporalDate(temporalDateLike). + 5. Return 𝔽(! ToISOWeekOfYear(temporalDate.[[ISOYear]], temporalDate.[[ISOMonth]], temporalDate.[[ISODay]])). +features: [Temporal] +---*/ + +const cal = new Temporal.Calendar("iso8601"); + +// The following week numbers are taken from the table "Examples of contemporary +// dates around New Year's Day" from +// https://en.wikipedia.org/wiki/ISO_week_date#Relation_with_the_Gregorian_calendar + +let d = new Temporal.PlainDate(1977, 1, 1); +assert.sameValue(cal.weekOfYear(d), 53, "1977-01-01 is in w53"); + +d = new Temporal.PlainDate(1977, 1, 2); +assert.sameValue(cal.weekOfYear(d), 53, "1977-01-02 is in w53"); + +d = new Temporal.PlainDate(1977, 12, 31); +assert.sameValue(cal.weekOfYear(d), 52, "1977-12-31 is in w52"); + +d = new Temporal.PlainDate(1978, 1, 1); +assert.sameValue(cal.weekOfYear(d), 52, "1978-01-01 is in w52"); + +d = new Temporal.PlainDate(1978, 1, 2); +assert.sameValue(cal.weekOfYear(d), 1, "1978-01-02 is in w01"); + +d = new Temporal.PlainDate(1978, 12, 31); +assert.sameValue(cal.weekOfYear(d), 52, "1978-12-31 is in w52"); + +d = new Temporal.PlainDate(1979, 1, 1); +assert.sameValue(cal.weekOfYear(d), 1, "1979-01-01 is in w01"); + +d = new Temporal.PlainDate(1979, 12, 30); +assert.sameValue(cal.weekOfYear(d), 52, "1979-12-30 is in w52"); + +d = new Temporal.PlainDate(1979, 12, 31); +assert.sameValue(cal.weekOfYear(d), 1, "1979-12-31 is in w01"); + +d = new Temporal.PlainDate(1980, 1, 1); +assert.sameValue(cal.weekOfYear(d), 1, "1980-01-01 is in w01"); + +d = new Temporal.PlainDate(1980, 12, 28); +assert.sameValue(cal.weekOfYear(d), 52, "1980-12-28 is in w52"); + +d = new Temporal.PlainDate(1980, 12, 29); +assert.sameValue(cal.weekOfYear(d), 1, "1980-12-29 is in w01"); + +d = new Temporal.PlainDate(1980, 12, 30); +assert.sameValue(cal.weekOfYear(d), 1, "1980-12-30 is in w01"); + +d = new Temporal.PlainDate(1980, 12, 31); +assert.sameValue(cal.weekOfYear(d), 1, "1980-12-31 is in w01"); + +d = new Temporal.PlainDate(1981, 1, 1); +assert.sameValue(cal.weekOfYear(d), 1, "1981-01-01 is in w01"); + +d = new Temporal.PlainDate(1981, 12, 31); +assert.sameValue(cal.weekOfYear(d), 53, "1981-12-31 is in w53"); + +d = new Temporal.PlainDate(1982, 1, 1); +assert.sameValue(cal.weekOfYear(d), 53, "1982-01-01 is in w53"); + +d = new Temporal.PlainDate(1982, 1, 2); +assert.sameValue(cal.weekOfYear(d), 53, "1982-01-02 is in w53"); + +d = new Temporal.PlainDate(1982, 1, 3); +assert.sameValue(cal.weekOfYear(d), 53, "1982-01-03 is in w53"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-plaindatetime.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-plaindatetime.js new file mode 100644 index 0000000000..34a58428d6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-plaindatetime.js @@ -0,0 +1,79 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.weekofyear +description: > + Temporal.Calendar.prototype.weekOfYear will take Temporal.PlainDateTime object + and return the week of year of that date. +info: | + 4. Let temporalDate be ? ToTemporalDate(temporalDateLike). + 5. Return 𝔽(! ToISOWeekOfYear(temporalDate.[[ISOYear]], temporalDate.[[ISOMonth]], temporalDate.[[ISODay]])). +features: [Temporal] +---*/ + +const cal = new Temporal.Calendar("iso8601"); + +// The following week numbers are taken from the table "Examples of contemporary +// dates around New Year's Day" from +// https://en.wikipedia.org/wiki/ISO_week_date#Relation_with_the_Gregorian_calendar + +let dt = new Temporal.PlainDateTime(1977, 1, 1, 9, 8); +assert.sameValue(cal.weekOfYear(dt), 53, "1977-01-01 is in w53"); + +dt = new Temporal.PlainDateTime(1977, 1, 2, 9, 8); +assert.sameValue(cal.weekOfYear(dt), 53, "1977-01-02 is in w53"); + +dt = new Temporal.PlainDateTime(1977, 12, 31, 9, 8); +assert.sameValue(cal.weekOfYear(dt), 52, "1977-12-31 is in w52"); + +dt = new Temporal.PlainDateTime(1978, 1, 1, 9, 8); +assert.sameValue(cal.weekOfYear(dt), 52, "1978-01-01 is in w52"); + +dt = new Temporal.PlainDateTime(1978, 1, 2, 9, 8); +assert.sameValue(cal.weekOfYear(dt), 1, "1978-01-02 is in w01"); + +dt = new Temporal.PlainDateTime(1978, 12, 31, 9, 8); +assert.sameValue(cal.weekOfYear(dt), 52, "1978-12-31 is in w52"); + +dt = new Temporal.PlainDateTime(1979, 1, 1, 9, 8); +assert.sameValue(cal.weekOfYear(dt), 1, "1979-01-01 is in w01"); + +dt = new Temporal.PlainDateTime(1979, 12, 30, 9, 8); +assert.sameValue(cal.weekOfYear(dt), 52, "1979-12-30 is in w52"); + +dt = new Temporal.PlainDateTime(1979, 12, 31, 9, 8); +assert.sameValue(cal.weekOfYear(dt), 1, "1979-12-31 is in w01"); + +dt = new Temporal.PlainDateTime(1980, 1, 1, 9, 8); +assert.sameValue(cal.weekOfYear(dt), 1, "1980-01-01 is in w01"); + +dt = new Temporal.PlainDateTime(1980, 12, 28, 9, 8); +assert.sameValue(cal.weekOfYear(dt), 52, "1980-12-28 is in w52"); + +dt = new Temporal.PlainDateTime(1980, 12, 29, 9, 8); +assert.sameValue(cal.weekOfYear(dt), 1, "1980-12-29 is in w01"); + +dt = new Temporal.PlainDateTime(1980, 12, 30, 9, 8); +assert.sameValue(cal.weekOfYear(dt), 1, "1980-12-30 is in w01"); + +dt = new Temporal.PlainDateTime(1980, 12, 31, 9, 8); +assert.sameValue(cal.weekOfYear(dt), 1, "1980-12-31 is in w01"); + +dt = new Temporal.PlainDateTime(1981, 1, 1, 9, 8); +assert.sameValue(cal.weekOfYear(dt), 1, "1981-01-01 is in w01"); + +dt = new Temporal.PlainDateTime(1981, 12, 31, 9, 8); +assert.sameValue(cal.weekOfYear(dt), 53, "1981-12-31 is in w53"); + +dt = new Temporal.PlainDateTime(1982, 1, 1, 9, 8); +assert.sameValue(cal.weekOfYear(dt), 53, "1982-01-01 is in w53"); + +dt = new Temporal.PlainDateTime(1982, 1, 2, 9, 8); +assert.sameValue(cal.weekOfYear(dt), 53, "1982-01-02 is in w53"); + +dt = new Temporal.PlainDateTime(1982, 1, 3, 9, 8); +assert.sameValue(cal.weekOfYear(dt), 53, "1982-01-03 is in w53"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-case-insensitive.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-case-insensitive.js new file mode 100644 index 0000000000..eb32b40458 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/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.calendar.prototype.weekofyear +description: The calendar name is case-insensitive +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "IsO8601"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.weekOfYear(arg); +assert.sameValue(result1, 47, "Calendar is case-insensitive"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.weekOfYear(arg); +assert.sameValue(result2, 47, "Calendar is case-insensitive (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js new file mode 100644 index 0000000000..ca3fc7f4a8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/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.calendar.prototype.weekofyear +description: > + A Temporal.Calendar instance passed to weekOfYear() in a property bag does + not have its 'calendar' property observably checked +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +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.weekOfYear(arg); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +instance.weekOfYear(arg); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-leap-second.js new file mode 100644 index 0000000000..4b3792f346 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/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.calendar.prototype.weekofyear +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.weekOfYear(arg); +assert.sameValue( + result1, + 47, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.weekOfYear(arg); +assert.sameValue( + result2, + 47, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-number.js new file mode 100644 index 0000000000..c5c9117e86 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/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.calendar.prototype.weekofyear +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.weekOfYear(arg); +assert.sameValue(result1, 47, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.weekOfYear(arg); +assert.sameValue(result2, 47, "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.weekOfYear(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.weekOfYear(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/Calendar/prototype/weekOfYear/argument-propertybag-calendar-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-string.js new file mode 100644 index 0000000000..514b251f03 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/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.calendar.prototype.weekofyear +description: A calendar ID is valid input for Calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "iso8601"; + +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.weekOfYear(arg); +assert.sameValue(result, 47, `Calendar created from string "${calendar}"`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 0000000000..90ac76d277 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/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.calendar.prototype.weekofyear +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.Calendar("iso8601"); + +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.weekOfYear(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.weekOfYear(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.weekOfYear(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.weekOfYear(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.weekOfYear(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-year-zero.js new file mode 100644 index 0000000000..321b2a24fb --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/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.calendar.prototype.weekofyear +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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.weekOfYear(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-calendar-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-calendar-annotation.js new file mode 100644 index 0000000000..3048a29bbd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/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.calendar.prototype.weekofyear +description: Various forms of calendar annotation; critical flag has no effect +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02[u-ca=iso8601]", "without time or time zone"], + ["2000-05-02[UTC][u-ca=iso8601]", "with time zone and no time"], + ["2000-05-02T15:23[u-ca=iso8601]", "without time zone"], + ["2000-05-02T15:23[UTC][u-ca=iso8601]", "with time zone"], + ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], + ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], + ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], + ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.weekOfYear(arg); + + assert.sameValue( + result, + 18, + `calendar annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-critical-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-critical-unknown-annotation.js new file mode 100644 index 0000000000..5dbc9ef73d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-critical-unknown-annotation.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.calendar.prototype.weekofyear +description: Unknown annotations with critical flag are rejected +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[!foo=bar]", + "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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.weekOfYear(arg), + `reject unknown annotation with critical flag: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-date-with-utc-offset.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-date-with-utc-offset.js new file mode 100644 index 0000000000..b0bd62cb57 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/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.calendar.prototype.weekofyear +description: UTC offset not valid with format that does not include a time +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const validStrings = [ + "2000-05-02T00+00:00", + "2000-05-02T00+00:00[UTC]", + "2000-05-02T00+00:00[!UTC]", + "2000-05-02T00-02:30[America/St_Johns]", +]; + +for (const arg of validStrings) { + const result = instance.weekOfYear(arg); + + assert.sameValue( + result, + 18, + `"${arg}" is a valid UTC offset with time for PlainDate` + ); +} + +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.weekOfYear(arg), + `"${arg}" UTC offset without time is not valid for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-invalid.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-invalid.js new file mode 100644 index 0000000000..b5a920f80c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-invalid.js @@ -0,0 +1,64 @@ +// |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.calendar.prototype.weekofyear +description: > + RangeError thrown if an invalid ISO string (or syntactically valid ISO string + that is not supported) is used as a PlainDate +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + // invalid ISO strings: + "", + "invalid iso8601", + "2020-01-00", + "2020-01-32", + "2020-02-30", + "2021-02-29", + "2020-00-01", + "2020-13-01", + "2020-01-01T", + "2020-01-01T25:00:00", + "2020-01-01T01:60:00", + "2020-01-01T01:60:61", + "2020-01-01junk", + "2020-01-01T00:00:00junk", + "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-01", + "2020-001-01", + "2020-01-001", + "2020-01-01T001", + "2020-01-01T01:001", + "2020-01-01T01:01:001", + // valid, but forms not supported in Temporal: + "2020-W01-1", + "2020-001", + "+0002020-01-01", + // valid, but this calendar must not exist: + "2020-01-01[u-ca=notexist]", + // may be valid in other contexts, but insufficient information for PlainDate: + "2020-01", + "+002020-01", + "01-01", + "2020-W01", + "P1Y", + "-P12Y", + // valid, but outside the supported range: + "-999999-01-01", + "+999999-01-01", +]; +const instance = new Temporal.Calendar("iso8601"); +for (const arg of invalidStrings) { + assert.throws( + RangeError, + () => instance.weekOfYear(arg), + `"${arg}" should not be a valid ISO string for a PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-multiple-time-zone.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-multiple-time-zone.js new file mode 100644 index 0000000000..e20ff8d44c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-multiple-time-zone.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.calendar.prototype.weekofyear +description: More than one time zone annotation is not syntactical +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[UTC][UTC]", + "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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.weekOfYear(arg), + `reject more than one time zone annotation: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-time-separators.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-time-separators.js new file mode 100644 index 0000000000..1b3c088bc4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/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.calendar.prototype.weekofyear +description: Time separator in string argument can vary +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02T15:23", "uppercase T"], + ["2000-05-02t15:23", "lowercase T"], + ["2000-05-02 15:23", "space between date and time"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.weekOfYear(arg); + + assert.sameValue( + result, + 18, + `variant time separators (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-time-zone-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-time-zone-annotation.js new file mode 100644 index 0000000000..72df4dc0cf --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-time-zone-annotation.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.calendar.prototype.weekofyear +description: Various forms of time zone annotation; critical flag has no effect +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02[Asia/Kolkata]", "named, with no time"], + ["2000-05-02[!Europe/Vienna]", "named, with ! and no time"], + ["2000-05-02[+00:00]", "numeric, with no time"], + ["2000-05-02[!-02:30]", "numeric, with ! and no time"], + ["2000-05-02T15:23[America/Sao_Paulo]", "named, with no offset"], + ["2000-05-02T15:23[!Asia/Tokyo]", "named, with ! and no offset"], + ["2000-05-02T15:23[-02:30]", "numeric, with no offset"], + ["2000-05-02T15:23[!+00:00]", "numeric, with ! and no offset"], + ["2000-05-02T15:23+00:00[America/New_York]", "named, with offset"], + ["2000-05-02T15:23+00:00[!UTC]", "named, with offset and !"], + ["2000-05-02T15:23+00:00[+01:00]", "numeric, with offset"], + ["2000-05-02T15:23+00:00[!-08:00]", "numeric, with offset and !"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.weekOfYear(arg); + + assert.sameValue( + result, + 18, + `time zone annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-unknown-annotation.js new file mode 100644 index 0000000000..97d20a1d6d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/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.calendar.prototype.weekofyear +description: Various forms of unknown annotation +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02[foo=bar]", "without time"], + ["2000-05-02T15:23[foo=bar]", "alone"], + ["2000-05-02T15:23[UTC][foo=bar]", "with time zone"], + ["2000-05-02T15:23[u-ca=iso8601][foo=bar]", "with calendar"], + ["2000-05-02T15:23[UTC][foo=bar][u-ca=iso8601]", "with time zone and calendar"], + ["2000-05-02T15:23[foo=bar][_foo-bar0=Ignore-This-999999999999]", "with another unknown annotation"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.weekOfYear(arg); + + assert.sameValue( + result, + 18, + `unknown annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-with-utc-designator.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-with-utc-designator.js new file mode 100644 index 0000000000..8506ffbebd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/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.calendar.prototype.weekofyear +description: RangeError thrown if a string with UTC designator is used as a PlainDate +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "2019-10-01T09:00:00Z", + "2019-10-01T09:00:00Z[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.weekOfYear(arg), + "String with UTC designator should not be valid as a PlainDate" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string.js new file mode 100644 index 0000000000..e3ef1cf9fb --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string.js @@ -0,0 +1,42 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.weekofyear +description: > + Temporal.Calendar.prototype.weekOfYear will take an ISO 8601 date string and + return the week of year of that date. +info: | + 4. Let temporalDate be ? ToTemporalDate(temporalDateLike). + 5. Return 𝔽(! ToISOWeekOfYear(temporalDate.[[ISOYear]], temporalDate.[[ISOMonth]], temporalDate.[[ISODay]])). +features: [Temporal] +---*/ + +const cal = new Temporal.Calendar("iso8601"); + +// The following week numbers are taken from the table "Examples of contemporary +// dates around New Year's Day" from +// https://en.wikipedia.org/wiki/ISO_week_date#Relation_with_the_Gregorian_calendar + +assert.sameValue(cal.weekOfYear("1977-01-01"), 53, "1977-01-01 is in w53"); +assert.sameValue(cal.weekOfYear("1977-01-02"), 53, "1977-01-02 is in w53"); +assert.sameValue(cal.weekOfYear("1977-12-31"), 52, "1977-12-31 is in w52"); +assert.sameValue(cal.weekOfYear("1978-01-01"), 52, "1978-01-01 is in w52"); +assert.sameValue(cal.weekOfYear("1978-01-02"), 1, "1978-01-02 is in w01"); +assert.sameValue(cal.weekOfYear("1978-12-31"), 52, "1978-12-31 is in w52"); +assert.sameValue(cal.weekOfYear("1979-01-01"), 1, "1979-01-01 is in w01"); +assert.sameValue(cal.weekOfYear("1979-12-30"), 52, "1979-12-30 is in w52"); +assert.sameValue(cal.weekOfYear("1979-12-31"), 1, "1979-12-31 is in w01"); +assert.sameValue(cal.weekOfYear("1980-01-01"), 1, "1980-01-01 is in w01"); +assert.sameValue(cal.weekOfYear("1980-12-28"), 52, "1980-12-28 is in w52"); +assert.sameValue(cal.weekOfYear("1980-12-29"), 1, "1980-12-29 is in w01"); +assert.sameValue(cal.weekOfYear("1980-12-30"), 1, "1980-12-30 is in w01"); +assert.sameValue(cal.weekOfYear("1980-12-31"), 1, "1980-12-31 is in w01"); +assert.sameValue(cal.weekOfYear("1981-01-01"), 1, "1981-01-01 is in w01"); +assert.sameValue(cal.weekOfYear("1981-12-31"), 53, "1981-12-31 is in w53"); +assert.sameValue(cal.weekOfYear("1982-01-01"), 53, "1982-01-01 is in w53"); +assert.sameValue(cal.weekOfYear("1982-01-02"), 53, "1982-01-02 is in w53"); +assert.sameValue(cal.weekOfYear("1982-01-03"), 53, "1982-01-03 is in w53"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-wrong-type.js new file mode 100644 index 0000000000..c01cbccbf8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/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.calendar.prototype.weekofyear +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +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.weekOfYear(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.weekOfYear(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/Calendar/prototype/weekOfYear/argument-zoneddatetime-convert.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-zoneddatetime-convert.js new file mode 100644 index 0000000000..ff2c13446a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-zoneddatetime-convert.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.calendar.prototype.weekofyear +description: An exception from TimeZone#getOffsetNanosecondsFor() is propagated. +features: [Temporal] +---*/ + +class TZ extends Temporal.TimeZone { + constructor() { super("UTC") } + getOffsetNanosecondsFor() { throw new Test262Error() } +} + +const tz = new TZ(); +const arg = new Temporal.ZonedDateTime(0n, tz); +const instance = new Temporal.Calendar("iso8601"); + +assert.throws(Test262Error, () => instance.weekOfYear(arg)); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-zoneddatetime-slots.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-zoneddatetime-slots.js new file mode 100644 index 0000000000..09fcb58af3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-zoneddatetime-slots.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.calendar.prototype.weekofyear +description: Getters are not called when converting a ZonedDateTime to a PlainDate. +includes: [compareArray.js] +features: [Temporal] +---*/ + +const actual = []; +const prototypeDescrs = Object.getOwnPropertyDescriptors(Temporal.ZonedDateTime.prototype); +const getters = ["year", "month", "monthCode", "day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond", "calendar"]; + +for (const property of getters) { + Object.defineProperty(Temporal.ZonedDateTime.prototype, property, { + get() { + actual.push(`get ${property}`); + const value = prototypeDescrs[property].get.call(this); + return { + toString() { + actual.push(`toString ${property}`); + return value.toString(); + }, + valueOf() { + actual.push(`valueOf ${property}`); + return value; + }, + }; + }, + }); +} + +const arg = new Temporal.ZonedDateTime(0n, "UTC"); +const instance = new Temporal.Calendar("iso8601"); +instance.weekOfYear(arg); +assert.compareArray(actual, []); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js new file mode 100644 index 0000000000..99482299fa --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/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.calendar.prototype.weekofyear +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(RangeError, () => calendar.weekOfYear(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js new file mode 100644 index 0000000000..81a165f107 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/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.calendar.prototype.weekofyear +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + timeZone.getOffsetNanosecondsFor = notCallable; + assert.throws( + TypeError, + () => calendar.weekOfYear(datetime), + `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js new file mode 100644 index 0000000000..4c27a2650e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/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.calendar.prototype.weekofyear +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(RangeError, () => calendar.weekOfYear(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js new file mode 100644 index 0000000000..29962e7b7a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/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.calendar.prototype.weekofyear +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(TypeError, () => calendar.weekOfYear(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/basic.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/basic.js new file mode 100644 index 0000000000..2249b2200b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/basic.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.calendar.prototype.weekofyear +description: Basic tests for weekOfYear(). +features: [Temporal] +---*/ + +const iso = Temporal.Calendar.from("iso8601"); +const res = 44; +assert.sameValue(iso.weekOfYear(Temporal.PlainDate.from("1994-11-05")), res, "PlainDate"); +assert.sameValue(iso.weekOfYear(Temporal.PlainDateTime.from("1994-11-05T08:15:30")), res, "PlainDateTime"); +assert.sameValue(iso.weekOfYear({ year: 1994, month: 11, day: 5 }), res, "property bag"); +assert.sameValue(iso.weekOfYear("1994-11-05"), res, "string"); +assert.throws(TypeError, () => iso.weekOfYear({ year: 2000 }), "property bag with missing properties"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/branding.js new file mode 100644 index 0000000000..053d01dc38 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/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.calendar.prototype.weekofyear +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const weekOfYear = Temporal.Calendar.prototype.weekOfYear; + +assert.sameValue(typeof weekOfYear, "function"); + +const args = [new Temporal.PlainDate(2021, 7, 20)]; + +assert.throws(TypeError, () => weekOfYear.apply(undefined, args), "undefined"); +assert.throws(TypeError, () => weekOfYear.apply(null, args), "null"); +assert.throws(TypeError, () => weekOfYear.apply(true, args), "true"); +assert.throws(TypeError, () => weekOfYear.apply("", args), "empty string"); +assert.throws(TypeError, () => weekOfYear.apply(Symbol(), args), "symbol"); +assert.throws(TypeError, () => weekOfYear.apply(1, args), "1"); +assert.throws(TypeError, () => weekOfYear.apply({}, args), "plain object"); +assert.throws(TypeError, () => weekOfYear.apply(Temporal.Calendar, args), "Temporal.Calendar"); +assert.throws(TypeError, () => weekOfYear.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/builtin.js new file mode 100644 index 0000000000..bad9179706 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/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.calendar.prototype.weekofyear +description: > + Tests that Temporal.Calendar.prototype.weekOfYear + 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.Calendar.prototype.weekOfYear), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.weekOfYear), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.weekOfYear), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.Calendar.prototype.weekOfYear.hasOwnProperty("prototype"), + false, "prototype property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/calendar-datefromfields-called-with-options-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/calendar-datefromfields-called-with-options-undefined.js new file mode 100644 index 0000000000..ec8530b8a0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/calendar-datefromfields-called-with-options-undefined.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.calendar.prototype.weekofyear +description: > + Calendar.dateFromFields method is called with undefined as the options value + when call originates internally +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = TemporalHelpers.calendarFromFieldsUndefinedOptions(); +calendar.weekOfYear({ year: 2000, month: 5, day: 3, calendar }); +assert.sameValue(calendar.dateFromFieldsCallCount, 1); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/calendar-fields-iterable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/calendar-fields-iterable.js new file mode 100644 index 0000000000..1d22e37f68 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/calendar-fields-iterable.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.calendar.prototype.weekofyear +description: Verify the result of calendar.fields() is treated correctly. +info: | + sec-temporal.calendar.prototype.weekofyear step 4: + 4. Let _date_ be ? ToTemporalDate(_dateOrDateTime_). + sec-temporal-totemporaldate step 2.c: + c. Let _fieldNames_ be ? CalendarFields(_calendar_, « *"day"*, *"month"*, *"monthCode"*, *"year"* »). + sec-temporal-calendarfields step 4: + 4. Let _result_ be ? IterableToListOfType(_fieldsArray_, « String »). +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + "day", + "month", + "monthCode", + "year", +]; + +const calendar1 = TemporalHelpers.calendarFieldsIterable(); +const calendar2 = TemporalHelpers.calendarFieldsIterable(); +calendar1.weekOfYear({ year: 2000, month: 5, day: 2, calendar: calendar2 }); + +assert.sameValue(calendar1.fieldsCallCount, 0, "fields() method not called"); +assert.sameValue(calendar2.fieldsCallCount, 1, "fields() method called once"); +assert.compareArray(calendar2.fieldsCalledWith[0], expected, "fields() method called with correct args"); +assert(calendar2.iteratorExhausted[0], "iterated through the whole iterable"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/calendar-temporal-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/calendar-temporal-object.js new file mode 100644 index 0000000000..1149907743 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/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.calendar.prototype.weekofyear +description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots +info: | + sec-temporal.calendar.prototype.weekofyear step 4: + 4. Let _date_ be ? ToTemporalDate(_dateOrDateTime_). + sec-temporal-totemporaldate 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 calendar = new Temporal.Calendar("iso8601"); + calendar.weekOfYear({ year: 2000, month: 5, day: 2, calendar: temporalObject }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/cross-year.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/cross-year.js new file mode 100644 index 0000000000..e32e6377d8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/cross-year.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.calendar.prototype.weekofyear +description: weekOfYear() crossing year boundaries. +features: [Temporal] +---*/ + +const iso = Temporal.Calendar.from("iso8601"); +assert.sameValue(iso.weekOfYear(Temporal.PlainDate.from("2019-12-31")), 1, "week 1 from next year"); +assert.sameValue(iso.weekOfYear(Temporal.PlainDate.from("2021-01-01")), 53, "week 1 from next year"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/infinity-throws-rangeerror.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/infinity-throws-rangeerror.js new file mode 100644 index 0000000000..6a5c458218 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/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.calendar.prototype.weekofyear +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); +const base = { year: 2000, month: 5, day: 2 }; + +[Infinity, -Infinity].forEach((inf) => { + ["year", "month", "day"].forEach((prop) => { + assert.throws(RangeError, () => instance.weekOfYear({ ...base, [prop]: inf }), `${prop} property cannot be ${inf}`); + + const calls = []; + const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop); + assert.throws(RangeError, () => instance.weekOfYear({ ...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/Calendar/prototype/weekOfYear/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/length.js new file mode 100644 index 0000000000..0dea48edaa --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/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.calendar.prototype.weekofyear +description: Temporal.Calendar.prototype.weekOfYear.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.Calendar.prototype.weekOfYear, "length", { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/name.js new file mode 100644 index 0000000000..155077ed42 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/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.calendar.prototype.weekofyear +description: Temporal.Calendar.prototype.weekOfYear.name is "weekOfYear". +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.Calendar.prototype.weekOfYear, "name", { + value: "weekOfYear", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/not-a-constructor.js new file mode 100644 index 0000000000..fcb6898f30 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/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.calendar.prototype.weekofyear +description: > + Temporal.Calendar.prototype.weekOfYear 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.Calendar.prototype.weekOfYear(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.Calendar.prototype.weekOfYear), false, + "isConstructor(Temporal.Calendar.prototype.weekOfYear)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/prop-desc.js new file mode 100644 index 0000000000..d64279f5fb --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/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.calendar.prototype.weekofyear +description: The "weekOfYear" property of Temporal.Calendar.prototype +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.Calendar.prototype.weekOfYear, + "function", + "`typeof Calendar.prototype.weekOfYear` is `function`" +); + +verifyProperty(Temporal.Calendar.prototype, "weekOfYear", { + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/shell.js new file mode 100644 index 0000000000..eda1477282 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/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/Calendar/prototype/weekOfYear/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/year-zero.js new file mode 100644 index 0000000000..f7a798b849 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/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.calendar.prototype.weekofyear +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.weekOfYear(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-calendar-datefromfields-called-with-null-prototype-fields.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-calendar-datefromfields-called-with-null-prototype-fields.js new file mode 100644 index 0000000000..ef8575d1f5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-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.calendar.prototype.year +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.Calendar("iso8601"); +const arg = { year: 2000, month: 5, day: 2, calendar }; +instance.year(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/Calendar/prototype/year/argument-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-leap-second.js new file mode 100644 index 0000000000..1608cbed9d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-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.calendar.prototype.year +description: Leap second is a valid ISO string for PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.year(arg); +assert.sameValue( + result1, + 2016, + "leap second is a valid ISO string for PlainDate" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.year(arg); +assert.sameValue( + result2, + 2016, + "second: 60 is ignored in property bag for PlainDate" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-number.js new file mode 100644 index 0000000000..4ef02c995b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/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.calendar.prototype.year +description: A number is converted to a string, then to Temporal.PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const arg = 19761118; + +const result = instance.year(arg); +assert.sameValue(result, 1976, "19761118 is a valid ISO string for PlainDate"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.year(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-case-insensitive.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-case-insensitive.js new file mode 100644 index 0000000000..cd07191837 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/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.calendar.prototype.year +description: The calendar name is case-insensitive +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "IsO8601"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.year(arg); +assert.sameValue(result1, 1976, "Calendar is case-insensitive"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.year(arg); +assert.sameValue(result2, 1976, "Calendar is case-insensitive (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-instance-does-not-get-calendar-property.js new file mode 100644 index 0000000000..0288543c8d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/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.calendar.prototype.year +description: > + A Temporal.Calendar instance passed to year() in a property bag does + not have its 'calendar' property observably checked +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +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.year(arg); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +instance.year(arg); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-leap-second.js new file mode 100644 index 0000000000..542ecde17e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/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.calendar.prototype.year +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.year(arg); +assert.sameValue( + result1, + 1976, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.year(arg); +assert.sameValue( + result2, + 1976, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-number.js new file mode 100644 index 0000000000..0df0395bdd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/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.calendar.prototype.year +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.year(arg); +assert.sameValue(result1, 1976, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.year(arg); +assert.sameValue(result2, 1976, "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.year(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.year(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/Calendar/prototype/year/argument-propertybag-calendar-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-string.js new file mode 100644 index 0000000000..2a1f7c87e9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/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.calendar.prototype.year +description: A calendar ID is valid input for Calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "iso8601"; + +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.year(arg); +assert.sameValue(result, 1976, `Calendar created from string "${calendar}"`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 0000000000..79ffa0817a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/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.calendar.prototype.year +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.Calendar("iso8601"); + +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.year(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.year(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.year(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.year(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.year(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-year-zero.js new file mode 100644 index 0000000000..7d973a2718 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/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.calendar.prototype.year +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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.year(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-calendar-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-calendar-annotation.js new file mode 100644 index 0000000000..410a45dc4b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/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.calendar.prototype.year +description: Various forms of calendar annotation; critical flag has no effect +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02[u-ca=iso8601]", "without time or time zone"], + ["2000-05-02[UTC][u-ca=iso8601]", "with time zone and no time"], + ["2000-05-02T15:23[u-ca=iso8601]", "without time zone"], + ["2000-05-02T15:23[UTC][u-ca=iso8601]", "with time zone"], + ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], + ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], + ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], + ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.year(arg); + + assert.sameValue( + result, + 2000, + `calendar annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-critical-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-critical-unknown-annotation.js new file mode 100644 index 0000000000..4ca06aa320 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-critical-unknown-annotation.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.calendar.prototype.year +description: Unknown annotations with critical flag are rejected +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[!foo=bar]", + "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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.year(arg), + `reject unknown annotation with critical flag: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-date-with-utc-offset.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-date-with-utc-offset.js new file mode 100644 index 0000000000..2abdedfb9f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/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.calendar.prototype.year +description: UTC offset not valid with format that does not include a time +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const validStrings = [ + "2000-05-02T00+00:00", + "2000-05-02T00+00:00[UTC]", + "2000-05-02T00+00:00[!UTC]", + "2000-05-02T00-02:30[America/St_Johns]", +]; + +for (const arg of validStrings) { + const result = instance.year(arg); + + assert.sameValue( + result, + 2000, + `"${arg}" is a valid UTC offset with time for PlainDate` + ); +} + +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.year(arg), + `"${arg}" UTC offset without time is not valid for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-invalid.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-invalid.js new file mode 100644 index 0000000000..bea6611e78 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-invalid.js @@ -0,0 +1,64 @@ +// |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.calendar.prototype.year +description: > + RangeError thrown if an invalid ISO string (or syntactically valid ISO string + that is not supported) is used as a PlainDate +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + // invalid ISO strings: + "", + "invalid iso8601", + "2020-01-00", + "2020-01-32", + "2020-02-30", + "2021-02-29", + "2020-00-01", + "2020-13-01", + "2020-01-01T", + "2020-01-01T25:00:00", + "2020-01-01T01:60:00", + "2020-01-01T01:60:61", + "2020-01-01junk", + "2020-01-01T00:00:00junk", + "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-01", + "2020-001-01", + "2020-01-001", + "2020-01-01T001", + "2020-01-01T01:001", + "2020-01-01T01:01:001", + // valid, but forms not supported in Temporal: + "2020-W01-1", + "2020-001", + "+0002020-01-01", + // valid, but this calendar must not exist: + "2020-01-01[u-ca=notexist]", + // may be valid in other contexts, but insufficient information for PlainDate: + "2020-01", + "+002020-01", + "01-01", + "2020-W01", + "P1Y", + "-P12Y", + // valid, but outside the supported range: + "-999999-01-01", + "+999999-01-01", +]; +const instance = new Temporal.Calendar("iso8601"); +for (const arg of invalidStrings) { + assert.throws( + RangeError, + () => instance.year(arg), + `"${arg}" should not be a valid ISO string for a PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-multiple-time-zone.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-multiple-time-zone.js new file mode 100644 index 0000000000..48e6e101b4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-multiple-time-zone.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.calendar.prototype.year +description: More than one time zone annotation is not syntactical +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[UTC][UTC]", + "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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.year(arg), + `reject more than one time zone annotation: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-time-separators.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-time-separators.js new file mode 100644 index 0000000000..a15c7a37df --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/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.calendar.prototype.year +description: Time separator in string argument can vary +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02T15:23", "uppercase T"], + ["2000-05-02t15:23", "lowercase T"], + ["2000-05-02 15:23", "space between date and time"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.year(arg); + + assert.sameValue( + result, + 2000, + `variant time separators (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-time-zone-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-time-zone-annotation.js new file mode 100644 index 0000000000..e4efcac9ab --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-time-zone-annotation.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.calendar.prototype.year +description: Various forms of time zone annotation; critical flag has no effect +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02[Asia/Kolkata]", "named, with no time"], + ["2000-05-02[!Europe/Vienna]", "named, with ! and no time"], + ["2000-05-02[+00:00]", "numeric, with no time"], + ["2000-05-02[!-02:30]", "numeric, with ! and no time"], + ["2000-05-02T15:23[America/Sao_Paulo]", "named, with no offset"], + ["2000-05-02T15:23[!Asia/Tokyo]", "named, with ! and no offset"], + ["2000-05-02T15:23[-02:30]", "numeric, with no offset"], + ["2000-05-02T15:23[!+00:00]", "numeric, with ! and no offset"], + ["2000-05-02T15:23+00:00[America/New_York]", "named, with offset"], + ["2000-05-02T15:23+00:00[!UTC]", "named, with offset and !"], + ["2000-05-02T15:23+00:00[+01:00]", "numeric, with offset"], + ["2000-05-02T15:23+00:00[!-08:00]", "numeric, with offset and !"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.year(arg); + + assert.sameValue( + result, + 2000, + `time zone annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-unknown-annotation.js new file mode 100644 index 0000000000..dc331b77d4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/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.calendar.prototype.year +description: Various forms of unknown annotation +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02[foo=bar]", "without time"], + ["2000-05-02T15:23[foo=bar]", "alone"], + ["2000-05-02T15:23[UTC][foo=bar]", "with time zone"], + ["2000-05-02T15:23[u-ca=iso8601][foo=bar]", "with calendar"], + ["2000-05-02T15:23[UTC][foo=bar][u-ca=iso8601]", "with time zone and calendar"], + ["2000-05-02T15:23[foo=bar][_foo-bar0=Ignore-This-999999999999]", "with another unknown annotation"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.year(arg); + + assert.sameValue( + result, + 2000, + `unknown annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-with-utc-designator.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-with-utc-designator.js new file mode 100644 index 0000000000..696add2c5b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/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.calendar.prototype.year +description: RangeError thrown if a string with UTC designator is used as a PlainDate +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "2019-10-01T09:00:00Z", + "2019-10-01T09:00:00Z[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.year(arg), + "String with UTC designator should not be valid as a PlainDate" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-wrong-type.js new file mode 100644 index 0000000000..2f14a8efe6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/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.calendar.prototype.year +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +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.year(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.year(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/Calendar/prototype/year/argument-zoneddatetime-convert.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-zoneddatetime-convert.js new file mode 100644 index 0000000000..6ae7560a7b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-zoneddatetime-convert.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.calendar.prototype.year +description: An exception from TimeZone#getOffsetNanosecondsFor() is propagated. +features: [Temporal] +---*/ + +class TZ extends Temporal.TimeZone { + constructor() { super("UTC") } + getOffsetNanosecondsFor() { throw new Test262Error() } +} + +const tz = new TZ(); +const arg = new Temporal.ZonedDateTime(0n, tz); +const instance = new Temporal.Calendar("iso8601"); + +assert.throws(Test262Error, () => instance.year(arg)); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-zoneddatetime-slots.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-zoneddatetime-slots.js new file mode 100644 index 0000000000..c097494cd1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-zoneddatetime-slots.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.calendar.prototype.year +description: Getters are not called when converting a ZonedDateTime to a PlainDate. +includes: [compareArray.js] +features: [Temporal] +---*/ + +const actual = []; +const prototypeDescrs = Object.getOwnPropertyDescriptors(Temporal.ZonedDateTime.prototype); +const getters = ["year", "month", "monthCode", "day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond", "calendar"]; + +for (const property of getters) { + Object.defineProperty(Temporal.ZonedDateTime.prototype, property, { + get() { + actual.push(`get ${property}`); + const value = prototypeDescrs[property].get.call(this); + return { + toString() { + actual.push(`toString ${property}`); + return value.toString(); + }, + valueOf() { + actual.push(`valueOf ${property}`); + return value; + }, + }; + }, + }); +} + +const arg = new Temporal.ZonedDateTime(0n, "UTC"); +const instance = new Temporal.Calendar("iso8601"); +instance.year(arg); +assert.compareArray(actual, []); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js new file mode 100644 index 0000000000..c4b7cffc1f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/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.calendar.prototype.year +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(RangeError, () => calendar.year(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js new file mode 100644 index 0000000000..656af7e140 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/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.calendar.prototype.year +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + timeZone.getOffsetNanosecondsFor = notCallable; + assert.throws( + TypeError, + () => calendar.year(datetime), + `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js new file mode 100644 index 0000000000..ef1234ee56 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/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.calendar.prototype.year +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(RangeError, () => calendar.year(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js new file mode 100644 index 0000000000..8fd76aac16 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/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.calendar.prototype.year +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(TypeError, () => calendar.year(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/basic.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/basic.js new file mode 100644 index 0000000000..e8f878fdbc --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/basic.js @@ -0,0 +1,20 @@ +// |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.calendar.prototype.year +description: Basic tests for year(). +features: [Temporal] +---*/ + +const iso = Temporal.Calendar.from("iso8601"); +const res = 1994; +assert.sameValue(iso.year(Temporal.PlainDate.from("1994-11-05")), res, "PlainDate"); +assert.sameValue(iso.year(Temporal.PlainDateTime.from("1994-11-05T08:15:30")), res, "PlainDateTime"); +assert.sameValue(iso.year(Temporal.PlainYearMonth.from("1994-11")), res, "PlainYearMonth"); +assert.sameValue(iso.year({ year: 1994, month: 11, day: 5 }), res, "property bag"); +assert.sameValue(iso.year("1994-11-05"), res, "string"); +assert.throws(TypeError, () => iso.year({ month: 5 }), "property bag with missing properties"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/branding.js new file mode 100644 index 0000000000..1c36c604d4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/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.calendar.prototype.year +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const year = Temporal.Calendar.prototype.year; + +assert.sameValue(typeof year, "function"); + +const args = [new Temporal.PlainDate(2000, 1, 1)]; + +assert.throws(TypeError, () => year.apply(undefined, args), "undefined"); +assert.throws(TypeError, () => year.apply(null, args), "null"); +assert.throws(TypeError, () => year.apply(true, args), "true"); +assert.throws(TypeError, () => year.apply("", args), "empty string"); +assert.throws(TypeError, () => year.apply(Symbol(), args), "symbol"); +assert.throws(TypeError, () => year.apply(1, args), "1"); +assert.throws(TypeError, () => year.apply({}, args), "plain object"); +assert.throws(TypeError, () => year.apply(Temporal.Calendar, args), "Temporal.Calendar"); +assert.throws(TypeError, () => year.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/builtin.js new file mode 100644 index 0000000000..5ac001b488 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/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.calendar.prototype.year +description: > + Tests that Temporal.Calendar.prototype.year + 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.Calendar.prototype.year), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.year), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.year), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.Calendar.prototype.year.hasOwnProperty("prototype"), + false, "prototype property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/calendar-datefromfields-called-with-options-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/calendar-datefromfields-called-with-options-undefined.js new file mode 100644 index 0000000000..a050453a31 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/calendar-datefromfields-called-with-options-undefined.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.calendar.prototype.year +description: > + Calendar.dateFromFields method is called with undefined as the options value + when call originates internally +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = TemporalHelpers.calendarFromFieldsUndefinedOptions(); +calendar.year({ year: 2000, month: 5, day: 3, calendar }); +assert.sameValue(calendar.dateFromFieldsCallCount, 1); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/calendar-fields-iterable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/calendar-fields-iterable.js new file mode 100644 index 0000000000..d95e15afcd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/calendar-fields-iterable.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.calendar.prototype.year +description: Verify the result of calendar.fields() is treated correctly. +info: | + sec-temporal.calendar.prototype.year step 4: + 4. Return ? ISOYear(_dateOrDateTime_). + sec-temporal-isoyear step 1.a: + a. Set _dateOrDateTime_ to ? ToTemporalDate(_dateOrDateTime_). + sec-temporal-totemporaldate step 2.c: + c. Let _fieldNames_ be ? CalendarFields(_calendar_, « *"day"*, *"month"*, *"monthCode"*, *"year"* »). + sec-temporal-calendarfields step 4: + 4. Let _result_ be ? IterableToListOfType(_fieldsArray_, « String »). +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + "day", + "month", + "monthCode", + "year", +]; + +const calendar1 = TemporalHelpers.calendarFieldsIterable(); +const calendar2 = TemporalHelpers.calendarFieldsIterable(); +calendar1.year({ year: 2000, month: 5, day: 2, calendar: calendar2 }); + +assert.sameValue(calendar1.fieldsCallCount, 0, "fields() method not called"); +assert.sameValue(calendar2.fieldsCallCount, 1, "fields() method called once"); +assert.compareArray(calendar2.fieldsCalledWith[0], expected, "fields() method called with correct args"); +assert(calendar2.iteratorExhausted[0], "iterated through the whole iterable"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/calendar-temporal-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/calendar-temporal-object.js new file mode 100644 index 0000000000..4f223f06ac --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/calendar-temporal-object.js @@ -0,0 +1,31 @@ +// |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.calendar.prototype.dayofweek +description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots +info: | + sec-temporal.calendar.prototype.year step 4: + 4. Return ? ISOYear(_dateOrDateTime_). + sec-temporal-isoyear step 1.a: + a. Set _dateOrDateTime_ to ? ToTemporalDate(_dateOrDateTime_). + sec-temporal-totemporaldate 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 calendar = new Temporal.Calendar("iso8601"); + calendar.year({ year: 2000, month: 5, day: 2, calendar: temporalObject }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/date-time.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/date-time.js new file mode 100644 index 0000000000..ce4b9090e7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/date-time.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.year +description: > + Temporal.Calendar.prototype.year will take PlainDateTime and return + the value of the year. +info: | + 1. Let calendar be the this value. + 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]). + 3. Assert: calendar.[[Identifier]] is "iso8601". + 4. If Type(temporalDateLike) is not Object or temporalDateLike does not have an [[InitializedTemporalDate]] or [[InitializedTemporalYearMonth]] internal slot, then + a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike). + 5. Return ! ISOYear(temporalDateLike). +features: [Temporal] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +let dateTime = new Temporal.PlainDateTime(1997, 8, 23, 5, 30, 13) +assert.sameValue(cal.year(dateTime), 1997, 'cal.year(new Temporal.PlainDateTime(1997, 8, 23, 5, 30, 13)) must return 1997'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/date.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/date.js new file mode 100644 index 0000000000..cfe9eb7449 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/date.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.year +description: > + Temporal.Calendar.prototype.year will take PlainDate and return + the value of the year. +info: | + 1. Let calendar be the this value. + 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]). + 3. Assert: calendar.[[Identifier]] is "iso8601". + 4. If Type(temporalDateLike) is not Object or temporalDateLike does not have an [[InitializedTemporalDate]] or [[InitializedTemporalYearMonth]] internal slot, then + a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike). + 5. Return ! ISOYear(temporalDateLike). +features: [Temporal] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +let date = new Temporal.PlainDate(2021, 7, 15); +assert.sameValue(cal.year(date), 2021, 'cal.year(new Temporal.PlainDate(2021, 7, 15)) must return 2021'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/infinity-throws-rangeerror.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/infinity-throws-rangeerror.js new file mode 100644 index 0000000000..e81bc6f488 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/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.calendar.prototype.year +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); +const base = { year: 2000, month: 5, day: 2 }; + +[Infinity, -Infinity].forEach((inf) => { + ["year", "month", "day"].forEach((prop) => { + assert.throws(RangeError, () => instance.year({ ...base, [prop]: inf }), `${prop} property cannot be ${inf}`); + + const calls = []; + const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop); + assert.throws(RangeError, () => instance.year({ ...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/Calendar/prototype/year/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/length.js new file mode 100644 index 0000000000..ffcb847b7d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/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.calendar.prototype.year +description: Temporal.Calendar.prototype.year.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.Calendar.prototype.year, "length", { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/name.js new file mode 100644 index 0000000000..107397ad94 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/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.calendar.prototype.year +description: Temporal.Calendar.prototype.year.name is "year". +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.Calendar.prototype.year, "name", { + value: "year", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/not-a-constructor.js new file mode 100644 index 0000000000..bc6a631dc2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/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.calendar.prototype.year +description: > + Temporal.Calendar.prototype.year 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.Calendar.prototype.year(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.Calendar.prototype.year), false, + "isConstructor(Temporal.Calendar.prototype.year)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/prop-desc.js new file mode 100644 index 0000000000..963969da91 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/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.calendar.prototype.year +description: The "year" property of Temporal.Calendar.prototype +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.Calendar.prototype.year, + "function", + "`typeof Calendar.prototype.year` is `function`" +); + +verifyProperty(Temporal.Calendar.prototype, "year", { + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/shell.js new file mode 100644 index 0000000000..eda1477282 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/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/Calendar/prototype/year/string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/string.js new file mode 100644 index 0000000000..98198babcb --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/string.js @@ -0,0 +1,23 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.year +description: > + Temporal.Calendar.prototype.year will take ISO8601 string and return + the value of the year. +info: | + 1. Let calendar be the this value. + 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]). + 3. Assert: calendar.[[Identifier]] is "iso8601". + 4. If Type(temporalDateLike) is not Object or temporalDateLike does not have an [[InitializedTemporalDate]] or [[InitializedTemporalYearMonth]] internal slot, then + a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike). + 5. Return ! ISOYear(temporalDateLike). +features: [Temporal] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +assert.sameValue(cal.year("2019-03-15"), 2019, 'cal.year("2019-03-15") must return 2019'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/throw-range-error-ToTemporalDate.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/throw-range-error-ToTemporalDate.js new file mode 100644 index 0000000000..9fd959681b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/throw-range-error-ToTemporalDate.js @@ -0,0 +1,22 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.year +description: > + Temporal.Calendar.prototype.year throws RangeError on + ToTemporalDate when temporalDateLike is invalid string. +info: | + 4. If Type(temporalDateLike) is not Object or temporalDateLike + does not have an [[InitializedTemporalDate]] or + [[InitializedTemporalYearMonth]] internal slot, then + a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike). +features: [Temporal, arrow-function] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +assert.throws(RangeError, () => cal.year("invalid string"), + 'cal.year("invalid string") throws a RangeError exception'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/year-month.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/year-month.js new file mode 100644 index 0000000000..8e41f681fc --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/year-month.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.year +description: > + Temporal.Calendar.prototype.year will take PlainYearMonth and return + the value of the year. +info: | + 1. Let calendar be the this value. + 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]). + 3. Assert: calendar.[[Identifier]] is "iso8601". + 4. If Type(temporalDateLike) is not Object or temporalDateLike does not have an [[InitializedTemporalDate]] or [[InitializedTemporalYearMonth]] internal slot, then + a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike). + 5. Return ! ISOYear(temporalDateLike). +features: [Temporal] +---*/ +let cal = new Temporal.Calendar("iso8601"); + +let yearMonth = new Temporal.PlainYearMonth(1999, 6); +assert.sameValue(cal.year(yearMonth), 1999, 'cal.year(new Temporal.PlainYearMonth(1999, 6)) must return 1999'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/year-zero.js new file mode 100644 index 0000000000..31c7467c66 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/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.calendar.prototype.year +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.year(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/basic.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/basic.js new file mode 100644 index 0000000000..9785663d2b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/basic.js @@ -0,0 +1,43 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.yearmonthfromfields +description: Temporal.Calendar.prototype.yearMonthFromFields return correctly with valid data. +info: | + 1. Let calendar be the this value. + 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]). + 3. Assert: calendar.[[Identifier]] is "iso8601". + 4. If Type(fields) is not Object, throw a TypeError exception. + 5. Set options to ? GetOptionsObject(options). + 6. Let result be ? ISOYearMonthFromFields(fields, options). + 7. Return ? CreateTemporalYearMonth(result.[[Year]], result.[[Month]], calendar, result.[[ReferenceISODay]]). +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const cal = new Temporal.Calendar("iso8601") + +let result = cal.yearMonthFromFields({ year: 2021, month: 7 }); +TemporalHelpers.assertPlainYearMonth(result, 2021, 7, "M07", "year 2021, month 7"); +result = cal.yearMonthFromFields({ year: 2021, month: 12 }); +TemporalHelpers.assertPlainYearMonth(result, 2021, 12, "M12", "year 2021, month 12"); +result = cal.yearMonthFromFields({ year: 2021, monthCode: "M07" }); +TemporalHelpers.assertPlainYearMonth(result, 2021, 7, "M07", "year 2021, monthCode M07"); +result = cal.yearMonthFromFields({ year: 2021, monthCode: "M12" }); +TemporalHelpers.assertPlainYearMonth(result, 2021, 12, "M12", "year 2021, monthCode M12"); + +["constrain", "reject"].forEach((overflow) => { + const opt = { overflow }; + result = cal.yearMonthFromFields({ year: 2021, month: 7 }, opt); + TemporalHelpers.assertPlainYearMonth(result, 2021, 7, "M07", `year 2021, month 7, overflow ${overflow}`); + result = cal.yearMonthFromFields({ year: 2021, month: 12 }, opt); + TemporalHelpers.assertPlainYearMonth(result, 2021, 12, "M12", `year 2021, month 12, overflow ${overflow}`); + result = cal.yearMonthFromFields({ year: 2021, monthCode: "M07" }, opt); + TemporalHelpers.assertPlainYearMonth(result, 2021, 7, "M07", `year 2021, monthCode M07, overflow ${overflow}`); + result = cal.yearMonthFromFields({ year: 2021, monthCode: "M12" }, opt); + TemporalHelpers.assertPlainYearMonth(result, 2021, 12, "M12", `year 2021, monthCode M12, overflow ${overflow}`); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/branding.js new file mode 100644 index 0000000000..609894def1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/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.calendar.prototype.yearmonthfromfields +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const yearMonthFromFields = Temporal.Calendar.prototype.yearMonthFromFields; + +assert.sameValue(typeof yearMonthFromFields, "function"); + +const args = [{ year: 2021, month: 1 }]; + +assert.throws(TypeError, () => yearMonthFromFields.apply(undefined, args), "undefined"); +assert.throws(TypeError, () => yearMonthFromFields.apply(null, args), "null"); +assert.throws(TypeError, () => yearMonthFromFields.apply(true, args), "true"); +assert.throws(TypeError, () => yearMonthFromFields.apply("", args), "empty string"); +assert.throws(TypeError, () => yearMonthFromFields.apply(Symbol(), args), "symbol"); +assert.throws(TypeError, () => yearMonthFromFields.apply(1, args), "1"); +assert.throws(TypeError, () => yearMonthFromFields.apply({}, args), "plain object"); +assert.throws(TypeError, () => yearMonthFromFields.apply(Temporal.Calendar, args), "Temporal.Calendar"); +assert.throws(TypeError, () => yearMonthFromFields.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/builtin.js new file mode 100644 index 0000000000..0fdda4247f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/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.calendar.prototype.yearmonthfromfields +description: > + Tests that Temporal.Calendar.prototype.yearMonthFromFields + 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.Calendar.prototype.yearMonthFromFields), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.yearMonthFromFields), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.yearMonthFromFields), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.Calendar.prototype.yearMonthFromFields.hasOwnProperty("prototype"), + false, "prototype property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/fields-missing-properties.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/fields-missing-properties.js new file mode 100644 index 0000000000..4e751f5ce9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/fields-missing-properties.js @@ -0,0 +1,25 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.yearmonthfromfields +description: Temporal.Calendar.prototype.yearMonthFromFields will throw TypeError with incorrect input data type. +info: | + 1. Let calendar be the this value. + 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]). + 3. Assert: calendar.[[Identifier]] is "iso8601". + 4. If Type(fields) is not Object, throw a TypeError exception. + 5. Set options to ? GetOptionsObject(options). + 6. Let result be ? ISOYearMonthFromFields(fields, options). + 7. Return ? CreateTemporalYearMonth(result.[[Year]], result.[[Month]], calendar, result.[[ReferenceISODay]]). +features: [Temporal] +---*/ + +const cal = new Temporal.Calendar("iso8601") + +assert.throws(TypeError, () => cal.yearMonthFromFields({}), "at least one correctly spelled property is required"); +assert.throws(TypeError, () => cal.yearMonthFromFields({ month: 1 }), "year is required"); +assert.throws(TypeError, () => cal.yearMonthFromFields({ year: 2021 }), "month or monthCode is required"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/fields-not-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/fields-not-object.js new file mode 100644 index 0000000000..4c14ec0d19 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/fields-not-object.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-temporal.calendar.prototype.yearmonthfromfields +description: Throw a TypeError if the fields is not an object +features: [Symbol, Temporal] +---*/ + +const tests = [undefined, null, true, false, "string", Symbol("sym"), Math.PI, Infinity, NaN, 42n]; +const iso = Temporal.Calendar.from("iso8601"); +for (const fields of tests) { + assert.throws(TypeError, () => iso.yearMonthFromFields(fields, {})); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/infinity-throws-rangeerror.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/infinity-throws-rangeerror.js new file mode 100644 index 0000000000..0625864395 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/infinity-throws-rangeerror.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. + +/*--- +description: Throws if any value in the property bag is Infinity or -Infinity +esid: sec-temporal.calendar.prototype.yearmonthfromfields +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); +const base = { year: 2000, month: 5 }; + +[Infinity, -Infinity].forEach((inf) => { + ["year", "month"].forEach((prop) => { + ["constrain", "reject"].forEach((overflow) => { + assert.throws(RangeError, () => instance.yearMonthFromFields({ ...base, [prop]: inf }, { overflow }), `${prop} property cannot be ${inf} (overflow ${overflow}`); + + const calls = []; + const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop); + assert.throws(RangeError, () => instance.yearMonthFromFields({ ...base, [prop]: obj }, { overflow })); + 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/Calendar/prototype/yearMonthFromFields/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/length.js new file mode 100644 index 0000000000..db596e5599 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/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.calendar.prototype.yearmonthfromfields +description: Temporal.Calendar.prototype.yearMonthFromFields.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.Calendar.prototype.yearMonthFromFields, "length", { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/missing-properties.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/missing-properties.js new file mode 100644 index 0000000000..385b7f87db --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/missing-properties.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.calendar.prototype.yearmonthfromfields +description: Errors due to missing properties on fields object are thrown in the correct order +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +let getMonth = false; +let getMonthCode = false; +const missingYearAndMonth = { + get month() { + getMonth = true; + }, + get monthCode() { + getMonthCode = true; + }, +}; +assert.throws(TypeError, () => instance.yearMonthFromFields(missingYearAndMonth), "year should be checked after fetching but before resolving the month"); +assert(getMonth, "year is fetched after month"); +assert(getMonthCode, "year is fetched after monthCode"); + +assert.throws(TypeError, () => instance.yearMonthFromFields({ year: 2000 }), "month should be resolved last"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/monthcode-invalid.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/monthcode-invalid.js new file mode 100644 index 0000000000..a57a16ffc2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/monthcode-invalid.js @@ -0,0 +1,34 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.yearmonthfromfields +description: Throw RangeError for an out-of-range, conflicting, or ill-formed monthCode +info: | + 1. Let calendar be the this value. + 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]). + 3. Assert: calendar.[[Identifier]] is "iso8601". + 4. If Type(fields) is not Object, throw a TypeError exception. + 5. Set options to ? GetOptionsObject(options). + 6. Let result be ? ISOYearMonthFromFields(fields, options). + 7. Return ? CreateTemporalYearMonth(result.[[Year]], result.[[Month]], calendar, result.[[ReferenceISODay]]). +features: [Temporal] +---*/ + +const cal = new Temporal.Calendar("iso8601"); + +["m1", "M1", "m01"].forEach((monthCode) => { + assert.throws(RangeError, () => cal.yearMonthFromFields({ year: 2021, monthCode }), + `monthCode '${monthCode}' is not well-formed`); +}); + +assert.throws(RangeError, () => cal.yearMonthFromFields({ year: 2021, month: 12, monthCode: "M11" }), + "monthCode and month conflict"); + +["M00", "M19", "M99", "M13"].forEach((monthCode) => { + assert.throws(RangeError, () => cal.yearMonthFromFields({ year: 2021, monthCode }), + `monthCode '${monthCode}' is not valid for year 2021`); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/name.js new file mode 100644 index 0000000000..2d8b990950 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/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.calendar.prototype.yearmonthfromfields +description: Temporal.Calendar.prototype.yearMonthFromFields.name is "yearMonthFromFields". +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.Calendar.prototype.yearMonthFromFields, "name", { + value: "yearMonthFromFields", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/not-a-constructor.js new file mode 100644 index 0000000000..b505f3068f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/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.calendar.prototype.yearmonthfromfields +description: > + Temporal.Calendar.prototype.yearMonthFromFields 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.Calendar.prototype.yearMonthFromFields(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.Calendar.prototype.yearMonthFromFields), false, + "isConstructor(Temporal.Calendar.prototype.yearMonthFromFields)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/one-of-era-erayear-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/one-of-era-erayear-undefined.js new file mode 100644 index 0000000000..2ece6f43e8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/one-of-era-erayear-undefined.js @@ -0,0 +1,19 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.yearMonthFromFields +description: Does not throw a RangeError if only one of era/eraYear fields is present +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const base = { year: 2000, month: 5, day: 2, era: 'ce' }; +const instance = new Temporal.Calendar('iso8601'); +TemporalHelpers.assertPlainYearMonth(instance.yearMonthFromFields({ ...base }), 2000, 5, 'M05'); + +const base2 = { year: 2000, month: 5, day: 2, eraYear: 1 }; +TemporalHelpers.assertPlainYearMonth(instance.yearMonthFromFields({ ...base }), 2000, 5, 'M05'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/options-not-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/options-not-object.js new file mode 100644 index 0000000000..77a9e9e8a0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/options-not-object.js @@ -0,0 +1,20 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.yearmonthfromfields +description: Throw a TypeError if options is not an object or undefined +info: | + 5. Set options to ? GetOptionsObject(options). +features: [Symbol, Temporal] +---*/ + +const tests = [null, true, false, "string", Symbol("sym"), Math.PI, Infinity, NaN, 42n]; +const iso = new Temporal.Calendar("iso8601"); +for (const options of tests) { + assert.throws(TypeError, () => iso.yearMonthFromFields({ year: 2021, month: 7 }, options), + "options is not object"); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/options-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/options-object.js new file mode 100644 index 0000000000..09a234a9a9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/options-object.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.calendar.prototype.yearmonthfromfields +description: Empty or a function object may be used as options +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const result1 = instance.yearMonthFromFields({ year: 2000, monthCode: "M05" }, {}); +TemporalHelpers.assertPlainYearMonth( + result1, 2000, 5, "M05", + "options may be an empty plain object" +); + +const result2 = instance.yearMonthFromFields({ year: 2000, monthCode: "M05" }, () => {}); +TemporalHelpers.assertPlainYearMonth( + result2, 2000, 5, "M05", + "options may be a function object" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/options-wrong-type.js new file mode 100644 index 0000000000..9a4bd2f437 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/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.calendar.prototype.yearmonthfromfields +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.Calendar("iso8601"); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.yearMonthFromFields({ year: 2000, monthCode: "M05" }, value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/order-of-operations.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/order-of-operations.js new file mode 100644 index 0000000000..c31a2154da --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/order-of-operations.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.calendar.prototype.yearmonthfromfields +description: Properties on objects passed to yearMonthFromFields() are accessed in the correct order +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + "get fields.month", + "get fields.month.valueOf", + "call fields.month.valueOf", + "get fields.monthCode", + "get fields.monthCode.toString", + "call fields.monthCode.toString", + "get fields.year", + "get fields.year.valueOf", + "call fields.year.valueOf", + "get options.overflow", + "get options.overflow.toString", + "call options.overflow.toString", +]; +const actual = []; + +const instance = new Temporal.Calendar("iso8601"); + +const fields = TemporalHelpers.propertyBagObserver(actual, { + year: 1.7, + month: 1.7, + monthCode: "M01", +}, "fields"); + +const options = TemporalHelpers.propertyBagObserver(actual, { + overflow: "reject", +}, "options"); + +const result = instance.yearMonthFromFields(fields, options); +TemporalHelpers.assertPlainYearMonth(result, 1, 1, "M01", "yearMonth result"); +assert.sameValue(result.calendar, instance, "calendar result"); +assert.compareArray(actual, expected, "order of operations"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-constrain.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-constrain.js new file mode 100644 index 0000000000..0c3accf759 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-constrain.js @@ -0,0 +1,94 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.yearmonthfromfields +description: Temporal.Calendar.prototype.yearMonthFromFields will return correctly with data and overflow set to 'constrain'. +info: | + 1. Let calendar be the this value. + 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]). + 3. Assert: calendar.[[Identifier]] is "iso8601". + 4. If Type(fields) is not Object, throw a TypeError exception. + 5. Set options to ? GetOptionsObject(options). + 6. Let result be ? ISOYearMonthFromFields(fields, options). + 7. Return ? CreateTemporalYearMonth(result.[[Year]], result.[[Month]], calendar, result.[[ReferenceISODay]]). +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const cal = new Temporal.Calendar("iso8601") +const opt = { overflow: "constrain" }; + +let result = cal.yearMonthFromFields({ year: 2021, month: 1 }, opt); +TemporalHelpers.assertPlainYearMonth(result, 2021, 1, "M01", "month 1 with overflow constrain"); +result = cal.yearMonthFromFields({ year: 2021, month: 2 }, opt); +TemporalHelpers.assertPlainYearMonth(result, 2021, 2, "M02", "month 2 with overflow constrain"); +result = cal.yearMonthFromFields({ year: 2021, month: 3 }, opt); +TemporalHelpers.assertPlainYearMonth(result, 2021, 3, "M03", "month 3 with overflow constrain"); +result = cal.yearMonthFromFields({ year: 2021, month: 4 }, opt); +TemporalHelpers.assertPlainYearMonth(result, 2021, 4, "M04", "month 4 with overflow constrain"); +result = cal.yearMonthFromFields({ year: 2021, month: 5 }, opt); +TemporalHelpers.assertPlainYearMonth(result, 2021, 5, "M05", "month 5 with overflow constrain"); +result = cal.yearMonthFromFields({ year: 2021, month: 6 }, opt); +TemporalHelpers.assertPlainYearMonth(result, 2021, 6, "M06", "month 6 with overflow constrain"); +result = cal.yearMonthFromFields({ year: 2021, month: 7 }, opt); +TemporalHelpers.assertPlainYearMonth(result, 2021, 7, "M07", "month 7 with overflow constrain"); +result = cal.yearMonthFromFields({ year: 2021, month: 8 }, opt); +TemporalHelpers.assertPlainYearMonth(result, 2021, 8, "M08", "month 8 with overflow constrain"); +result = cal.yearMonthFromFields({ year: 2021, month: 9 }, opt); +TemporalHelpers.assertPlainYearMonth(result, 2021, 9, "M09", "month 9 with overflow constrain"); +result = cal.yearMonthFromFields({ year: 2021, month: 10 }, opt); +TemporalHelpers.assertPlainYearMonth(result, 2021, 10, "M10", "month 10 with overflow constrain"); +result = cal.yearMonthFromFields({ year: 2021, month: 11 }, opt); +TemporalHelpers.assertPlainYearMonth(result, 2021, 11, "M11", "month 11 with overflow constrain"); +result = cal.yearMonthFromFields({ year: 2021, month: 12 }, opt); +TemporalHelpers.assertPlainYearMonth(result, 2021, 12, "M12", "month 12 with overflow constrain"); + +assert.throws( + RangeError, + () => cal.yearMonthFromFields({ year: 2021, month: -99999 }, opt), + "negative month -99999 is out of range even with overflow constrain" +) +assert.throws( + RangeError, + () => cal.yearMonthFromFields({ year: 2021, month: -1 }, opt), + "negative month -1 is out of range even with overflow constrain" +) +assert.throws( + RangeError, + () => cal.yearMonthFromFields({ year: 2021, month: 0 }, opt), + "month zero is out of range even with overflow constrain" +) + +result = cal.yearMonthFromFields({ year: 2021, month: 13 }, opt); +TemporalHelpers.assertPlainYearMonth(result, 2021, 12, "M12", "month 13 is constrained to 12"); +result = cal.yearMonthFromFields({ year: 2021, month: 99999 }, opt); +TemporalHelpers.assertPlainYearMonth(result, 2021, 12, "M12", "month 99999 is constrained to 12"); + +result = cal.yearMonthFromFields({ year: 2021, monthCode: "M01" }, opt); +TemporalHelpers.assertPlainYearMonth(result, 2021, 1, "M01", "monthCode M01 with overflow constrain"); +result = cal.yearMonthFromFields({ year: 2021, monthCode: "M02" }, opt); +TemporalHelpers.assertPlainYearMonth(result, 2021, 2, "M02", "monthCode M02 with overflow constrain"); +result = cal.yearMonthFromFields({ year: 2021, monthCode: "M03" }, opt); +TemporalHelpers.assertPlainYearMonth(result, 2021, 3, "M03", "monthCode M03 with overflow constrain"); +result = cal.yearMonthFromFields({ year: 2021, monthCode: "M04" }, opt); +TemporalHelpers.assertPlainYearMonth(result, 2021, 4, "M04", "monthCode M04 with overflow constrain"); +result = cal.yearMonthFromFields({ year: 2021, monthCode: "M05" }, opt); +TemporalHelpers.assertPlainYearMonth(result, 2021, 5, "M05", "monthCode M05 with overflow constrain"); +result = cal.yearMonthFromFields({ year: 2021, monthCode: "M06" }, opt); +TemporalHelpers.assertPlainYearMonth(result, 2021, 6, "M06", "monthCode M06 with overflow constrain"); +result = cal.yearMonthFromFields({ year: 2021, monthCode: "M07" }, opt); +TemporalHelpers.assertPlainYearMonth(result, 2021, 7, "M07", "monthCode M07 with overflow constrain"); +result = cal.yearMonthFromFields({ year: 2021, monthCode: "M08" }, opt); +TemporalHelpers.assertPlainYearMonth(result, 2021, 8, "M08", "monthCode M08 with overflow constrain"); +result = cal.yearMonthFromFields({ year: 2021, monthCode: "M09" }, opt); +TemporalHelpers.assertPlainYearMonth(result, 2021, 9, "M09", "monthCode M09 with overflow constrain"); +result = cal.yearMonthFromFields({ year: 2021, monthCode: "M10" }, opt); +TemporalHelpers.assertPlainYearMonth(result, 2021, 10, "M10", "monthCode M10 with overflow constrain"); +result = cal.yearMonthFromFields({ year: 2021, monthCode: "M11" }, opt); +TemporalHelpers.assertPlainYearMonth(result, 2021, 11, "M11", "monthCode M11 with overflow constrain"); +result = cal.yearMonthFromFields({ year: 2021, monthCode: "M12" }, opt); +TemporalHelpers.assertPlainYearMonth(result, 2021, 12, "M12", "monthCode M12 with overflow constrain"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-invalid-string.js new file mode 100644 index 0000000000..126567df64 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-invalid-string.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.calendar.prototype.yearmonthfromfields +description: RangeError thrown when overflow 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-totemporaloverflow step 1: + 1. Return ? GetOption(_normalizedOptions_, *"overflow"*, « String », « *"constrain"*, *"reject"* », *"constrain"*). + sec-temporal-isoyearmonthfromfields step 2: + 2. Let _overflow_ be ? ToTemporalOverflow(_options_). + sec-temporal.calendar.prototype.yearmonthfromfields step 6: + 6. Let _result_ be ? ISOYearMonthFromFields(_fields_, _options_). +features: [Temporal] +---*/ + +const calendar = new Temporal.Calendar("iso8601"); +const badOverflows = ["", "CONSTRAIN", "balance", "other string", "constra\u0131n", "reject\0"]; +for (const overflow of badOverflows) { + assert.throws( + RangeError, + () => calendar.yearMonthFromFields({ year: 2000, month: 5 }, { overflow }), + `invalid overflow ("${overflow}")` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-reject.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-reject.js new file mode 100644 index 0000000000..579c4969e4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-reject.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.yearmonthfromfields +description: Throw RangeError for input data out of range with overflow reject +info: | + 1. Let calendar be the this value. + 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]). + 3. Assert: calendar.[[Identifier]] is "iso8601". + 4. If Type(fields) is not Object, throw a TypeError exception. + 5. Set options to ? GetOptionsObject(options). + 6. Let result be ? ISOYearMonthFromFields(fields, options). + 7. Return ? CreateTemporalYearMonth(result.[[Year]], result.[[Month]], calendar, result.[[ReferenceISODay]]). +features: [Temporal] +---*/ + +const cal = new Temporal.Calendar("iso8601"); + +[-1, 0, 13, 9995].forEach((month) => { + assert.throws( + RangeError, + () => cal.yearMonthFromFields({year: 2021, month, day: 5}, { overflow: "reject" }), + `Month ${month} is out of range for 2021 with overflow: reject` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-undefined.js new file mode 100644 index 0000000000..fa60c3db4b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-undefined.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.calendar.prototype.yearmonthfromfields +description: Fallback value for overflow option +info: | + sec-getoption step 3: + 3. If _value_ is *undefined*, return _fallback_. + sec-temporal-totemporaloverflow step 1: + 1. Return ? GetOption(_normalizedOptions_, *"overflow"*, « String », « *"constrain"*, *"reject"* », *"constrain"*). + sec-temporal-isoyearmonthfromfields step 2: + 2. Let _overflow_ be ? ToTemporalOverflow(_options_). + sec-temporal.calendar.prototype.yearmonthfromfields step 6: + 6. Let _result_ be ? ISOYearMonthFromFields(_fields_, _options_). +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = new Temporal.Calendar("iso8601"); + +const explicit = calendar.yearMonthFromFields({ year: 2000, month: 15 }, { overflow: undefined }); +TemporalHelpers.assertPlainYearMonth(explicit, 2000, 12, "M12", "default overflow is constrain"); +const implicit = calendar.yearMonthFromFields({ year: 2000, month: 15 }, {}); +TemporalHelpers.assertPlainYearMonth(implicit, 2000, 12, "M12", "default overflow is constrain"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-wrong-type.js new file mode 100644 index 0000000000..5cdf0b1c55 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-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.calendar.prototype.yearmonthfromfields +description: Type conversions for overflow option +info: | + sec-getoption step 9.a: + a. Set _value_ to ? ToString(_value_). + sec-temporal-totemporaloverflow step 1: + 1. Return ? GetOption(_normalizedOptions_, *"overflow"*, « String », « *"constrain"*, *"reject"* », *"constrain"*). + sec-temporal-isoyearmonthfromfields step 2: + 2. Let _overflow_ be ? ToTemporalOverflow(_options_). + sec-temporal.calendar.prototype.yearmonthfromfields step 6: + 6. Let _result_ be ? ISOYearMonthFromFields(_fields_, _options_). +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = new Temporal.Calendar("iso8601"); +TemporalHelpers.checkStringOptionWrongType("overflow", "constrain", + (overflow) => calendar.yearMonthFromFields({ year: 2000, month: 5 }, { overflow }), + (result, descr) => TemporalHelpers.assertPlainYearMonth(result, 2000, 5, "M05", descr), +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/prop-desc.js new file mode 100644 index 0000000000..95d5bca68c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/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.calendar.prototype.yearmonthfromfields +description: The "yearMonthFromFields" property of Temporal.Calendar.prototype +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.Calendar.prototype.yearMonthFromFields, + "function", + "`typeof Calendar.prototype.yearMonthFromFields` is `function`" +); + +verifyProperty(Temporal.Calendar.prototype, "yearMonthFromFields", { + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/reference-day.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/reference-day.js new file mode 100644 index 0000000000..9a8a517fd0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/reference-day.js @@ -0,0 +1,41 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.yearmonthfromfields +description: Reference ISO day is chosen to be the first of the calendar month +info: | + 6.d. Perform ! CreateDataPropertyOrThrow(_fields_, *"day"*, *1*<sub>𝔽</sub>). + e. Let _result_ be ? CalendarDateToISO(_calendar_.[[Identifier]], _fields_, _options_). +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const cal = new Temporal.Calendar("iso8601"); + +const result1 = cal.yearMonthFromFields({ year: 2023, monthCode: "M01", day: 13 }); +TemporalHelpers.assertPlainYearMonth( + result1, + 2023, 1, "M01", + "reference day is 1 even if day is given", + /* era = */ undefined, /* era year = */ undefined, /* reference day = */ 1 +); + +const result2 = cal.yearMonthFromFields({ year: 2021, monthCode: "M02", day: 50 }, { overflow: "constrain" }); +TemporalHelpers.assertPlainYearMonth( + result2, + 2021, 2, "M02", + "reference day is 1 even if day is out of range (overflow constrain)", + /* era = */ undefined, /* era year = */ undefined, /* reference day = */ 1 +); + +const result3 = cal.yearMonthFromFields({ year: 2021, monthCode: "M02", day: 50 }, { overflow: "reject" }); +TemporalHelpers.assertPlainYearMonth( + result3, + 2021, 2, "M02", + "reference day is 1 even if day is out of range (overflow reject)", + /* era = */ undefined, /* era year = */ undefined, /* reference day = */ 1 +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/shell.js new file mode 100644 index 0000000000..eda1477282 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/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/Calendar/prototype/yearOfWeek/argument-calendar-datefromfields-called-with-null-prototype-fields.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-calendar-datefromfields-called-with-null-prototype-fields.js new file mode 100644 index 0000000000..a48392ac3c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-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.calendar.prototype.yearofweek +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.Calendar("iso8601"); +const arg = { year: 2000, month: 5, day: 2, calendar }; +instance.yearOfWeek(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/Calendar/prototype/yearOfWeek/argument-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-leap-second.js new file mode 100644 index 0000000000..88665ba1af --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-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.calendar.prototype.yearofweek +description: Leap second is a valid ISO string for PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.yearOfWeek(arg); +assert.sameValue( + result1, + 2016, + "leap second is a valid ISO string for PlainDate" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.yearOfWeek(arg); +assert.sameValue( + result2, + 2016, + "second: 60 is ignored in property bag for PlainDate" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-number.js new file mode 100644 index 0000000000..0ced166011 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/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.calendar.prototype.yearofweek +description: A number is converted to a string, then to Temporal.PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const arg = 19761118; + +const result = instance.yearOfWeek(arg); +assert.sameValue(result, 1976, "19761118 is a valid ISO string for PlainDate"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.yearOfWeek(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-case-insensitive.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-case-insensitive.js new file mode 100644 index 0000000000..2dbacb58f0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/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.calendar.prototype.yearofweek +description: The calendar name is case-insensitive +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "IsO8601"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.yearOfWeek(arg); +assert.sameValue(result1, 1976, "Calendar is case-insensitive"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.yearOfWeek(arg); +assert.sameValue(result2, 1976, "Calendar is case-insensitive (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-instance-does-not-get-calendar-property.js new file mode 100644 index 0000000000..994289b36c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/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.calendar.prototype.yearofweek +description: > + A Temporal.Calendar instance passed to yearOfWeek() in a property bag does + not have its 'calendar' property observably checked +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +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.yearOfWeek(arg); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +instance.yearOfWeek(arg); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-leap-second.js new file mode 100644 index 0000000000..6337db75ef --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/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.calendar.prototype.yearofweek +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.yearOfWeek(arg); +assert.sameValue( + result1, + 1976, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.yearOfWeek(arg); +assert.sameValue( + result2, + 1976, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-number.js new file mode 100644 index 0000000000..1c7cc915f9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/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.calendar.prototype.yearofweek +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.yearOfWeek(arg); +assert.sameValue(result1, 1976, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.yearOfWeek(arg); +assert.sameValue(result2, 1976, "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.yearOfWeek(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.yearOfWeek(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/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-string.js new file mode 100644 index 0000000000..f9be116860 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/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.calendar.prototype.yearofweek +description: A calendar ID is valid input for Calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "iso8601"; + +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.yearOfWeek(arg); +assert.sameValue(result, 1976, `Calendar created from string "${calendar}"`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 0000000000..5ece042150 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/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.calendar.prototype.yearofweek +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.Calendar("iso8601"); + +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.yearOfWeek(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.yearOfWeek(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.yearOfWeek(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.yearOfWeek(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.yearOfWeek(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-year-zero.js new file mode 100644 index 0000000000..615aa87990 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/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.calendar.prototype.yearofweek +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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.yearOfWeek(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-calendar-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-calendar-annotation.js new file mode 100644 index 0000000000..9f9a077390 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/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.calendar.prototype.yearofweek +description: Various forms of calendar annotation; critical flag has no effect +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02[u-ca=iso8601]", "without time or time zone"], + ["2000-05-02[UTC][u-ca=iso8601]", "with time zone and no time"], + ["2000-05-02T15:23[u-ca=iso8601]", "without time zone"], + ["2000-05-02T15:23[UTC][u-ca=iso8601]", "with time zone"], + ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], + ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], + ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], + ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.yearOfWeek(arg); + + assert.sameValue( + result, + 2000, + `calendar annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-critical-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-critical-unknown-annotation.js new file mode 100644 index 0000000000..7f6e79a888 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-critical-unknown-annotation.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.calendar.prototype.yearofweek +description: Unknown annotations with critical flag are rejected +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[!foo=bar]", + "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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.yearOfWeek(arg), + `reject unknown annotation with critical flag: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-date-with-utc-offset.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-date-with-utc-offset.js new file mode 100644 index 0000000000..ab4e573498 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/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.calendar.prototype.yearofweek +description: UTC offset not valid with format that does not include a time +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const validStrings = [ + "2000-05-02T00+00:00", + "2000-05-02T00+00:00[UTC]", + "2000-05-02T00+00:00[!UTC]", + "2000-05-02T00-02:30[America/St_Johns]", +]; + +for (const arg of validStrings) { + const result = instance.yearOfWeek(arg); + + assert.sameValue( + result, + 2000, + `"${arg}" is a valid UTC offset with time for PlainDate` + ); +} + +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.yearOfWeek(arg), + `"${arg}" UTC offset without time is not valid for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-invalid.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-invalid.js new file mode 100644 index 0000000000..835dba81b0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-invalid.js @@ -0,0 +1,64 @@ +// |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.calendar.prototype.yearofweek +description: > + RangeError thrown if an invalid ISO string (or syntactically valid ISO string + that is not supported) is used as a PlainDate +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + // invalid ISO strings: + "", + "invalid iso8601", + "2020-01-00", + "2020-01-32", + "2020-02-30", + "2021-02-29", + "2020-00-01", + "2020-13-01", + "2020-01-01T", + "2020-01-01T25:00:00", + "2020-01-01T01:60:00", + "2020-01-01T01:60:61", + "2020-01-01junk", + "2020-01-01T00:00:00junk", + "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-01", + "2020-001-01", + "2020-01-001", + "2020-01-01T001", + "2020-01-01T01:001", + "2020-01-01T01:01:001", + // valid, but forms not supported in Temporal: + "2020-W01-1", + "2020-001", + "+0002020-01-01", + // valid, but this calendar must not exist: + "2020-01-01[u-ca=notexist]", + // may be valid in other contexts, but insufficient information for PlainDate: + "2020-01", + "+002020-01", + "01-01", + "2020-W01", + "P1Y", + "-P12Y", + // valid, but outside the supported range: + "-999999-01-01", + "+999999-01-01", +]; +const instance = new Temporal.Calendar("iso8601"); +for (const arg of invalidStrings) { + assert.throws( + RangeError, + () => instance.yearOfWeek(arg), + `"${arg}" should not be a valid ISO string for a PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-multiple-time-zone.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-multiple-time-zone.js new file mode 100644 index 0000000000..130e6e26c0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-multiple-time-zone.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.calendar.prototype.yearofweek +description: More than one time zone annotation is not syntactical +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[UTC][UTC]", + "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.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.yearOfWeek(arg), + `reject more than one time zone annotation: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-time-separators.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-time-separators.js new file mode 100644 index 0000000000..929d36ea2d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/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.calendar.prototype.yearofweek +description: Time separator in string argument can vary +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02T15:23", "uppercase T"], + ["2000-05-02t15:23", "lowercase T"], + ["2000-05-02 15:23", "space between date and time"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.yearOfWeek(arg); + + assert.sameValue( + result, + 2000, + `variant time separators (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-time-zone-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-time-zone-annotation.js new file mode 100644 index 0000000000..b4de797987 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-time-zone-annotation.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.calendar.prototype.yearofweek +description: Various forms of time zone annotation; critical flag has no effect +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02[Asia/Kolkata]", "named, with no time"], + ["2000-05-02[!Europe/Vienna]", "named, with ! and no time"], + ["2000-05-02[+00:00]", "numeric, with no time"], + ["2000-05-02[!-02:30]", "numeric, with ! and no time"], + ["2000-05-02T15:23[America/Sao_Paulo]", "named, with no offset"], + ["2000-05-02T15:23[!Asia/Tokyo]", "named, with ! and no offset"], + ["2000-05-02T15:23[-02:30]", "numeric, with no offset"], + ["2000-05-02T15:23[!+00:00]", "numeric, with ! and no offset"], + ["2000-05-02T15:23+00:00[America/New_York]", "named, with offset"], + ["2000-05-02T15:23+00:00[!UTC]", "named, with offset and !"], + ["2000-05-02T15:23+00:00[+01:00]", "numeric, with offset"], + ["2000-05-02T15:23+00:00[!-08:00]", "numeric, with offset and !"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.yearOfWeek(arg); + + assert.sameValue( + result, + 2000, + `time zone annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-unknown-annotation.js new file mode 100644 index 0000000000..c28d7532d2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/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.calendar.prototype.yearofweek +description: Various forms of unknown annotation +features: [Temporal] +---*/ + +const tests = [ + ["2000-05-02[foo=bar]", "without time"], + ["2000-05-02T15:23[foo=bar]", "alone"], + ["2000-05-02T15:23[UTC][foo=bar]", "with time zone"], + ["2000-05-02T15:23[u-ca=iso8601][foo=bar]", "with calendar"], + ["2000-05-02T15:23[UTC][foo=bar][u-ca=iso8601]", "with time zone and calendar"], + ["2000-05-02T15:23[foo=bar][_foo-bar0=Ignore-This-999999999999]", "with another unknown annotation"], +]; + +const instance = new Temporal.Calendar("iso8601"); + +tests.forEach(([arg, description]) => { + const result = instance.yearOfWeek(arg); + + assert.sameValue( + result, + 2000, + `unknown annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-with-utc-designator.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-with-utc-designator.js new file mode 100644 index 0000000000..1d0807eec4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-with-utc-designator.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.calendar.prototype.yearofweek +description: RangeError thrown if a string with UTC designator is used as a PlainDate +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "2019-10-01T09:00:00Z", + "2019-10-01T09:00:00Z[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.yearOfWeek(arg), + "String with UTC designator should not be valid as a PlainDate" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string.js new file mode 100644 index 0000000000..c2da0ac7de --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string.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.calendar.prototype.yearofweek +description: > + Temporal.Calendar.prototype.yearOfWeek will take an ISO 8601 date string and + return the ISO week calendar year of that date. +features: [Temporal] +---*/ + +const cal = new Temporal.Calendar("iso8601"); + +// The following week calendar years are taken from the table "Examples of +// contemporary dates around New Year's Day" from +// https://en.wikipedia.org/wiki/ISO_week_date#Relation_with_the_Gregorian_calendar + +assert.sameValue(cal.yearOfWeek("1977-01-01"), 1976, "1977-01-01 is in yearOfWeek 1976"); +assert.sameValue(cal.yearOfWeek("1977-01-02"), 1976, "1977-01-02 is in yearOfWeek 1976"); +assert.sameValue(cal.yearOfWeek("1977-12-31"), 1977, "1977-12-31 is in yearOfWeek 1977"); +assert.sameValue(cal.yearOfWeek("1978-01-01"), 1977, "1978-01-01 is in yearOfWeek 1977"); +assert.sameValue(cal.yearOfWeek("1978-01-02"), 1978, "1978-01-02 is in yearOfWeek 1978"); +assert.sameValue(cal.yearOfWeek("1978-12-31"), 1978, "1978-12-31 is in yearOfWeek 1978"); +assert.sameValue(cal.yearOfWeek("1979-01-01"), 1979, "1979-01-01 is in yearOfWeek 1979"); +assert.sameValue(cal.yearOfWeek("1979-12-30"), 1979, "1979-12-30 is in yearOfWeek 1979"); +assert.sameValue(cal.yearOfWeek("1979-12-31"), 1980, "1979-12-31 is in yearOfWeek 1980"); +assert.sameValue(cal.yearOfWeek("1980-01-01"), 1980, "1980-01-01 is in yearOfWeek 1980"); +assert.sameValue(cal.yearOfWeek("1980-12-28"), 1980, "1980-12-28 is in yearOfWeek 1980"); +assert.sameValue(cal.yearOfWeek("1980-12-29"), 1981, "1980-12-29 is in yearOfWeek 1981"); +assert.sameValue(cal.yearOfWeek("1980-12-30"), 1981, "1980-12-30 is in yearOfWeek 1981"); +assert.sameValue(cal.yearOfWeek("1980-12-31"), 1981, "1980-12-31 is in yearOfWeek 1981"); +assert.sameValue(cal.yearOfWeek("1981-01-01"), 1981, "1981-01-01 is in yearOfWeek 1981"); +assert.sameValue(cal.yearOfWeek("1981-12-31"), 1981, "1981-12-31 is in yearOfWeek 1981"); +assert.sameValue(cal.yearOfWeek("1982-01-01"), 1981, "1982-01-01 is in yearOfWeek 1981"); +assert.sameValue(cal.yearOfWeek("1982-01-02"), 1981, "1982-01-02 is in yearOfWeek 1981"); +assert.sameValue(cal.yearOfWeek("1982-01-03"), 1981, "1982-01-03 is in yearOfWeek 1981"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-wrong-type.js new file mode 100644 index 0000000000..c380a659e8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/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.calendar.prototype.yearofweek +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +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.yearOfWeek(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.yearOfWeek(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/Calendar/prototype/yearOfWeek/argument-zoneddatetime-convert.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-convert.js new file mode 100644 index 0000000000..8e2e4ac05a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-convert.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.calendar.prototype.yearofweek +description: An exception from TimeZone#getOffsetNanosecondsFor() is propagated. +features: [Temporal] +---*/ + +class TZ extends Temporal.TimeZone { + constructor() { super("UTC") } + getOffsetNanosecondsFor() { throw new Test262Error() } +} + +const tz = new TZ(); +const arg = new Temporal.ZonedDateTime(0n, tz); +const instance = new Temporal.Calendar("iso8601"); + +assert.throws(Test262Error, () => instance.yearOfWeek(arg)); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-slots.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-slots.js new file mode 100644 index 0000000000..9b575e8f80 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-slots.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.calendar.prototype.yearofweek +description: Getters are not called when converting a ZonedDateTime to a PlainDate. +includes: [compareArray.js] +features: [Temporal] +---*/ + +const actual = []; +const prototypeDescrs = Object.getOwnPropertyDescriptors(Temporal.ZonedDateTime.prototype); +const getters = ["year", "month", "monthCode", "day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond", "calendar"]; + +for (const property of getters) { + Object.defineProperty(Temporal.ZonedDateTime.prototype, property, { + get() { + actual.push(`get ${property}`); + const value = prototypeDescrs[property].get.call(this); + return { + toString() { + actual.push(`toString ${property}`); + return value.toString(); + }, + valueOf() { + actual.push(`valueOf ${property}`); + return value; + }, + }; + }, + }); +} + +const arg = new Temporal.ZonedDateTime(0n, "UTC"); +const instance = new Temporal.Calendar("iso8601"); +instance.yearOfWeek(arg); +assert.compareArray(actual, []); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js new file mode 100644 index 0000000000..3eed9b18b2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.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.calendar.prototype.yearofweek +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(RangeError, () => calendar.yearOfWeek(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js new file mode 100644 index 0000000000..546d6ec4bc --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.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.calendar.prototype.yearofweek +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + timeZone.getOffsetNanosecondsFor = notCallable; + assert.throws( + TypeError, + () => calendar.yearOfWeek(datetime), + `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js new file mode 100644 index 0000000000..c6556ce338 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.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.calendar.prototype.yearofweek +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(RangeError, () => calendar.yearOfWeek(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js new file mode 100644 index 0000000000..30e6709ab8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.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.calendar.prototype.yearofweek +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 calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + assert.throws(TypeError, () => calendar.yearOfWeek(datetime)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/basic.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/basic.js new file mode 100644 index 0000000000..566e872c58 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/basic.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.calendar.prototype.yearofweek +description: Basic tests for yearOfWeek(). +features: [Temporal] +---*/ + +const iso = Temporal.Calendar.from("iso8601"); +const res = 1994; +assert.sameValue(iso.yearOfWeek(Temporal.PlainDate.from("1994-11-05")), res, "PlainDate"); +assert.sameValue(iso.yearOfWeek(Temporal.PlainDateTime.from("1994-11-05T08:15:30")), res, "PlainDateTime"); +assert.sameValue(iso.yearOfWeek({ year: 1994, month: 11, day: 5 }), res, "property bag"); +assert.sameValue(iso.yearOfWeek("1994-11-05"), res, "string"); +assert.throws(TypeError, () => iso.yearOfWeek({ year: 2000 }), "property bag with missing properties"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/branding.js new file mode 100644 index 0000000000..cf7010dce5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/branding.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.calendar.prototype.yearofweek +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const yearOfWeek = Temporal.Calendar.prototype.yearOfWeek; + +assert.sameValue(typeof yearOfWeek, "function"); + +const args = [new Temporal.PlainDate(2021, 7, 20)]; + +assert.throws(TypeError, () => yearOfWeek.apply(undefined, args), "undefined"); +assert.throws(TypeError, () => yearOfWeek.apply(null, args), "null"); +assert.throws(TypeError, () => yearOfWeek.apply(true, args), "true"); +assert.throws(TypeError, () => yearOfWeek.apply("", args), "empty string"); +assert.throws(TypeError, () => yearOfWeek.apply(Symbol(), args), "symbol"); +assert.throws(TypeError, () => yearOfWeek.apply(1, args), "1"); +assert.throws(TypeError, () => yearOfWeek.apply({}, args), "plain object"); +assert.throws(TypeError, () => yearOfWeek.apply(Temporal.Calendar, args), "Temporal.Calendar"); +assert.throws(TypeError, () => yearOfWeek.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/builtin.js new file mode 100644 index 0000000000..48c242c032 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/builtin.js @@ -0,0 +1,36 @@ +// |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.calendar.prototype.yearofweek +description: > + Tests that Temporal.Calendar.prototype.yearOfWeek + 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.Calendar.prototype.yearOfWeek), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.yearOfWeek), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.yearOfWeek), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.Calendar.prototype.yearOfWeek.hasOwnProperty("prototype"), + false, "prototype property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/calendar-datefromfields-called-with-options-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/calendar-datefromfields-called-with-options-undefined.js new file mode 100644 index 0000000000..0300eec749 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/calendar-datefromfields-called-with-options-undefined.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.calendar.prototype.yearofweek +description: > + Calendar.dateFromFields method is called with undefined as the options value + when call originates internally +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = TemporalHelpers.calendarFromFieldsUndefinedOptions(); +calendar.yearOfWeek({ year: 2000, month: 5, day: 3, calendar }); +assert.sameValue(calendar.dateFromFieldsCallCount, 1); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/calendar-fields-iterable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/calendar-fields-iterable.js new file mode 100644 index 0000000000..1a415b440e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/calendar-fields-iterable.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.calendar.prototype.yearofweek +description: Verify the result of calendar.fields() is treated correctly. +info: | + sec-temporal.calendar.prototype.yearofweek step 4: + 4. Let _date_ be ? ToTemporalDate(_dateOrDateTime_). + sec-temporal-totemporaldate step 2.c: + c. Let _fieldNames_ be ? CalendarFields(_calendar_, « *"day"*, *"month"*, *"monthCode"*, *"year"* »). + sec-temporal-calendarfields step 4: + 4. Let _result_ be ? IterableToListOfType(_fieldsArray_, « String »). +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + "day", + "month", + "monthCode", + "year", +]; + +const calendar1 = TemporalHelpers.calendarFieldsIterable(); +const calendar2 = TemporalHelpers.calendarFieldsIterable(); +calendar1.yearOfWeek({ year: 2000, month: 5, day: 2, calendar: calendar2 }); + +assert.sameValue(calendar1.fieldsCallCount, 0, "fields() method not called"); +assert.sameValue(calendar2.fieldsCallCount, 1, "fields() method called once"); +assert.compareArray(calendar2.fieldsCalledWith[0], expected, "fields() method called with correct args"); +assert(calendar2.iteratorExhausted[0], "iterated through the whole iterable"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/calendar-temporal-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/calendar-temporal-object.js new file mode 100644 index 0000000000..1a7c8dc880 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/calendar-temporal-object.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.calendar.prototype.yearofweek +description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots +info: | + sec-temporal.calendar.prototype.yearofweek step 4: + 4. Let _date_ be ? ToTemporalDate(_dateOrDateTime_). + sec-temporal-totemporaldate 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 calendar = new Temporal.Calendar("iso8601"); + calendar.yearOfWeek({ year: 2000, month: 5, day: 2, calendar: temporalObject }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/cross-year.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/cross-year.js new file mode 100644 index 0000000000..d3baa73f29 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/cross-year.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.calendar.prototype.yearOfWeek +description: yearOfWeek() where the result is different from the calendar year +features: [Temporal] +---*/ + +const iso = Temporal.Calendar.from("iso8601"); +assert.sameValue(iso.yearOfWeek(Temporal.PlainDate.from("2019-12-31")), 2020, "next year"); +assert.sameValue(iso.yearOfWeek(Temporal.PlainDate.from("2021-01-01")), 2020, "previous year"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/infinity-throws-rangeerror.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/infinity-throws-rangeerror.js new file mode 100644 index 0000000000..6c0af7f7b9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/infinity-throws-rangeerror.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. + +/*--- +description: Throws if any value in the property bag is Infinity or -Infinity +esid: sec-temporal.calendar.prototype.yearofweek +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); +const base = { year: 2000, month: 5, day: 2 }; + +[Infinity, -Infinity].forEach((inf) => { + ["year", "month", "day"].forEach((prop) => { + assert.throws(RangeError, () => instance.yearOfWeek({ ...base, [prop]: inf }), `${prop} property cannot be ${inf}`); + + const calls = []; + const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop); + assert.throws(RangeError, () => instance.yearOfWeek({ ...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/Calendar/prototype/yearOfWeek/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/length.js new file mode 100644 index 0000000000..873f4caa50 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/length.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.calendar.prototype.yearofweek +description: Temporal.Calendar.prototype.yearOfWeek.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.Calendar.prototype.yearOfWeek, "length", { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/name.js new file mode 100644 index 0000000000..e932b4dc56 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/name.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.calendar.prototype.yearofweek +description: Temporal.Calendar.prototype.yearOfWeek.name is "yearOfWeek". +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.Calendar.prototype.yearOfWeek, "name", { + value: "yearOfWeek", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/not-a-constructor.js new file mode 100644 index 0000000000..9943d9d656 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/not-a-constructor.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.calendar.prototype.yearofweek +description: > + Temporal.Calendar.prototype.yearOfWeek 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.Calendar.prototype.yearOfWeek(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.Calendar.prototype.yearOfWeek), false, + "isConstructor(Temporal.Calendar.prototype.yearOfWeek)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/prop-desc.js new file mode 100644 index 0000000000..4448687f4c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/prop-desc.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.calendar.prototype.yearofweek +description: The "yearOfWeek" property of Temporal.Calendar.prototype +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.Calendar.prototype.yearOfWeek, + "function", + "`typeof Calendar.prototype.yearOfWeek` is `function`" +); + +verifyProperty(Temporal.Calendar.prototype, "yearOfWeek", { + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/shell.js new file mode 100644 index 0000000000..eda1477282 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/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/Calendar/prototype/yearOfWeek/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/year-zero.js new file mode 100644 index 0000000000..1287b7888b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/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.calendar.prototype.yearofweek +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.yearOfWeek(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/shell.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/shell.js diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/subclass.js b/js/src/tests/test262/built-ins/Temporal/Calendar/subclass.js new file mode 100644 index 0000000000..f7d4fdd6e1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/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.calendar +description: Test for Temporal.Calendar subclassing. +features: [Temporal] +---*/ + +class CustomCalendar extends Temporal.Calendar { +} + +const instance = new CustomCalendar("iso8601"); +assert.sameValue(instance.toString(), "iso8601"); +assert.sameValue(Object.getPrototypeOf(instance), CustomCalendar.prototype, "Instance of CustomCalendar"); +assert(instance instanceof CustomCalendar, "Instance of CustomCalendar"); +assert(instance instanceof Temporal.Calendar, "Instance of Temporal.Calendar"); + +reportCompare(0, 0); |