Skip to content

Commit

Permalink
Temporal: Tests for upper limit on rounding increments
Browse files Browse the repository at this point in the history
Previously in a few cases (calendar units in Duration) the value for the
roundingIncrement option had no upper limit, other than having to be
finite. These tests cover a normative change limiting it to 1e9.

Normative PR: tc39/proposal-temporal#2480
  • Loading branch information
ptomato committed Feb 1, 2023
1 parent 8aeab83 commit e7364ea
Show file tree
Hide file tree
Showing 35 changed files with 346 additions and 104 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// 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.duration.prototype.round
description: Rounding for roundingIncrement option
info: |
sec-temporal-totemporalroundingincrement:
3. Let _integerIncrement_ be truncate(ℝ(_increment_)).
includes: [temporalHelpers.js]
features: [Temporal]
---*/

const instance = new Temporal.Duration(1);
const options = {
smallestUnit: "years",
roundingMode: "expand",
relativeTo: new Temporal.PlainDate(2000, 1, 1),
};
const result = instance.round({ ...options, roundingIncrement: 2.5 });
TemporalHelpers.assertDuration(result, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, "roundingIncrement 2.5 truncates to 2");
const result2 = instance.round({ ...options, roundingIncrement: 1e9 + 0.5 });
TemporalHelpers.assertDuration(result2, 1e9, 0, 0, 0, 0, 0, 0, 0, 0, 0, "roundingIncrement 1e9 + 0.5 truncates to 1e9");
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// 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.duration.prototype.round
description: RangeError thrown when roundingIncrement option out of range
info: |
sec-temporal-totemporalroundingincrement:
4. If _integerIncrement_ < 1 or _integerIncrement_ > 10<sup>9</sup>, throw a *RangeError* exception.
features: [Temporal]
---*/

const instance = new Temporal.Duration(1);
const options = { smallestUnit: "years", relativeTo: new Temporal.PlainDate(2000, 1, 1) };
assert.throws(RangeError, () => instance.round({ ...options, roundingIncrement: -Infinity }));
assert.throws(RangeError, () => instance.round({ ...options, roundingIncrement: -1 }));
assert.throws(RangeError, () => instance.round({ ...options, roundingIncrement: 0 }));
assert.throws(RangeError, () => instance.round({ ...options, roundingIncrement: 1e9 + 1 }));
assert.throws(RangeError, () => instance.round({ ...options, roundingIncrement: Infinity }));
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,16 @@
esid: sec-temporal.instant.prototype.round
description: Rounding for roundingIncrement option
info: |
sec-temporal-totemporalroundingincrement step 7:
7. Set _increment_ to floor(ℝ(_increment_)).
ToTemporalRoundingIncrement ( _normalizedOptions_ )
1. Let _increment_ be ? GetOption(_normalizedOptions_, *"roundingIncrement"*, *"number"*, *undefined*, *1*<sub>𝔽</sub>).
2. If _increment_ is not finite, throw a *RangeError* exception.
3. Let _integerIncrement_ be truncate(ℝ(_increment_)).
4. If _integerIncrement_ < 1 or _integerIncrement_ > 10<sup>9</sup>, throw a *RangeError* exception.
5. Return _integerIncrement_.
features: [Temporal]
---*/

const instant = new Temporal.Instant(1_000_000_000_000_000_005n);
const result = instant.round({ smallestUnit: "nanosecond", roundingIncrement: 2.5 });
assert.sameValue(result.epochNanoseconds, 1_000_000_000_000_000_006n, "roundingIncrement 2.5 floors to 2");
const result = instant.round({ smallestUnit: "nanosecond", roundingIncrement: 2.5, roundingMode: "expand" });
assert.sameValue(result.epochNanoseconds, 1_000_000_000_000_000_006n, "roundingIncrement 2.5 truncates to 2");
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,20 @@
esid: sec-temporal.instant.prototype.round
description: RangeError thrown when roundingIncrement option out of range
info: |
sec-temporal-totemporalroundingincrement step 6:
6. If _increment_ < 1 or _increment_ > _maximum_, throw a *RangeError* exception.
ToTemporalRoundingIncrement ( _normalizedOptions_ )
1. Let _increment_ be ? GetOption(_normalizedOptions_, *"roundingIncrement"*, *"number"*, *undefined*, *1*<sub>𝔽</sub>).
2. If _increment_ is not finite, throw a *RangeError* exception.
3. Let _integerIncrement_ be truncate(ℝ(_increment_)).
4. If _integerIncrement_ < 1 or _integerIncrement_ > 10<sup>9</sup>, throw a *RangeError* exception.
5. Return _integerIncrement_.
features: [Temporal]
---*/

