diff --git a/harness/temporalHelpers.js b/harness/temporalHelpers.js index 6aba4a03cf..b4c0fb1604 100644 --- a/harness/temporalHelpers.js +++ b/harness/temporalHelpers.js @@ -1197,6 +1197,8 @@ var TemporalHelpers = { "1976-11[U-CA=iso8601]", "1976-11[u-CA=iso8601]", "1976-11[FOO=bar]", + "+999999-01", + "-999999-01", ]; }, diff --git a/test/built-ins/Temporal/PlainYearMonth/argument-invalid.js b/test/built-ins/Temporal/PlainYearMonth/argument-invalid.js new file mode 100644 index 0000000000..7ccc20e375 --- /dev/null +++ b/test/built-ins/Temporal/PlainYearMonth/argument-invalid.js @@ -0,0 +1,24 @@ +// Copyright (C) 2024 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth +description: PlainYearMonth constructor with invalid iso dates +features: [Temporal] +---*/ + +const tests = [ + [2020, 0, 24], + [2020, 13, 24], + [2020, -3, 24], + [2020, 12, 32], + [2020, 2, 30], + [2019, 2, 29], + [2019, 2, 0], + [2019, 2, -20], +]; + +for (const [year, month, day] of tests) { + assert.throws(RangeError, () => new Temporal.PlainYearMonth(year, month, undefined, day), + `year=${year}, month=${month}, day=${day}`); +} diff --git a/test/built-ins/Temporal/PlainYearMonth/get-prototype-from-constructor-throws.js b/test/built-ins/Temporal/PlainYearMonth/get-prototype-from-constructor-throws.js new file mode 100644 index 0000000000..cfbc0ade8e --- /dev/null +++ b/test/built-ins/Temporal/PlainYearMonth/get-prototype-from-constructor-throws.js @@ -0,0 +1,40 @@ +// Copyright (C) 2024 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth +description: > + OrdinaryCreateFromConstructor returns with an abrupt completion. +info: | + CreateTemporalYearMonth ( isoDate, calendar [ , newTarget ] ) + + ... + 3. Let object be ? OrdinaryCreateFromConstructor(newTarget, + "%Temporal.PlainYearMonth.prototype%", « [[InitializedTemporalYearMonth]], + [[ISODate]], [[Calendar]] »). + ... + + OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] ) + + ... + 2. Let proto be ? GetPrototypeFromConstructor(constructor, intrinsicDefaultProto). + ... + + GetPrototypeFromConstructor ( constructor, intrinsicDefaultProto ) + + ... + 2. Let proto be ? Get(constructor, "prototype"). + ... + +features: [Temporal] +---*/ + +var newTarget = Object.defineProperty(function(){}.bind(), "prototype", { + get() { + throw new Test262Error(); + } +}); + +assert.throws(Test262Error, function() { + Reflect.construct(Temporal.PlainYearMonth, [1, 1], newTarget) +}); diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/add/throws-if-year-outside-valid-iso-range.js b/test/built-ins/Temporal/PlainYearMonth/prototype/add/throws-if-year-outside-valid-iso-range.js new file mode 100644 index 0000000000..694c0c6b0d --- /dev/null +++ b/test/built-ins/Temporal/PlainYearMonth/prototype/add/throws-if-year-outside-valid-iso-range.js @@ -0,0 +1,27 @@ +// Copyright (C) 2024 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.add +description: > + Throws if thisFields is not within valid ISO date range. +info: | + Temporal.PlainYearMonth.prototype.add ( temporalDurationLike [ , options ] ) + + ... + 3. Return ? AddDurationToYearMonth(add, yearMonth, temporalDurationLike, options). + + AddDurationToYearMonth ( operation, yearMonth, temporalDurationLike, options ) + + ... + 8. Set fields.[[Day]] to 1. + 9. Let intermediateDate be ? CalendarDateFromFields(calendar, fields, constrain). + ... + +features: [Temporal] +---*/ + +const minYearMonth = new Temporal.PlainYearMonth(-271821, 4); +const blank = new Temporal.Duration(); + +assert.throws(RangeError, () => minYearMonth.add(blank)); diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/since/throws-if-rounded-date-outside-valid-iso-range.js b/test/built-ins/Temporal/PlainYearMonth/prototype/since/throws-if-rounded-date-outside-valid-iso-range.js new file mode 100644 index 0000000000..ccf6a29d90 --- /dev/null +++ b/test/built-ins/Temporal/PlainYearMonth/prototype/since/throws-if-rounded-date-outside-valid-iso-range.js @@ -0,0 +1,47 @@ +// Copyright (C) 2024 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.since +description: > + Throws if rounded date outside valid ISO date range. +info: | + Temporal.PlainYearMonth.prototype.since ( other [ , options ] ) + + ... + 3. Return ? DifferenceTemporalPlainYearMonth(since, yearMonth, other, options). + + DifferenceTemporalPlainYearMonth ( operation, yearMonth, other, options ) + + ... + 16. If settings.[[SmallestUnit]] is not month or settings.[[RoundingIncrement]] ≠ 1, then + ... + d. Set duration to ? RoundRelativeDuration(duration, destEpochNs, isoDateTime, + unset, calendar, settings.[[LargestUnit]], settings.[[RoundingIncrement]], + settings.[[SmallestUnit]], settings.[[RoundingMode]]).[[Duration]]. + ... + + RoundRelativeDuration ( duration, destEpochNs, isoDateTime, timeZone, calendar, + largestUnit, increment, smallestUnit, roundingMode ) + + ... + 5. If irregularLengthUnit is true, then + a. Let record be ? NudgeToCalendarUnit(sign, duration, destEpochNs, isoDateTime, + timeZone, calendar, increment, smallestUnit, roundingMode). + ... + + NudgeToCalendarUnit ( sign, duration, destEpochNs, isoDateTime, timeZone, calendar, + increment, unit, roundingMode ) + + ... + 8. Let end be ? CalendarDateAdd(calendar, isoDateTime.[[ISODate]], endDuration, constrain). + ... + +features: [Temporal] +---*/ + +var from = new Temporal.PlainYearMonth(1970, 1); +var to = new Temporal.PlainYearMonth(1971, 1); +var options = {roundingIncrement: 100_000_000}; + +assert.throws(RangeError, () => from.since(to, options)); diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/since/throws-if-year-outside-valid-iso-range.js b/test/built-ins/Temporal/PlainYearMonth/prototype/since/throws-if-year-outside-valid-iso-range.js new file mode 100644 index 0000000000..33e841b91e --- /dev/null +++ b/test/built-ins/Temporal/PlainYearMonth/prototype/since/throws-if-year-outside-valid-iso-range.js @@ -0,0 +1,45 @@ +// Copyright (C) 2024 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.since +description: > + Throws if thisFields is not within valid ISO date range. +info: | + Temporal.PlainYearMonth.prototype.since ( other [ , options ] ) + + ... + 3. Return ? DifferenceTemporalPlainYearMonth(since, yearMonth, other, options). + + DifferenceTemporalPlainYearMonth ( operation, yearMonth, other, options ) + + ... + 8. Set thisFields.[[Day]] to 1. + 9. Let thisDate be ? CalendarDateFromFields(calendar, thisFields, constrain). + ... + +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const minYearMonth = new Temporal.PlainYearMonth(-271821, 4); +const maxYearMonth = new Temporal.PlainYearMonth(275760, 9); +const epochYearMonth = new Temporal.PlainYearMonth(1970, 1); + +TemporalHelpers.assertDuration( + minYearMonth.since(minYearMonth), + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "minYearMonth.since(minYearMonth)" +); + +assert.throws( + RangeError, + () => minYearMonth.since(maxYearMonth), + "minYearMonth.since(maxYearMonth)" +); + +assert.throws( + RangeError, + () => minYearMonth.since(epochYearMonth), + "minYearMonth.since(epochYearMonth)" +); diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/throws-if-year-outside-valid-iso-range.js b/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/throws-if-year-outside-valid-iso-range.js new file mode 100644 index 0000000000..1234f12bb7 --- /dev/null +++ b/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/throws-if-year-outside-valid-iso-range.js @@ -0,0 +1,27 @@ +// Copyright (C) 2024 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.subtract +description: > + Throws if thisFields is not within valid ISO date range. +info: | + Temporal.PlainYearMonth.prototype.subtract ( temporalDurationLike [ , options ] ) + + ... + 3. Return ? AddDurationToYearMonth(subtract, yearMonth, temporalDurationLike, options). + + AddDurationToYearMonth ( operation, yearMonth, temporalDurationLike, options ) + + ... + 8. Set fields.[[Day]] to 1. + 9. Let intermediateDate be ? CalendarDateFromFields(calendar, fields, constrain). + ... + +features: [Temporal] +---*/ + +const minYearMonth = new Temporal.PlainYearMonth(-271821, 4); +const blank = new Temporal.Duration(); + +assert.throws(RangeError, () => minYearMonth.subtract(blank)); diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/toJSON/basic.js b/test/built-ins/Temporal/PlainYearMonth/prototype/toJSON/basic.js new file mode 100644 index 0000000000..0c23a684e8 --- /dev/null +++ b/test/built-ins/Temporal/PlainYearMonth/prototype/toJSON/basic.js @@ -0,0 +1,22 @@ +// Copyright (C) 2024 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.tojson +description: Basic behavior for toJSON +features: [Temporal] +---*/ + +const tests = [ + [new Temporal.PlainYearMonth(1972, 1), "1972-01"], + [new Temporal.PlainYearMonth(1972, 12), "1972-12"], +]; + +const options = new Proxy({}, { + get() { throw new Test262Error("should not get properties off argument") } +}); + +for (const [yearMonth, expected] of tests) { + assert.sameValue(yearMonth.toJSON(), expected, "toJSON without argument"); + assert.sameValue(yearMonth.toJSON(options), expected, "toJSON with argument"); +} diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/toLocaleString/return-string.js b/test/built-ins/Temporal/PlainYearMonth/prototype/toLocaleString/return-string.js new file mode 100644 index 0000000000..92ff7d0138 --- /dev/null +++ b/test/built-ins/Temporal/PlainYearMonth/prototype/toLocaleString/return-string.js @@ -0,0 +1,15 @@ +// Copyright (C) 2024 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.tolocalestring +description: toLocaleString returns a string. +features: [Temporal] +---*/ + +const pym = new Temporal.PlainYearMonth(1, 1); + +assert.sameValue( + typeof pym.toLocaleString(undefined, {calendar: "iso8601"}), + "string" +); diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/until/throws-if-rounded-date-outside-valid-iso-range.js b/test/built-ins/Temporal/PlainYearMonth/prototype/until/throws-if-rounded-date-outside-valid-iso-range.js new file mode 100644 index 0000000000..070ed2fd7c --- /dev/null +++ b/test/built-ins/Temporal/PlainYearMonth/prototype/until/throws-if-rounded-date-outside-valid-iso-range.js @@ -0,0 +1,47 @@ +// Copyright (C) 2024 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.until +description: > + Throws if rounded date outside valid ISO date range. +info: | + Temporal.PlainYearMonth.prototype.until ( other [ , options ] ) + + ... + 3. Return ? DifferenceTemporalPlainYearMonth(until, yearMonth, other, options). + + DifferenceTemporalPlainYearMonth ( operation, yearMonth, other, options ) + + ... + 16. If settings.[[SmallestUnit]] is not month or settings.[[RoundingIncrement]] ≠ 1, then + ... + d. Set duration to ? RoundRelativeDuration(duration, destEpochNs, isoDateTime, + unset, calendar, settings.[[LargestUnit]], settings.[[RoundingIncrement]], + settings.[[SmallestUnit]], settings.[[RoundingMode]]).[[Duration]]. + ... + + RoundRelativeDuration ( duration, destEpochNs, isoDateTime, timeZone, calendar, + largestUnit, increment, smallestUnit, roundingMode ) + + ... + 5. If irregularLengthUnit is true, then + a. Let record be ? NudgeToCalendarUnit(sign, duration, destEpochNs, isoDateTime, + timeZone, calendar, increment, smallestUnit, roundingMode). + ... + + NudgeToCalendarUnit ( sign, duration, destEpochNs, isoDateTime, timeZone, calendar, + increment, unit, roundingMode ) + + ... + 8. Let end be ? CalendarDateAdd(calendar, isoDateTime.[[ISODate]], endDuration, constrain). + ... + +features: [Temporal] +---*/ + +var from = new Temporal.PlainYearMonth(1970, 1); +var to = new Temporal.PlainYearMonth(1971, 1); +var options = {roundingIncrement: 100_000_000}; + +assert.throws(RangeError, () => from.until(to, options)); diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/until/throws-if-year-outside-valid-iso-range.js b/test/built-ins/Temporal/PlainYearMonth/prototype/until/throws-if-year-outside-valid-iso-range.js new file mode 100644 index 0000000000..1cf376b31a --- /dev/null +++ b/test/built-ins/Temporal/PlainYearMonth/prototype/until/throws-if-year-outside-valid-iso-range.js @@ -0,0 +1,45 @@ +// Copyright (C) 2024 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.until +description: > + Throws if thisFields is not within valid ISO date range. +info: | + Temporal.PlainYearMonth.prototype.until ( other [ , options ] ) + + ... + 3. Return ? DifferenceTemporalPlainYearMonth(until, yearMonth, other, options). + + DifferenceTemporalPlainYearMonth ( operation, yearMonth, other, options ) + + ... + 8. Set thisFields.[[Day]] to 1. + 9. Let thisDate be ? CalendarDateFromFields(calendar, thisFields, constrain). + ... + +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const minYearMonth = new Temporal.PlainYearMonth(-271821, 4); +const maxYearMonth = new Temporal.PlainYearMonth(275760, 9); +const epochYearMonth = new Temporal.PlainYearMonth(1970, 1); + +TemporalHelpers.assertDuration( + minYearMonth.until(minYearMonth), + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "minYearMonth.until(minYearMonth)" +); + +assert.throws( + RangeError, + () => minYearMonth.until(maxYearMonth), + "minYearMonth.until(maxYearMonth)" +); + +assert.throws( + RangeError, + () => minYearMonth.until(epochYearMonth), + "minYearMonth.until(epochYearMonth)" +); diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/with/yearmonthlike-invalid.js b/test/built-ins/Temporal/PlainYearMonth/prototype/with/yearmonthlike-invalid.js new file mode 100644 index 0000000000..8aeb93f042 --- /dev/null +++ b/test/built-ins/Temporal/PlainYearMonth/prototype/with/yearmonthlike-invalid.js @@ -0,0 +1,58 @@ +// Copyright (C) 2024 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.with +description: > + Throws TypeError on an argument that is not a PlainYearMonth-like property bag +info: | + Temporal.PlainYearMonth.prototype.with ( temporalYearMonthLike [ , options ] ) + + ... + 3. If ? IsPartialTemporalObject(temporalYearMonthLike) is false, throw a TypeError exception. + ... + 6. Let partialYearMonth be ? PrepareCalendarFields(calendar, temporalYearMonthLike, « year, month, month-code », « », partial). + ... +features: [Temporal] +---*/ + +const plainYearMonth = new Temporal.PlainYearMonth(1, 1); + +const tests = [ + // Step 3. + // IsPartialTemporalObject, step 1. + [undefined], + [null], + [true], + ["2019-05-17"], + ["2019-05-17T12:34"], + ["2019-05-17T12:34Z"], + ["18:05:42.577"], + ["42"], + [Symbol(), "symbol"], + [42, "number"], + [42n, "bigint"], + + // IsPartialTemporalObject, step 2. + [Temporal.PlainDate.from("2019-05-17"), "PlainDate"], + [Temporal.PlainDateTime.from("2019-05-17T12:34"), "PlainDateTime"], + [Temporal.PlainMonthDay.from("2019-05-17"), "PlainMonthDay"], + [Temporal.PlainTime.from("12:34"), "PlainTime"], + [Temporal.PlainYearMonth.from("2019-05-17"), "PlainYearMonth"], + [Temporal.ZonedDateTime.from("2019-05-17T12:34Z[UTC]"), "ZonedDateTime"], + + // IsPartialTemporalObject, step 3. + [{ year: 2021, calendar: "iso8601" }, "calendar"], + + // IsPartialTemporalObject, step 4. + [{ year: 2021, timeZone: "UTC" }, "timeZone"], + + // Step 6. + // PrepareCalendarFields, step 10. + [{}, "empty object"], + [{ months: 12 }, "only plural property"], +]; + +for (const [value, message = String(value)] of tests) { + assert.throws(TypeError, () => plainYearMonth.with(value), message); +}