diff options
Diffstat (limited to 'js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime')
40 files changed, 1252 insertions, 0 deletions
diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-number.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-number.js new file mode 100644 index 0000000000..3c363713a3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-number.js @@ -0,0 +1,28 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaintime +description: A number is invalid in place of an ISO string for Temporal.PlainTime +features: [Temporal] +---*/ + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); + +const numbers = [ + 1, + -123456.987654321, + 1234567, + 123456.9876543219, +]; + +for (const arg of numbers) { + assert.throws( + TypeError, + () => instance.withPlainTime(arg), + `A number (${arg}) is not a valid ISO string for PlainTime` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-calendar-annotation.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-calendar-annotation.js new file mode 100644 index 0000000000..a052bf77e8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-calendar-annotation.js @@ -0,0 +1,43 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaintime +description: Various forms of calendar annotation; critical flag has no effect +features: [Temporal] +---*/ + +const tests = [ + ["12:34:56.987654321[u-ca=iso8601]", "without time zone"], + ["12:34:56.987654321[UTC][u-ca=iso8601]", "with time zone"], + ["12:34:56.987654321[!u-ca=iso8601]", "with ! and no time zone"], + ["12:34:56.987654321[UTC][!u-ca=iso8601]", "with ! and time zone"], + ["T12:34:56.987654321[u-ca=iso8601]", "with T and no time zone"], + ["T12:34:56.987654321[UTC][u-ca=iso8601]", "with T and time zone"], + ["T12:34:56.987654321[!u-ca=iso8601]", "with T, !, and no time zone"], + ["T12:34:56.987654321[UTC][!u-ca=iso8601]", "with T, !, and time zone"], + ["1970-01-01T12:34:56.987654321[u-ca=iso8601]", "with date and no time zone"], + ["1970-01-01T12:34:56.987654321[UTC][u-ca=iso8601]", "with date and time zone"], + ["1970-01-01T12:34:56.987654321[!u-ca=iso8601]", "with !, date, and no time zone"], + ["1970-01-01T12:34:56.987654321[UTC][!u-ca=iso8601]", "with !, date, and time zone"], + ["12:34:56.987654321[u-ca=hebrew]", "calendar annotation ignored"], + ["12:34:56.987654321[u-ca=unknown]", "calendar annotation ignored even if unknown calendar"], + ["12:34:56.987654321[!u-ca=unknown]", "calendar annotation ignored even if unknown calendar with !"], + ["1970-01-01T12:34:56.987654321[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], +]; + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.ZonedDateTime(0n, timeZone); + +tests.forEach(([arg, description]) => { + const result = instance.withPlainTime(arg); + + assert.sameValue( + result.epochNanoseconds, + 45_296_987_654_321n, + `calendar annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-critical-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-critical-unknown-annotation.js new file mode 100644 index 0000000000..231cb49b0b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-critical-unknown-annotation.js @@ -0,0 +1,30 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaintime +description: Unknown annotations with critical flag are rejected +features: [Temporal] +---*/ + +const invalidStrings = [ + "00:00[!foo=bar]", + "T00:00[!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 timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.ZonedDateTime(0n, timeZone); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.withPlainTime(arg), + `reject unknown annotation with critical flag: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-date-with-utc-offset.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-date-with-utc-offset.js new file mode 100644 index 0000000000..b59e9c1079 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-date-with-utc-offset.js @@ -0,0 +1,53 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaintime +description: UTC offset not valid with format that does not include a time +features: [Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.ZonedDateTime(0n, timeZone); + +const validStrings = [ + "12:34:56.987654321+00:00", + "12:34:56.987654321+00:00[UTC]", + "12:34:56.987654321+00:00[!UTC]", + "12:34:56.987654321-02:30[America/St_Johns]", + "1976-11-18T12:34:56.987654321+00:00", + "1976-11-18T12:34:56.987654321+00:00[UTC]", + "1976-11-18T12:34:56.987654321+00:00[!UTC]", + "1976-11-18T12:34:56.987654321-02:30[America/St_Johns]", +]; + +for (const arg of validStrings) { + const result = instance.withPlainTime(arg); + + assert.sameValue( + result.epochNanoseconds, + 45_296_987_654_321n, + `"${arg}" is a valid UTC offset with time for PlainTime` + ); +} + +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.withPlainTime(arg), + `"${arg}" UTC offset without time is not valid for PlainTime` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-multiple-calendar.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-multiple-calendar.js new file mode 100644 index 0000000000..7997635a90 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-multiple-calendar.js @@ -0,0 +1,33 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// 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.zoneddatetime.prototype.withplaintime +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "00:00[u-ca=iso8601][!u-ca=iso8601]", + "00:00[!u-ca=iso8601][u-ca=iso8601]", + "00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.ZonedDateTime(0n, timeZone); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.withPlainTime(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-multiple-time-zone.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-multiple-time-zone.js new file mode 100644 index 0000000000..731ce895a2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-multiple-time-zone.js @@ -0,0 +1,30 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaintime +description: More than one time zone annotation is not syntactical +features: [Temporal] +---*/ + +const invalidStrings = [ + "00:00[UTC][UTC]", + "T00:00[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 timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.ZonedDateTime(0n, timeZone); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.withPlainTime(arg), + `reject more than one time zone annotation: ${arg}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-no-implicit-midnight.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-no-implicit-midnight.js new file mode 100644 index 0000000000..4f2f77be0a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-no-implicit-midnight.js @@ -0,0 +1,19 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaintime +description: RangeError thrown if a date-only string is passed in a PlainTime context +features: [Temporal, arrow-function] +---*/ + +const arg = "2019-10-01"; +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); +assert.throws( + RangeError, + () => instance.withPlainTime(arg), + "Date-only string throws, does not implicitly convert to midnight" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-time-designator-required-for-disambiguation.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-time-designator-required-for-disambiguation.js new file mode 100644 index 0000000000..51e897a340 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-time-designator-required-for-disambiguation.js @@ -0,0 +1,37 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaintime +description: ISO 8601 time designator "T" required in cases of ambiguity +includes: [temporalHelpers.js] +features: [Temporal, arrow-function] +---*/ + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); + +TemporalHelpers.ISO.plainTimeStringsAmbiguous().forEach((string) => { + let arg = string; + assert.throws( + RangeError, + () => instance.withPlainTime(arg), + `'${arg}' is ambiguous and requires T prefix` + ); + // The same string with a T prefix should not throw: + arg = `T${string}`; + instance.withPlainTime(arg); + + arg = ` ${string}`; + assert.throws( + RangeError, + () => instance.withPlainTime(arg), + `space is not accepted as a substitute for T prefix: '${arg}'` + ); +}); + +// None of these should throw without a T prefix, because they are unambiguously time strings: +TemporalHelpers.ISO.plainTimeStringsUnambiguous().forEach( + (arg) => instance.withPlainTime(arg)); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-time-separators.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-time-separators.js new file mode 100644 index 0000000000..4698f39f6c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-time-separators.js @@ -0,0 +1,32 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaintime +description: Time separator in string argument can vary +features: [Temporal] +---*/ + +const tests = [ + ["1976-11-18T12:34:56.987654321", "uppercase T"], + ["1976-11-18t12:34:56.987654321", "lowercase T"], + ["1976-11-18 12:34:56.987654321", "space between date and time"], + ["T12:34:56.987654321", "time-only uppercase T"], + ["t12:34:56.987654321", "time-only lowercase T"], +]; + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.ZonedDateTime(0n, timeZone); + +tests.forEach(([arg, description]) => { + const result = instance.withPlainTime(arg); + + assert.sameValue( + result.epochNanoseconds, + 45_296_987_654_321n, + `variant time separators (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-time-zone-annotation.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-time-zone-annotation.js new file mode 100644 index 0000000000..b861c603cd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-time-zone-annotation.js @@ -0,0 +1,51 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaintime +description: Various forms of time zone annotation; critical flag has no effect +features: [Temporal] +---*/ + +const tests = [ + ["12:34:56.987654321[Asia/Kolkata]", "named, with no offset"], + ["12:34:56.987654321[!Europe/Vienna]", "named, with ! and no offset"], + ["12:34:56.987654321[+00:00]", "numeric, with no offset"], + ["12:34:56.987654321[!-02:30]", "numeric, with ! and no offset"], + ["T12:34:56.987654321[UTC]", "named, with T and no offset"], + ["T12:34:56.987654321[!Africa/Abidjan]", "named, with T, !, and no offset"], + ["T12:34:56.987654321[+01:00]", "numeric, with T and no offset"], + ["T12:34:56.987654321[!-08:00]", "numeric, with T, !, and no offset"], + ["12:34:56.987654321+00:00[America/Sao_Paulo]", "named, with offset"], + ["12:34:56.987654321+00:00[!Asia/Tokyo]", "named, with ! and offset"], + ["12:34:56.987654321+00:00[-02:30]", "numeric, with offset"], + ["12:34:56.987654321+00:00[!+00:00]", "numeric, with ! and offset"], + ["T12:34:56.987654321+00:00[America/New_York]", "named, with T and offset"], + ["T12:34:56.987654321+00:00[!UTC]", "named, with T, !, and offset"], + ["T12:34:56.987654321+00:00[-08:00]", "numeric, with T and offset"], + ["T12:34:56.987654321+00:00[!+01:00]", "numeric, with T, !, and offset"], + ["1970-01-01T12:34:56.987654321[Africa/Lagos]", "named, with date and no offset"], + ["1970-01-01T12:34:56.987654321[!America/Vancouver]", "named, with date, !, and no offset"], + ["1970-01-01T12:34:56.987654321[+00:00]", "numeric, with date and no offset"], + ["1970-01-01T12:34:56.987654321[!-02:30]", "numeric, with date, !, and no offset"], + ["1970-01-01T12:34:56.987654321+00:00[Europe/London]", "named, with date and offset"], + ["1970-01-01T12:34:56.987654321+00:00[!Asia/Seoul]", "named, with date, offset, and !"], + ["1970-01-01T12:34:56.987654321+00:00[+01:00]", "numeric, with date and offset"], + ["1970-01-01T12:34:56.987654321+00:00[!-08:00]", "numeric, with date, offset, and !"], +]; + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.ZonedDateTime(0n, timeZone); + +tests.forEach(([arg, description]) => { + const result = instance.withPlainTime(arg); + + assert.sameValue( + result.epochNanoseconds, + 45_296_987_654_321n, + `time zone annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-unknown-annotation.js new file mode 100644 index 0000000000..7870e582ff --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-unknown-annotation.js @@ -0,0 +1,40 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaintime +description: Various forms of unknown annotation +features: [Temporal] +---*/ + +const tests = [ + ["12:34:56.987654321[foo=bar]", "alone"], + ["12:34:56.987654321[UTC][foo=bar]", "with time zone"], + ["12:34:56.987654321[u-ca=iso8601][foo=bar]", "with calendar"], + ["12:34:56.987654321[UTC][foo=bar][u-ca=iso8601]", "with time zone and calendar"], + ["T12:34:56.987654321[foo=bar]", "with T"], + ["T12:34:56.987654321[UTC][foo=bar]", "with T and time zone"], + ["T12:34:56.987654321[u-ca=iso8601][foo=bar]", "with T and calendar"], + ["T12:34:56.987654321[UTC][foo=bar][u-ca=iso8601]", "with T, time zone, and calendar"], + ["1970-01-01T12:34:56.987654321[foo=bar]", "with date"], + ["1970-01-01T12:34:56.987654321[UTC][foo=bar]", "with date and time zone"], + ["1970-01-01T12:34:56.987654321[u-ca=iso8601][foo=bar]", "with date and calendar"], + ["1970-01-01T12:34:56.987654321[UTC][foo=bar][u-ca=iso8601]", "with date, time zone, and calendar"], + ["1970-01-01T12:34:56.987654321[foo=bar][_foo-bar0=Ignore-This-999999999999]", "with another unknown annotation"], +]; + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.ZonedDateTime(0n, timeZone); + +tests.forEach(([arg, description]) => { + const result = instance.withPlainTime(arg); + + assert.sameValue( + result.epochNanoseconds, + 45_296_987_654_321n, + `unknown annotation (${description})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-with-time-designator.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-with-time-designator.js new file mode 100644 index 0000000000..5158ef1810 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-with-time-designator.js @@ -0,0 +1,31 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaintime +description: ISO 8601 time designator "T" allowed at the start of PlainTime strings +features: [Temporal, arrow-function] +---*/ + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); +const validStrings = [ + "T00:30", + "t00:30", + "T0030", + "t0030", + "T00:30:00", + "t00:30:00", + "T003000", + "t003000", + "T00:30:00.000000000", + "t00:30:00.000000000", + "T003000.000000000", + "t003000.000000000", +]; +validStrings.forEach((arg) => { + const result = instance.withPlainTime(arg); + assert.sameValue(result.epochNanoseconds, 999995400_000_000_000n, `T prefix is accepted: ${arg}`); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-with-utc-designator.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-with-utc-designator.js new file mode 100644 index 0000000000..5421bdb7bd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-with-utc-designator.js @@ -0,0 +1,26 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaintime +description: RangeError thrown if a string with UTC designator is used as a PlainTime +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "2019-10-01T09:00:00Z", + "2019-10-01T09:00:00Z[UTC]", + "09:00:00Z[UTC]", + "09:00:00Z", +]; +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.withPlainTime(arg), + "String with UTC designator should not be valid as a PlainTime" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-wrong-type.js new file mode 100644 index 0000000000..9ee14e55fb --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-wrong-type.js @@ -0,0 +1,42 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaintime +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainTime +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); + +const primitiveTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of primitiveTests) { + assert.throws( + typeof arg === 'string' ? RangeError : TypeError, + () => instance.withPlainTime(arg), + `${description} does not convert to a valid ISO string` + ); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainTime, "Temporal.PlainTime, object"], + [Temporal.PlainTime.prototype, "Temporal.PlainTime.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.withPlainTime(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/ZonedDateTime/prototype/withPlainTime/argument-zoneddatetime-balance-negative-time-units.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-zoneddatetime-balance-negative-time-units.js new file mode 100644 index 0000000000..36c14236b5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-zoneddatetime-balance-negative-time-units.js @@ -0,0 +1,49 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaintime +description: Negative time fields are balanced upwards if the argument is given as ZonedDateTime +info: | + sec-temporal-balancetime steps 3–14: + 3. Set _microsecond_ to _microsecond_ + floor(_nanosecond_ / 1000). + 4. Set _nanosecond_ to _nanosecond_ modulo 1000. + 5. Set _millisecond_ to _millisecond_ + floor(_microsecond_ / 1000). + 6. Set _microsecond_ to _microsecond_ modulo 1000. + 7. Set _second_ to _second_ + floor(_millisecond_ / 1000). + 8. Set _millisecond_ to _millisecond_ modulo 1000. + 9. Set _minute_ to _minute_ + floor(_second_ / 60). + 10. Set _second_ to _second_ modulo 60. + 11. Set _hour_ to _hour_ + floor(_minute_ / 60). + 12. Set _minute_ to _minute_ modulo 60. + 13. Let _days_ be floor(_hour_ / 24). + 14. Set _hour_ to _hour_ modulo 24. + sec-temporal-balanceisodatetime step 1: + 1. Let _balancedTime_ be ? BalanceTime(_hour_, _minute_, _second_, _millisecond_, _microsecond_, _nanosecond_). + sec-temporal-builtintimezonegetplaindatetimefor step 3: + 3. Set _result_ to ? BalanceISODateTime(_result_.[[Year]], _result_.[[Month]], _result_.[[Day]], _result_.[[Hour]], _result_.[[Minute]], _result_.[[Second]], _result_.[[Millisecond]], _result_.[[Microsecond]], _result_.[[Nanosecond]] + _offsetNanoseconds_). + sec-temporal-totemporaltime step 3.b: + b. If _item_ has an [[InitializedTemporalZonedDateTime]] internal slot, then + ... + ii. 1. Set _plainDateTime_ to ? BuiltinTimeZoneGetPlainDateTimeFor(_item_.[[TimeZone]], _instant_, _item_.[[Calendar]]). + sec-temporal.zoneddatetime.prototype.withplaintime step 4.a: + a. Let _plainTime_ be ? ToTemporalTime(_plainTimeLike_). +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +// This code path is encountered if the time zone offset is negative and its +// absolute value in nanoseconds is greater than the nanosecond field of the +// exact time's epoch parts +const tz = TemporalHelpers.specificOffsetTimeZone(-2); +const datetime = new Temporal.ZonedDateTime(3661_001_001_001n, tz); + +const otherTimeZone = new Temporal.TimeZone("UTC"); // should not be used to convert datetime -> PlainTime +const zdt = new Temporal.ZonedDateTime(86400_000_000_000n, otherTimeZone); +const newzdt = zdt.withPlainTime(datetime); + +assert.sameValue(newzdt.microsecond, 0); +assert.sameValue(newzdt.nanosecond, 999); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-zoneddatetime-negative-epochnanoseconds.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-zoneddatetime-negative-epochnanoseconds.js new file mode 100644 index 0000000000..2bdf59aa9c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-zoneddatetime-negative-epochnanoseconds.js @@ -0,0 +1,25 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaintime +description: A pre-epoch value is handled correctly by the modulo operation in GetISOPartsFromEpoch +info: | + sec-temporal-getisopartsfromepoch step 1: + 1. Let _remainderNs_ be the mathematical value whose sign is the sign of _epochNanoseconds_ and whose magnitude is abs(_epochNanoseconds_) modulo 10<sup>6</sup>. + sec-temporal-builtintimezonegetplaindatetimefor step 2: + 2. Let _result_ be ! GetISOPartsFromEpoch(_instant_.[[Nanoseconds]]). +features: [Temporal] +---*/ + +const datetime = new Temporal.ZonedDateTime(-13849764_999_999_999n, "UTC"); + +// This code path shows up anywhere we convert an exact time, before the Unix +// epoch, with nonzero microseconds or nanoseconds, into a wall time. + +const instance = new Temporal.ZonedDateTime(0n, "UTC"); +const result = instance.withPlainTime(datetime); +assert.sameValue(result.epochNanoseconds, 60635_000_000_001n); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js new file mode 100644 index 0000000000..d1064ae7ab --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js @@ -0,0 +1,19 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaintime +description: RangeError thrown if time zone reports an offset that is not an integer number of nanoseconds +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +[3600_000_000_000.5, NaN, -Infinity, Infinity].forEach((wrongOffset) => { + const timeZone = TemporalHelpers.specificOffsetTimeZone(wrongOffset); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, "UTC"); + const other = new Temporal.ZonedDateTime(1_100_000_000_987_654_321n, timeZone); + assert.throws(RangeError, () => datetime.withPlainTime(other)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js new file mode 100644 index 0000000000..65dc46f85f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js @@ -0,0 +1,23 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaintime +description: TypeError thrown if timeZone.getOffsetNanosecondsFor is not callable +features: [BigInt, Symbol, Temporal, arrow-function] +---*/ + +[undefined, null, true, Math.PI, 'string', Symbol('sym'), 42n, {}].forEach((notCallable) => { + const timeZone = new Temporal.TimeZone("UTC"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, "UTC"); + const other = new Temporal.ZonedDateTime(1_100_000_000_987_654_321n, timeZone); + timeZone.getOffsetNanosecondsFor = notCallable; + assert.throws( + TypeError, + () => datetime.withPlainTime(other), + `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js new file mode 100644 index 0000000000..3baca11c86 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js @@ -0,0 +1,19 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaintime +description: RangeError thrown if time zone reports an offset that is out of range +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +[-86400_000_000_000, 86400_000_000_000].forEach((wrongOffset) => { + const timeZone = TemporalHelpers.specificOffsetTimeZone(wrongOffset); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, "UTC"); + const other = new Temporal.ZonedDateTime(1_100_000_000_987_654_321n, timeZone); + assert.throws(RangeError, () => datetime.withPlainTime(other)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js new file mode 100644 index 0000000000..f34255f8cd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js @@ -0,0 +1,28 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaintime +description: TypeError thrown if time zone reports an offset that is not a Number +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +[ + undefined, + null, + true, + "+01:00", + Symbol(), + 3600_000_000_000n, + {}, + { valueOf() { return 3600_000_000_000; } }, +].forEach((wrongOffset) => { + const timeZone = TemporalHelpers.specificOffsetTimeZone(wrongOffset); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, "UTC"); + const other = new Temporal.ZonedDateTime(1_100_000_000_987_654_321n, timeZone); + assert.throws(TypeError, () => datetime.withPlainTime(other)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/branding.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/branding.js new file mode 100644 index 0000000000..644b98458e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/branding.js @@ -0,0 +1,25 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaintime +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const withPlainTime = Temporal.ZonedDateTime.prototype.withPlainTime; + +assert.sameValue(typeof withPlainTime, "function"); + +assert.throws(TypeError, () => withPlainTime.call(undefined), "undefined"); +assert.throws(TypeError, () => withPlainTime.call(null), "null"); +assert.throws(TypeError, () => withPlainTime.call(true), "true"); +assert.throws(TypeError, () => withPlainTime.call(""), "empty string"); +assert.throws(TypeError, () => withPlainTime.call(Symbol()), "symbol"); +assert.throws(TypeError, () => withPlainTime.call(1), "1"); +assert.throws(TypeError, () => withPlainTime.call({}), "plain object"); +assert.throws(TypeError, () => withPlainTime.call(Temporal.ZonedDateTime), "Temporal.ZonedDateTime"); +assert.throws(TypeError, () => withPlainTime.call(Temporal.ZonedDateTime.prototype), "Temporal.ZonedDateTime.prototype"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/browser.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/builtin-timezone-no-observable-calls.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/builtin-timezone-no-observable-calls.js new file mode 100644 index 0000000000..e4282fd17c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/builtin-timezone-no-observable-calls.js @@ -0,0 +1,37 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// 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.zoneddatetime.prototype.withplaintime +description: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); +const getPossibleInstantsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getPossibleInstantsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getPossibleInstantsFor should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.withPlainTime(new Temporal.PlainTime(12, 34, 56)); + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", getPossibleInstantsForOriginal); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/builtin.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/builtin.js new file mode 100644 index 0000000000..c44365ab26 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/builtin.js @@ -0,0 +1,36 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaintime +description: > + Tests that Temporal.ZonedDateTime.prototype.withPlainTime + 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.ZonedDateTime.prototype.withPlainTime), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.ZonedDateTime.prototype.withPlainTime), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.ZonedDateTime.prototype.withPlainTime), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.ZonedDateTime.prototype.withPlainTime.hasOwnProperty("prototype"), + false, "prototype property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/getpossibleinstantsfor-called-with-iso8601-calendar.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/getpossibleinstantsfor-called-with-iso8601-calendar.js new file mode 100644 index 0000000000..890bef4f0c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/getpossibleinstantsfor-called-with-iso8601-calendar.js @@ -0,0 +1,58 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// 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.zoneddatetime.prototype.withplaintime +description: > + Time zone's getPossibleInstantsFor is called with a PlainDateTime with the + built-in ISO 8601 calendar +features: [Temporal] +info: | + DisambiguatePossibleInstants: + 2. Let _n_ be _possibleInstants_'s length. + ... + 5. Assert: _n_ = 0. + ... + 19. If _disambiguation_ is *"earlier"*, then + ... + c. Let _earlierDateTime_ be ! CreateTemporalDateTime(..., *"iso8601"*). + d. Set _possibleInstants_ to ? GetPossibleInstantsFor(_timeZone_, _earlierDateTime_). + ... + 20. Assert: _disambiguation_ is *"compatible"* or *"later"*. + ... + 23. Let _laterDateTime_ be ! CreateTemporalDateTime(..., *"iso8601"*). + 24. Set _possibleInstants_ to ? GetPossibleInstantsFor(_timeZone_, _laterDateTime_). +---*/ + +class SkippedDateTime extends Temporal.TimeZone { + constructor() { + super("UTC"); + this.calls = 0; + } + + getPossibleInstantsFor(dateTime) { + // Calls occur in pairs. For the first one return no possible instants so + // that DisambiguatePossibleInstants will call it again + if (this.calls++ % 2 == 0) { + return []; + } + + assert.sameValue( + dateTime.getISOFields().calendar, + "iso8601", + "getPossibleInstantsFor called with dateTime with built-in ISO 8601 calendar" + ); + return super.getPossibleInstantsFor(dateTime); + } +} + +const nonBuiltinISOCalendar = new Temporal.Calendar("iso8601"); +const timeZone = new SkippedDateTime(); + +const instance = new Temporal.ZonedDateTime(0n, timeZone, nonBuiltinISOCalendar); +instance.withPlainTime(); + +assert.sameValue(timeZone.calls, 2, "getPossibleInstantsFor should have been called 2 times"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/leap-second.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/leap-second.js new file mode 100644 index 0000000000..79685eb7ca --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/leap-second.js @@ -0,0 +1,29 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaintime +description: Leap second is a valid ISO string for PlainTime +features: [Temporal] +---*/ + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.withPlainTime(arg); +assert.sameValue( + result1.epochNanoseconds, + 1000079999_000_000_000n, + "leap second is a valid ISO string for PlainTime" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.withPlainTime(arg); +assert.sameValue( + result2.epochNanoseconds, + 1000079999_000_000_000n, + "second: 60 is ignored in property bag for PlainTime" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/length.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/length.js new file mode 100644 index 0000000000..5e419dd76a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/length.js @@ -0,0 +1,28 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaintime +description: Temporal.ZonedDateTime.prototype.withPlainTime.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.ZonedDateTime.prototype.withPlainTime, "length", { + value: 0, + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/name.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/name.js new file mode 100644 index 0000000000..b9294ef7dd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/name.js @@ -0,0 +1,26 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaintime +description: Temporal.ZonedDateTime.prototype.withPlainTime.name is "withPlainTime". +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.ZonedDateTime.prototype.withPlainTime, "name", { + value: "withPlainTime", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/not-a-constructor.js new file mode 100644 index 0000000000..9e0d86e8aa --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/not-a-constructor.js @@ -0,0 +1,24 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaintime +description: > + Temporal.ZonedDateTime.prototype.withPlainTime 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.ZonedDateTime.prototype.withPlainTime(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.ZonedDateTime.prototype.withPlainTime), false, + "isConstructor(Temporal.ZonedDateTime.prototype.withPlainTime)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/order-of-operations.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/order-of-operations.js new file mode 100644 index 0000000000..420678ddfd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/order-of-operations.js @@ -0,0 +1,88 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-get-temporal.zoneddatetime.prototype.withplaintime +description: User code calls happen in the correct order +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const actual = []; +const expected = [ + // ToTemporalTime + "get plainTimeLike.hour", + "get plainTimeLike.hour.valueOf", + "call plainTimeLike.hour.valueOf", + "get plainTimeLike.microsecond", + "get plainTimeLike.microsecond.valueOf", + "call plainTimeLike.microsecond.valueOf", + "get plainTimeLike.millisecond", + "get plainTimeLike.millisecond.valueOf", + "call plainTimeLike.millisecond.valueOf", + "get plainTimeLike.minute", + "get plainTimeLike.minute.valueOf", + "call plainTimeLike.minute.valueOf", + "get plainTimeLike.nanosecond", + "get plainTimeLike.nanosecond.valueOf", + "call plainTimeLike.nanosecond.valueOf", + "get plainTimeLike.second", + "get plainTimeLike.second.valueOf", + "call plainTimeLike.second.valueOf", + // lookup + "get this.timeZone.getOffsetNanosecondsFor", + "get this.timeZone.getPossibleInstantsFor", + // GetPlainDateTimeFor + "call this.timeZone.getOffsetNanosecondsFor", + // GetInstantFor + "call this.timeZone.getPossibleInstantsFor", +]; + +const calendar = TemporalHelpers.calendarObserver(actual, "this.calendar"); +const dstTimeZone = TemporalHelpers.springForwardFallBackTimeZone(); +const timeZone = TemporalHelpers.timeZoneObserver(actual, "this.timeZone", { + getOffsetNanosecondsFor: dstTimeZone.getOffsetNanosecondsFor, + getPossibleInstantsFor: dstTimeZone.getPossibleInstantsFor, +}); + +const instance = new Temporal.ZonedDateTime(946713600_000_000_000n /* 2000-01-01T00:00-08:00 */, timeZone, calendar); +const fallBackInstance = new Temporal.ZonedDateTime(972802800_000_000_000n /* 2000-10-29T00:00-07:00 */, timeZone, calendar); +const springForwardInstance = new Temporal.ZonedDateTime(954662400_000_000_000n /* 2000-04-02T00:00-08:00 */, timeZone, calendar); +actual.splice(0); // clear calls that happened in constructors + +const plainTimeLike = TemporalHelpers.propertyBagObserver(actual, { + hour: 2, + minute: 30, + second: 0, + millisecond: 0, + microsecond: 0, + nanosecond: 0, +}, "plainTimeLike"); + +instance.withPlainTime(plainTimeLike); +assert.compareArray(actual, expected, "order of operations at normal wall-clock time"); +actual.splice(0); // clear + +const plainTimeLike130 = TemporalHelpers.propertyBagObserver(actual, { + hour: 1, + minute: 30, + second: 0, + millisecond: 0, + microsecond: 0, + nanosecond: 0, +}, "plainTimeLike"); + +fallBackInstance.withPlainTime(plainTimeLike130); +assert.compareArray(actual, expected, "order of operations at repeated wall-clock time"); +actual.splice(0); // clear + +springForwardInstance.withPlainTime(plainTimeLike); +assert.compareArray(actual, expected.concat([ + "call this.timeZone.getOffsetNanosecondsFor", + "call this.timeZone.getOffsetNanosecondsFor", + "call this.timeZone.getPossibleInstantsFor", +]), "order of operations at skipped wall-clock time"); +actual.splice(0); // clear + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/plaintime-propertybag-no-time-units.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/plaintime-propertybag-no-time-units.js new file mode 100644 index 0000000000..62a6c07697 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/plaintime-propertybag-no-time-units.js @@ -0,0 +1,20 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaintime +description: Missing time units in property bag default to 0 +features: [Temporal] +---*/ + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); + +const props = {}; +assert.throws(TypeError, () => instance.withPlainTime(props), "TypeError if no properties are present"); + +props.minute = 30; +const result = instance.withPlainTime(props); +assert.sameValue(result.epochNanoseconds, 999995400_000_000_000n, "missing time units default to 0"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/prop-desc.js new file mode 100644 index 0000000000..0df6a75f9f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/prop-desc.js @@ -0,0 +1,24 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaintime +description: The "withPlainTime" property of Temporal.ZonedDateTime.prototype +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.ZonedDateTime.prototype.withPlainTime, + "function", + "`typeof ZonedDateTime.prototype.withPlainTime` is `function`" +); + +verifyProperty(Temporal.ZonedDateTime.prototype, "withPlainTime", { + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/shell.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/shell.js new file mode 100644 index 0000000000..eda1477282 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/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/ZonedDateTime/prototype/withPlainTime/subclassing-ignored.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/subclassing-ignored.js new file mode 100644 index 0000000000..70ad2f2ea8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/subclassing-ignored.js @@ -0,0 +1,31 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaintime +description: Objects of a subclass are never created as return values. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +TemporalHelpers.checkSubclassingIgnored( + Temporal.ZonedDateTime, + [10n, "UTC"], + "withPlainTime", + ["05:43:21.123456789"], + (result) => { + assert.sameValue(result.epochNanoseconds, 20601_123_456_789n, "epochNanoseconds result"); + assert.sameValue(result.year, 1970, "year result"); + assert.sameValue(result.month, 1, "month result"); + assert.sameValue(result.day, 1, "day result"); + assert.sameValue(result.hour, 5, "hour result"); + assert.sameValue(result.minute, 43, "minute result"); + assert.sameValue(result.second, 21, "second result"); + assert.sameValue(result.millisecond, 123, "millisecond result"); + assert.sameValue(result.microsecond, 456, "microsecond result"); + assert.sameValue(result.nanosecond, 789, "nanosecond result"); + }, +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/time-undefined.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/time-undefined.js new file mode 100644 index 0000000000..fb56367443 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/time-undefined.js @@ -0,0 +1,29 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaintime +description: The time is assumed to be midnight if not given +features: [BigInt, Temporal] +---*/ + +const datetime = new Temporal.ZonedDateTime(957270896_987_654_321n, "UTC"); + +const explicit = datetime.withPlainTime(undefined); +assert.sameValue(explicit.hour, 0, "default time is midnight"); +assert.sameValue(explicit.minute, 0, "default time is midnight"); +assert.sameValue(explicit.second, 0, "default time is midnight"); +assert.sameValue(explicit.millisecond, 0, "default time is midnight"); +assert.sameValue(explicit.microsecond, 0, "default time is midnight"); +assert.sameValue(explicit.nanosecond, 0, "default time is midnight"); + +const implicit = datetime.withPlainTime(); +assert.sameValue(implicit.hour, 0, "default time is midnight"); +assert.sameValue(implicit.minute, 0, "default time is midnight"); +assert.sameValue(implicit.second, 0, "default time is midnight"); +assert.sameValue(implicit.millisecond, 0, "default time is midnight"); +assert.sameValue(implicit.microsecond, 0, "default time is midnight"); +assert.sameValue(implicit.nanosecond, 0, "default time is midnight"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/timezone-getoffsetnanosecondsfor-non-integer.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/timezone-getoffsetnanosecondsfor-non-integer.js new file mode 100644 index 0000000000..abc5aab8a1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/timezone-getoffsetnanosecondsfor-non-integer.js @@ -0,0 +1,19 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaintime +description: RangeError thrown if time zone reports an offset that is not an integer number of nanoseconds +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +[3600_000_000_000.5, NaN, -Infinity, Infinity].forEach((wrongOffset) => { + const timeZone = TemporalHelpers.specificOffsetTimeZone(wrongOffset); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + const time = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); + assert.throws(RangeError, () => datetime.withPlainTime(time)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/timezone-getoffsetnanosecondsfor-not-callable.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/timezone-getoffsetnanosecondsfor-not-callable.js new file mode 100644 index 0000000000..a2a089cc9c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/timezone-getoffsetnanosecondsfor-not-callable.js @@ -0,0 +1,23 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaintime +description: TypeError thrown if timeZone.getOffsetNanosecondsFor is not callable +features: [BigInt, Symbol, Temporal, arrow-function] +---*/ + +[undefined, null, true, Math.PI, 'string', Symbol('sym'), 42n, {}].forEach((notCallable) => { + const timeZone = new Temporal.TimeZone("UTC"); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + const time = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); + timeZone.getOffsetNanosecondsFor = notCallable; + assert.throws( + TypeError, + () => datetime.withPlainTime(time), + `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/timezone-getoffsetnanosecondsfor-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/timezone-getoffsetnanosecondsfor-out-of-range.js new file mode 100644 index 0000000000..a08ece63c0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/timezone-getoffsetnanosecondsfor-out-of-range.js @@ -0,0 +1,19 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaintime +description: RangeError thrown if time zone reports an offset that is out of range +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +[-86400_000_000_000, 86400_000_000_000].forEach((wrongOffset) => { + const timeZone = TemporalHelpers.specificOffsetTimeZone(wrongOffset); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + const time = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); + assert.throws(RangeError, () => datetime.withPlainTime(time)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/timezone-getoffsetnanosecondsfor-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/timezone-getoffsetnanosecondsfor-wrong-type.js new file mode 100644 index 0000000000..81a053e2cd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/timezone-getoffsetnanosecondsfor-wrong-type.js @@ -0,0 +1,28 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaintime +description: TypeError thrown if time zone reports an offset that is not a Number +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +[ + undefined, + null, + true, + "+01:00", + Symbol(), + 3600_000_000_000n, + {}, + { valueOf() { return 3600_000_000_000; } }, +].forEach((wrongOffset) => { + const timeZone = TemporalHelpers.specificOffsetTimeZone(wrongOffset); + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone); + const time = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); + assert.throws(TypeError, () => datetime.withPlainTime(time)); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/year-zero.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/year-zero.js new file mode 100644 index 0000000000..e092ae571b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/year-zero.js @@ -0,0 +1,26 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaintime +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-12-07T03:24:30", + "-000000-12-07T03:24:30+01:00", + "-000000-12-07T03:24:30+00:00[UTC]", +]; +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.ZonedDateTime(0n, timeZone); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.withPlainTime(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); |