Skip to content

Commit ec7d6bd

Browse files
committed
Temporal: Tests for dates out-of-range when finding end of month
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
1 parent 00ba34c commit ec7d6bd

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-temporal.plainyearmonth.prototype.add
6+
description: RangeError thrown when adding negative duration and end of month is out of range
7+
features: [Temporal]
8+
info: |
9+
AddDurationToOrSubtractDurationFromPlainYearMonth:
10+
12. If _sign_ < 0, then
11+
a. Let _oneMonthDuration_ be ! CreateTemporalDuration(0, 1, 0, 0, 0, 0, 0, 0, 0, 0).
12+
b. Let _nextMonth_ be ? CalendarDateAdd(_calendar_, _intermediateDate_, _oneMonthDuration_, *undefined*, _dateAdd_).
13+
c. Let _endOfMonthISO_ be ! AddISODate(_nextMonth_.[[ISOYear]], _nextMonth_.[[ISOMonth]], _nextMonth_.[[ISODay]], 0, 0, 0, -1, *"constrain"*).
14+
d. Let _endOfMonth_ be ? CreateTemporalDate(_endOfMonthISO_.[[Year]], _endOfMonthISO_.[[Month]], _endOfMonthISO_.[[Day]], _calendar_).
15+
---*/
16+
17+
// Based on a test case by André Bargull <[email protected]>
18+
19+
const duration = new Temporal.Duration(0, 0, 0, -1);
20+
21+
// Calendar addition result is out of range
22+
assert.throws(RangeError, () => new Temporal.PlainYearMonth(275760, 9).add(duration), "Addition of 1 month to receiver out of range");
23+
24+
// Calendar addition succeeds, but subtracting 1 day gives out of range result
25+
const cal = new class extends Temporal.Calendar {
26+
dateAdd() {
27+
return new Temporal.PlainDate(-271821, 4, 19);
28+
}
29+
}("iso8601");
30+
assert.throws(RangeError, () => new Temporal.PlainYearMonth(2000, 1, cal).add(duration), "Subtraction of 1 day from next month out of range");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-temporal.plainyearmonth.prototype.subtract
6+
description: RangeError thrown when subtracting positive duration and end of month is out of range
7+
features: [Temporal]
8+
info: |
9+
AddDurationToOrSubtractDurationFromPlainYearMonth:
10+
12. If _sign_ &lt; 0, then
11+
a. Let _oneMonthDuration_ be ! CreateTemporalDuration(0, 1, 0, 0, 0, 0, 0, 0, 0, 0).
12+
b. Let _nextMonth_ be ? CalendarDateAdd(_calendar_, _intermediateDate_, _oneMonthDuration_, *undefined*, _dateAdd_).
13+
c. Let _endOfMonthISO_ be ! AddISODate(_nextMonth_.[[ISOYear]], _nextMonth_.[[ISOMonth]], _nextMonth_.[[ISODay]], 0, 0, 0, -1, *"constrain"*).
14+
d. Let _endOfMonth_ be ? CreateTemporalDate(_endOfMonthISO_.[[Year]], _endOfMonthISO_.[[Month]], _endOfMonthISO_.[[Day]], _calendar_).
15+
---*/
16+
17+
// Based on a test case by André Bargull <[email protected]>
18+
19+
const duration = new Temporal.Duration(0, 0, 0, 1);
20+
21+
// Calendar addition result is out of range
22+
assert.throws(RangeError, () => new Temporal.PlainYearMonth(275760, 9).subtract(duration), "Addition of 1 month to receiver out of range");
23+
24+
// Calendar addition succeeds, but subtracting 1 day gives out of range result
25+
const cal = new class extends Temporal.Calendar {
26+
dateAdd() {
27+
return new Temporal.PlainDate(-271821, 4, 19);
28+
}
29+
}("iso8601");
30+
assert.throws(RangeError, () => new Temporal.PlainYearMonth(2000, 1, cal).subtract(duration), "Subtraction of 1 day from next month out of range");

0 commit comments

Comments
 (0)