const instant = new Temporal.Instant(1_000_000_000_000_000_005n);
assert.throws(RangeError, () => instant.round({ smallestUnit: "nanoseconds", roundingIncrement: -Infinity }));
assert.throws(RangeError, () => instant.round({ smallestUnit: "nanoseconds", roundingIncrement: -1 }));
assert.throws(RangeError, () => instant.round({ smallestUnit: "nanoseconds", roundingIncrement: 0 }));
assert.throws(RangeError, () => instant.round({ smallestUnit: "nanoseconds", roundingIncrement: 0.9 }));
assert.throws(RangeError, () => instant.round({ smallestUnit: "nanoseconds", roundingIncrement: 1e9 + 1 }));
assert.throws(RangeError, () => instant.round({ smallestUnit: "nanoseconds", roundingIncrement: Infinity }));
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,18 @@
esid: sec-temporal.instant.prototype.since
description: Rounding for roundingIncrement option
info: |
sec-temporal-totemporalroundingincrement step 7:
7. Set _increment_ to floor(ℝ(_increment_)).
ToTemporalRoundingIncrement ( _normalizedOptions_ )
1. Let _increment_ be ? GetOption(_normalizedOptions_, *"roundingIncrement"*, *"number"*, *undefined*, *1*<sub>𝔽</sub>).
2. If _increment_ is not finite, throw a *RangeError* exception.
3. Let _integerIncrement_ be truncate(ℝ(_increment_)).
4. If _integerIncrement_ < 1 or _integerIncrement_ > 10<sup>9</sup>, throw a *RangeError* exception.
5. Return _integerIncrement_.
includes: [temporalHelpers.js]
features: [Temporal]
---*/

const earlier = new Temporal.Instant(1_000_000_000_000_000_000n);
const later = new Temporal.Instant(1_000_000_000_000_000_005n);
const result = later.since(earlier, { roundingIncrement: 2.5 });
TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, "roundingIncrement 2.5 floors to 2");
const result = later.since(earlier, { roundingIncrement: 2.5, roundingMode: "trunc" });
TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, "roundingIncrement 2.5 truncates to 2");
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,13 @@
esid: sec-temporal.instant.prototype.since
description: RangeError thrown when roundingIncrement option out of range
info: |
sec-temporal-totemporalroundingincrement step 6:
6. If _increment_ < 1 or _increment_ > _maximum_, throw a *RangeError* exception.
ToTemporalRoundingIncrement ( _normalizedOptions_ )
1. Let _increment_ be ? GetOption(_normalizedOptions_, *"roundingIncrement"*, *"number"*, *undefined*, *1*<sub>𝔽</sub>).
2. If _increment_ is not finite, throw a *RangeError* exception.
3. Let _integerIncrement_ be truncate(ℝ(_increment_)).
4. If _integerIncrement_ < 1 or _integerIncrement_ > 10<sup>9</sup>, throw a *RangeError* exception.
5. Return _integerIncrement_.
features: [Temporal]
---*/

Expand All @@ -15,4 +20,6 @@ const later = new Temporal.Instant(1_000_000_000_000_000_005n);
assert.throws(RangeError, () => later.since(earlier, { roundingIncrement: -Infinity }));
assert.throws(RangeError, () => later.since(earlier, { roundingIncrement: -1 }));
assert.throws(RangeError, () => later.since(earlier, { roundingIncrement: 0 }));
assert.throws(RangeError, () => later.since(earlier, { roundingIncrement: 0.9 }));
assert.throws(RangeError, () => later.since(earlier, { roundingIncrement: 1e9 + 1 }));
assert.throws(RangeError, () => later.since(earlier, { roundingIncrement: Infinity }));
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,18 @@
esid: sec-temporal.instant.prototype.until
description: Rounding for roundingIncrement option
info: |
sec-temporal-totemporalroundingincrement step 7:
7. Set _increment_ to floor(ℝ(_increment_)).
ToTemporalRoundingIncrement ( _normalizedOptions_ )
1. Let _increment_ be ? GetOption(_normalizedOptions_, *"roundingIncrement"*, *"number"*, *undefined*, *1*<sub>𝔽</sub>).
2. If _increment_ is not finite, throw a *RangeError* exception.
3. Let _integerIncrement_ be truncate(ℝ(_increment_)).
4. If _integerIncrement_ < 1 or _integerIncrement_ > 10<sup>9</sup>, throw a *RangeError* exception.
5. Return _integerIncrement_.
includes: [temporalHelpers.js]
features: [Temporal]
---*/

