Test rounding mode in Duration strings with fractional units

https://github.com/tc39/proposal-temporal/pull/1907 was a bug that caused
negative Duration strings with fractional units to be rounded incorrectly.
Add tests that ensure the rounding mode is correct.

This was a normative change that achieved consensus at the December 2021
TC39 meeting.
This commit is contained in:
Philip Chimento 2022-01-17 15:54:59 -08:00 committed by Rick Waldron
parent 9af34ce28c
commit 7b45a862b1
12 changed files with 204 additions and 0 deletions

View File

@ -0,0 +1,20 @@
// 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.duration.compare
description: Strings with fractional duration units are rounded with the correct rounding mode
features: [Temporal]
---*/
const expectedPos = new Temporal.Duration(0, 0, 0, 0, 1, 1, 52, 500);
const expectedNeg = new Temporal.Duration(0, 0, 0, 0, -1, -1, -52, -500);
assert.sameValue(Temporal.Duration.compare("PT1.03125H", expectedPos), 0,
"positive fractional units rounded with correct rounding mode (first argument)");
assert.sameValue(Temporal.Duration.compare("-PT1.03125H", expectedNeg), 0,
"negative fractional units rounded with correct rounding mode (first argument)");
assert.sameValue(Temporal.Duration.compare(expectedPos, "PT1.03125H"), 0,
"positive fractional units rounded with correct rounding mode (second argument)");
assert.sameValue(Temporal.Duration.compare(expectedNeg, "-PT1.03125H"), 0,
"negative fractional units rounded with correct rounding mode (second argument)");

View File

@ -0,0 +1,28 @@
// 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.duration.from
description: Strings with fractional duration units are rounded with the correct rounding mode
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const resultPosHours = Temporal.Duration.from("PT1.03125H");
TemporalHelpers.assertDuration(resultPosHours, 0, 0, 0, 0, 1, 1, 52, 500, 0, 0,
"positive fractional hours rounded with correct rounding mode");
const resultNegHours = Temporal.Duration.from("-PT1.03125H");
TemporalHelpers.assertDuration(resultNegHours, 0, 0, 0, 0, -1, -1, -52, -500, 0, 0,
"negative fractional hours rounded with correct rounding mode");
// The following input should not round, but may fail if an implementation does
// floating point arithmetic too early:
const resultPosSeconds = Temporal.Duration.from("PT46H66M71.50040904S");
TemporalHelpers.assertDuration(resultPosSeconds, 0, 0, 0, 0, 46, 66, 71, 500, 409, 40,
"positive fractional seconds not rounded");
const resultNegSeconds = Temporal.Duration.from("-PT46H66M71.50040904S");
TemporalHelpers.assertDuration(resultNegSeconds, 0, 0, 0, 0, -46, -66, -71, -500, -409, -40,
"negative fractional seconds not rounded");

View File

@ -0,0 +1,16 @@
// 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.duration.prototype.add
description: Strings with fractional duration units are rounded with the correct rounding mode
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const blank = new Temporal.Duration();
TemporalHelpers.assertDuration(blank.add("PT1.03125H"), 0, 0, 0, 0, 1, 1, 52, 500, 0, 0,
"positive fractional units rounded with correct rounding mode");
TemporalHelpers.assertDuration(blank.add("-PT1.03125H"), 0, 0, 0, 0, -1, -1, -52, -500, 0, 0,
"negative fractional units rounded with correct rounding mode");

View File

@ -0,0 +1,16 @@
// 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.duration.prototype.subtract
description: Strings with fractional duration units are rounded with the correct rounding mode
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const blank = new Temporal.Duration();
TemporalHelpers.assertDuration(blank.subtract("PT1.03125H"), 0, 0, 0, 0, -1, -1, -52, -500, 0, 0,
"positive fractional units rounded with correct rounding mode");
TemporalHelpers.assertDuration(blank.subtract("-PT1.03125H"), 0, 0, 0, 0, 1, 1, 52, 500, 0, 0,
"negative fractional units rounded with correct rounding mode");

View File

@ -0,0 +1,15 @@
// 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.instant.prototype.add
description: Strings with fractional duration units are rounded with the correct rounding mode
features: [Temporal]
---*/
const epoch = new Temporal.Instant(0n);
assert.sameValue(epoch.add("PT1.03125H").epochNanoseconds, 3712_500_000_000n,
"positive fractional units rounded with correct rounding mode");
assert.sameValue(epoch.add("-PT1.03125H").epochNanoseconds, -3712_500_000_000n,
"negative fractional units rounded with correct rounding mode");

