Skip to content

Commit

Permalink
Temporal: Tests for dates out-of-range when finding end of month
Browse files Browse the repository at this point in the history
In PlainYearMonth arithmetic, we need to find the end of the month when
adding a negative duration or subtracting a positive one. This end of the
month can be out of range.

Test case based on one provided by Anba. See issue:
tc39/proposal-temporal#2700
  • Loading branch information
ptomato committed Oct 18, 2023
1 parent 00ba34c commit ec7d6bd
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// 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.plainyearmonth.prototype.add
description: RangeError thrown when adding negative duration and end of month is out of range
features: [Temporal]
info: |
AddDurationToOrSubtractDurationFromPlainYearMonth:
12. If _sign_ < 0, then
a. Let _oneMonthDuration_ be ! CreateTemporalDuration(0, 1, 0, 0, 0, 0, 0, 0, 0, 0).
b. Let _nextMonth_ be ? CalendarDateAdd(_calendar_, _intermediateDate_, _oneMonthDuration_, *undefined*, _dateAdd_).
c. Let _endOfMonthISO_ be ! AddISODate(_nextMonth_.[[ISOYear]], _nextMonth_.[[ISOMonth]], _nextMonth_.[[ISODay]], 0, 0, 0, -1, *"constrain"*).
d. Let _endOfMonth_ be ? CreateTemporalDate(_endOfMonthISO_.[[Year]], _endOfMonthISO_.[[Month]], _endOfMonthISO_.[[Day]], _calendar_).
---*/

// Based on a test case by André Bargull <andre.bargull@gmail.com>

const duration = new Temporal.Duration(0, 0, 0, -1);

// Calendar addition result is out of range
assert.throws(RangeError, () => new Temporal.PlainYearMonth(275760, 9).add(duration), "Addition of 1 month to receiver out of range");

// Calendar addition succeeds, but subtracting 1 day gives out of range result
const cal = new class extends Temporal.Calendar {
dateAdd() {
return new Temporal.PlainDate(-271821, 4, 19);
}
}("iso8601");
assert.throws(RangeError, () => new Temporal.PlainYearMonth(2000, 1, cal).add(duration), "Subtraction of 1 day from next month out of range");
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// 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.plainyearmonth.prototype.subtract
description: RangeError thrown when subtracting positive duration and end of month is out of range
features: [Temporal]
info: |
AddDurationToOrSubtractDurationFromPlainYearMonth:
12. If _sign_ &lt; 0, then
a. Let _oneMonthDuration_ be ! CreateTemporalDuration(0, 1, 0, 0, 0, 0, 0, 0, 0, 0).
b. Let _nextMonth_ be ? CalendarDateAdd(_calendar_, _intermediateDate_, _oneMonthDuration_, *undefined*, _dateAdd_).
c. Let _endOfMonthISO_ be ! AddISODate(_nextMonth_.[[ISOYear]], _nextMonth_.[[ISOMonth]], _nextMonth_.[[ISODay]], 0, 0, 0, -1, *"constrain"*).
d. Let _endOfMonth_ be ? CreateTemporalDate(_endOfMonthISO_.[[Year]], _endOfMonthISO_.[[Month]], _endOfMonthISO_.[[Day]], _calendar_).
---*/

// Based on a test case by André Bargull <andre.bargull@gmail.com>

const duration = new Temporal.Duration(0, 0, 0, 1);

// Calendar addition result is out of range
assert.throws(RangeError, () => new Temporal.PlainYearMonth(275760, 9).subtract(duration), "Addition of 1 month to receiver out of range");

// Calendar addition succeeds, but subtracting 1 day gives out of range result
const cal = new class extends Temporal.Calendar {
dateAdd() {
return new Temporal.PlainDate(-271821, 4, 19);
}
}("iso8601");
assert.throws(RangeError, () => new Temporal.PlainYearMonth(2000, 1, cal).subtract(duration), "Subtraction of 1 day from next month out of range");

0 comments on commit ec7d6bd

Please sign in to comment.