const earlier = new Temporal.Instant(1_000_000_000_000_000_000n);
const later = new Temporal.Instant(1_000_000_000_000_000_005n);
const result = earlier.until(later, { roundingIncrement: 2.5 });
TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, "roundingIncrement 2.5 floors to 2");
const result = earlier.until(later, { roundingIncrement: 2.5, roundingMode: "trunc" });
TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, "roundingIncrement 2.5 truncates to 2");
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,13 @@
esid: sec-temporal.instant.prototype.until
description: RangeError thrown when roundingIncrement option out of range
info: |
sec-temporal-totemporalroundingincrement step 6:
6. If _increment_ < 1 or _increment_ > _maximum_, throw a *RangeError* exception.
ToTemporalRoundingIncrement ( _normalizedOptions_ )
1. Let _increment_ be ? GetOption(_normalizedOptions_, *"roundingIncrement"*, *"number"*, *undefined*, *1*<sub>𝔽</sub>).
2. If _increment_ is not finite, throw a *RangeError* exception.
3. Let _integerIncrement_ be truncate(ℝ(_increment_)).
4. If _integerIncrement_ < 1 or _integerIncrement_ > 10<sup>9</sup>, throw a *RangeError* exception.
5. Return _integerIncrement_.
features: [Temporal]
---*/

Expand All @@ -15,4 +20,6 @@ const later = new Temporal.Instant(1_000_000_000_000_000_005n);
assert.throws(RangeError, () => earlier.until(later, { roundingIncrement: -Infinity }));
assert.throws(RangeError, () => earlier.until(later, { roundingIncrement: -1 }));
assert.throws(RangeError, () => earlier.until(later, { roundingIncrement: 0 }));
assert.throws(RangeError, () => earlier.until(later, { roundingIncrement: 0.9 }));
assert.throws(RangeError, () => earlier.until(later, { roundingIncrement: 1e9 + 1 }));
assert.throws(RangeError, () => earlier.until(later, { roundingIncrement: Infinity }));
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,20 @@
esid: sec-temporal.plaindate.prototype.since
description: Rounding for roundingIncrement option
info: |
sec-temporal-totemporalroundingincrement step 7:
7. Set _increment_ to floor(ℝ(_increment_)).
ToTemporalRoundingIncrement ( _normalizedOptions_ )
1. Let _increment_ be ? GetOption(_normalizedOptions_, *"roundingIncrement"*, *"number"*, *undefined*, *1*<sub>𝔽</sub>).
2. If _increment_ is not finite, throw a *RangeError* exception.
3. Let _integerIncrement_ be truncate(ℝ(_increment_)).
4. If _integerIncrement_ < 1 or _integerIncrement_ > 10<sup>9</sup>, throw a *RangeError* exception.
5. Return _integerIncrement_.
includes: [temporalHelpers.js]
features: [Temporal]
---*/

const earlier = new Temporal.PlainDate(2000, 5, 2);
const later = new Temporal.PlainDate(2000, 5, 7);
const result = later.since(earlier, { roundingIncrement: 2.5 });
TemporalHelpers.assertDuration(result, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, "roundingIncrement 2.5 floors to 2");
const result = later.since(earlier, { roundingIncrement: 2.5, roundingMode: "trunc" });
TemporalHelpers.assertDuration(result, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, "roundingIncrement 2.5 truncates to 2");
const result2 = later.since(earlier, { smallestUnit: "days", roundingIncrement: 1e9 + 0.5, roundingMode: "expand" });
TemporalHelpers.assertDuration(result2, 0, 0, 0, 1e9, 0, 0, 0, 0, 0, 0, "roundingIncrement 1e9 + 0.5 truncates to 1e9");
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,13 @@
esid: sec-temporal.plaindate.prototype.since
description: RangeError thrown when roundingIncrement option out of range
info: |
sec-temporal-totemporalroundingincrement step 6:
6. If _increment_ < 1 or _increment_ > _maximum_, throw a *RangeError* exception.
ToTemporalRoundingIncrement ( _normalizedOptions_ )
1. Let _increment_ be ? GetOption(_normalizedOptions_, *"roundingIncrement"*, *"number"*, *undefined*, *1*<sub>𝔽</sub>).
2. If _increment_ is not finite, throw a *RangeError* exception.
3. Let _integerIncrement_ be truncate(ℝ(_increment_)).
4. If _integerIncrement_ < 1 or _integerIncrement_ > 10<sup>9</sup>, throw a *RangeError* exception.
5. Return _integerIncrement_.
features: [Temporal]
---*/