View File

@ -0,0 +1,15 @@
// 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.instant.prototype.subtract
description: Strings with fractional duration units are rounded with the correct rounding mode
features: [Temporal]
---*/
const epoch = new Temporal.Instant(0n);
assert.sameValue(epoch.subtract("PT1.03125H").epochNanoseconds, -3712_500_000_000n,
"positive fractional units rounded with correct rounding mode");
assert.sameValue(epoch.subtract("-PT1.03125H").epochNanoseconds, 3712_500_000_000n,
"negative fractional units rounded with correct rounding mode");

View File

@ -0,0 +1,16 @@
// 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.plaindatetime.prototype.add
description: Strings with fractional duration units are rounded with the correct rounding mode
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const datetime = new Temporal.PlainDateTime(2000, 5, 2);
TemporalHelpers.assertPlainDateTime(datetime.add("PT1.03125H"), 2000, 5, "M05", 2, 1, 1, 52, 500, 0, 0,
"positive fractional units rounded with correct rounding mode");
TemporalHelpers.assertPlainDateTime(datetime.add("-PT1.03125H"), 2000, 5, "M05", 1, 22, 58, 7, 500, 0, 0,
"negative fractional units rounded with correct rounding mode");

View File

@ -0,0 +1,16 @@
// 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.plaindatetime.prototype.subtract
description: Strings with fractional duration units are rounded with the correct rounding mode
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const datetime = new Temporal.PlainDateTime(2000, 5, 2);
TemporalHelpers.assertPlainDateTime(datetime.subtract("PT1.03125H"), 2000, 5, "M05", 1, 22, 58, 7, 500, 0, 0,
"positive fractional units rounded with correct rounding mode");
TemporalHelpers.assertPlainDateTime(datetime.subtract("-PT1.03125H"), 2000, 5, "M05", 2, 1, 1, 52, 500, 0, 0,
"negative fractional units rounded with correct rounding mode");

View File

@ -0,0 +1,16 @@
// 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.plaintime.prototype.add
description: Strings with fractional duration units are rounded with the correct rounding mode
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const midnight = new Temporal.PlainTime();
TemporalHelpers.assertPlainTime(midnight.add("PT1.03125H"), 1, 1, 52, 500, 0, 0,
"positive fractional units rounded with correct rounding mode");
TemporalHelpers.assertPlainTime(midnight.add("-PT1.03125H"), 22, 58, 7, 500, 0, 0,
"negative fractional units rounded with correct rounding mode");

View File

@ -0,0 +1,16 @@
// 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.plaintime.prototype.subtract
description: Strings with fractional duration units are rounded with the correct rounding mode
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const midnight = new Temporal.PlainTime();
TemporalHelpers.assertPlainTime(midnight.subtract("PT1.03125H"), 22, 58, 7, 500, 0, 0,
"positive fractional units rounded with correct rounding mode");
TemporalHelpers.assertPlainTime(midnight.subtract("-PT1.03125H"), 1, 1, 52, 500, 0, 0,
"negative fractional units rounded with correct rounding mode");

View File

@ -0,0 +1,15 @@
// 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.add
description: Strings with fractional duration units are rounded with the correct rounding mode
features: [Temporal]
---*/
const epoch = new Temporal.ZonedDateTime(0n, "UTC");
assert.sameValue(epoch.add("PT1.03125H").epochNanoseconds, 3712_500_000_000n,
"positive fractional units rounded with correct rounding mode");
assert.sameValue(epoch.add("-PT1.03125H").epochNanoseconds, -3712_500_000_000n,
"negative fractional units rounded with correct rounding mode");

View File

@ -0,0 +1,15 @@
// 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.subtract
description: Strings with fractional duration units are rounded with the correct rounding mode
features: [Temporal]
---*/
const epoch = new Temporal.ZonedDateTime(0n, "UTC");
assert.sameValue(epoch.subtract("PT1.03125H").epochNanoseconds, -3712_500_000_000n,
"positive fractional units rounded with correct rounding mode");
assert.sameValue(epoch.subtract("-PT1.03125H").epochNanoseconds, 3712_500_000_000n,
"negative fractional units rounded with correct rounding mode");