Expand All @@ -15,4 +20,6 @@ const later = new Temporal.PlainDate(2000, 5, 7);
assert.throws(RangeError, () => later.since(earlier, { roundingIncrement: -Infinity }));
assert.throws(RangeError, () => later.since(earlier, { roundingIncrement: -1 }));
assert.throws(RangeError, () => later.since(earlier, { roundingIncrement: 0 }));
assert.throws(RangeError, () => later.since(earlier, { roundingIncrement: 0.9 }));
assert.throws(RangeError, () => later.since(earlier, { roundingIncrement: 1e9 + 1 }));
assert.throws(RangeError, () => later.since(earlier, { roundingIncrement: Infinity }));
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,20 @@
esid: sec-temporal.plaindate.prototype.until
description: Rounding for roundingIncrement option
info: |
sec-temporal-totemporalroundingincrement step 7:
7. Set _increment_ to floor(ℝ(_increment_)).
ToTemporalRoundingIncrement ( _normalizedOptions_ )
1. Let _increment_ be ? GetOption(_normalizedOptions_, *"roundingIncrement"*, *"number"*, *undefined*, *1*<sub>𝔽</sub>).
2. If _increment_ is not finite, throw a *RangeError* exception.
3. Let _integerIncrement_ be truncate(ℝ(_increment_)).
4. If _integerIncrement_ < 1 or _integerIncrement_ > 10<sup>9</sup>, throw a *RangeError* exception.
5. Return _integerIncrement_.
includes: [temporalHelpers.js]
features: [Temporal]
---*/

const earlier = new Temporal.PlainDate(2000, 5, 2);
const later = new Temporal.PlainDate(2000, 5, 7);
const result = earlier.until(later, { roundingIncrement: 2.5 });
TemporalHelpers.assertDuration(result, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, "roundingIncrement 2.5 floors to 2");
const result = earlier.until(later, { roundingIncrement: 2.5, roundingMode: "trunc" });
TemporalHelpers.assertDuration(result, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, "roundingIncrement 2.5 truncates to 2");
const result2 = earlier.until(later, { smallestUnit: "days", roundingIncrement: 1e9 + 0.5, roundingMode: "expand" });
TemporalHelpers.assertDuration(result2, 0, 0, 0, 1e9, 0, 0, 0, 0, 0, 0, "roundingIncrement 1e9 + 0.5 truncates to 1e9");
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,13 @@
esid: sec-temporal.plaindate.prototype.until
description: RangeError thrown when roundingIncrement option out of range
info: |
sec-temporal-totemporalroundingincrement step 6:
6. If _increment_ < 1 or _increment_ > _maximum_, throw a *RangeError* exception.
ToTemporalRoundingIncrement ( _normalizedOptions_ )
1. Let _increment_ be ? GetOption(_normalizedOptions_, *"roundingIncrement"*, *"number"*, *undefined*, *1*<sub>𝔽</sub>).
2. If _increment_ is not finite, throw a *RangeError* exception.
3. Let _integerIncrement_ be truncate(ℝ(_increment_)).
4. If _integerIncrement_ < 1 or _integerIncrement_ > 10<sup>9</sup>, throw a *RangeError* exception.
5. Return _integerIncrement_.
features: [Temporal]
---*/

Expand All @@ -15,4 +20,6 @@ const later = new Temporal.PlainDate(2000, 5, 7);
assert.throws(RangeError, () => earlier.until(later, { roundingIncrement: -Infinity }));
assert.throws(RangeError, () => earlier.until(later, { roundingIncrement: -1 }));
assert.throws(RangeError, () => earlier.until(later, { roundingIncrement: 0 }));
assert.throws(RangeError, () => earlier.until(later, { roundingIncrement: 0.9 }));
assert.throws(RangeError, () => earlier.until(later, { roundingIncrement: 1e9 + 1 }));
assert.throws(RangeError, () => earlier.until(later, { roundingIncrement: Infinity }));
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,17 @@
esid: sec-temporal.plaindatetime.prototype.round
description: Rounding for roundingIncrement option
info: |
sec-temporal-totemporalroundingincrement step 7:
7. Set _increment_ to floor(ℝ(_increment_)).
ToTemporalRoundingIncrement ( _normalizedOptions_ )
1. Let _increment_ be ? GetOption(_normalizedOptions_, *"roundingIncrement"*, *"number"*, *undefined*, *1*<sub>𝔽</sub>).
2. If _increment_ is not finite, throw a *RangeError* exception.
3. Let _integerIncrement_ be truncate(ℝ(_increment_)).
4. If _integerIncrement_ < 1 or _integerIncrement_ > 10<sup>9</sup>, throw a *RangeError* exception.
5. Return _integerIncrement_.
includes: [temporalHelpers.js]
features: [Temporal]
---*/

const datetime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 0, 0, 5);
const result = datetime.round({ smallestUnit: "nanosecond", roundingIncrement: 2.5 });
TemporalHelpers.assertPlainDateTime(result, 2000, 5, "M05", 2, 12, 34, 56, 0, 0, 6, "roundingIncrement 2.5 floors to 2");
const result = datetime.round({ smallestUnit: "nanosecond", roundingIncrement: 2.5, roundingMode: "expand" });
TemporalHelpers.assertPlainDateTime(result, 2000, 5, "M05", 2, 12, 34, 56, 0, 0, 6, "roundingIncrement 2.5 truncates to 2");
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,20 @@
esid: sec-temporal.plaindatetime.prototype.round
description: RangeError thrown when roundingIncrement option out of range
info: |
sec-temporal-totemporalroundingincrement step 6:
6. If _increment_ < 1 or _increment_ > _maximum_, throw a *RangeError* exception.
ToTemporalRoundingIncrement ( _normalizedOptions_ )
1. Let _increment_ be ? GetOption(_normalizedOptions_, *"roundingIncrement"*, *"number"*, *undefined*, *1*<sub>𝔽</sub>).
2. If _increment_ is not finite, throw a *RangeError* exception.
3. Let _integerIncrement_ be truncate(ℝ(_increment_)).
4. If _integerIncrement_ < 1 or _integerIncrement_ > 10<sup>9</sup>, throw a *RangeError* exception.
5. Return _integerIncrement_.
features: [Temporal]
---*/

const datetime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 0, 0, 5);
assert.throws(RangeError, () => datetime.round({ smallestUnit: "nanoseconds", roundingIncrement: -Infinity }));
assert.throws(RangeError, () => datetime.round({ smallestUnit: "nanoseconds", roundingIncrement: -1 }));
assert.throws(RangeError, () => datetime.round({ smallestUnit: "nanoseconds", roundingIncrement: 0 }));
assert.throws(RangeError, () => datetime.round({ smallestUnit: "nanoseconds", roundingIncrement: 0.9 }));
assert.throws(RangeError, () => datetime.round({ smallestUnit: "nanoseconds", roundingIncrement: 1e9 + 1 }));
assert.throws(RangeError, () => datetime.round({ smallestUnit: "nanoseconds", roundingIncrement: Infinity }));
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,20 @@
esid: sec-temporal.plaindatetime.prototype.since
description: Rounding for roundingIncrement option
info: |
sec-temporal-totemporalroundingincrement step 7:
7. Set _increment_ to floor(ℝ(_increment_)).
ToTemporalRoundingIncrement ( _normalizedOptions_ )
1. Let _increment_ be ? GetOption(_normalizedOptions_, *"roundingIncrement"*, *"number"*, *undefined*, *1*<sub>𝔽</sub>).
2. If _increment_ is not finite, throw a *RangeError* exception.
3. Let _integerIncrement_ be truncate(ℝ(_increment_)).
4. If _integerIncrement_ < 1 or _integerIncrement_ > 10<sup>9</sup>, throw a *RangeError* exception.
5. Return _integerIncrement_.
includes: [temporalHelpers.js]
features: [Temporal]
---*/

const earlier = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 0, 0, 0);
const later = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 0, 0, 5);
const result = later.since(earlier, { roundingIncrement: 2.5 });
TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, "roundingIncrement 2.5 floors to 2");
const result = later.since(earlier, { roundingIncrement: 2.5, roundingMode: "trunc" });
TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, "roundingIncrement 2.5 truncates to 2");
const result2 = later.since(earlier, { smallestUnit: "days", roundingIncrement: 1e9 + 0.5, roundingMode: "expand" });
TemporalHelpers.assertDuration(result2, 0, 0, 0, 1e9, 0, 0, 0, 0, 0, 0, "roundingIncrement 1e9 + 0.5 truncates to 1e9");
Loading

0 comments on commit e7364ea

Please sign in to comment.