Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Temporal: Tests for balancing units after rounding #3956

Merged
merged 2 commits into from
Nov 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// 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 can cross unit boundaries up to the implicit largestUnit
includes: [temporalHelpers.js]
features: [Temporal]
---*/

const relativeTo = new Temporal.PlainDate(2022, 1, 1);
const roundingMode = "expand";

// Positive, date units
{
const duration = new Temporal.Duration(1, 11, 0, 24);
const result = duration.round({ smallestUnit: "months", roundingMode, relativeTo });
TemporalHelpers.assertDuration(result, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, "1 year 12 months balances to 2 years");
}

// Negative, date units
{
const duration = new Temporal.Duration(-1, -11, 0, -24);
const result = duration.round({ smallestUnit: "months", roundingMode, relativeTo });
TemporalHelpers.assertDuration(result, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, "-1 year -12 months balances to -2 years");
}

// Positive, time units
{
const duration = new Temporal.Duration(0, 0, 0, 0, 1, 59, 59, 900);
const result = duration.round({ smallestUnit: "seconds", roundingMode });
TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, "1:59:60 balances to 2 hours");
}

// Negative, time units
{
const duration = new Temporal.Duration(0, 0, 0, 0, -1, -59, -59, -900);
const result = duration.round({ smallestUnit: "seconds", roundingMode });
TemporalHelpers.assertDuration(result, 0, 0, 0, 0, -2, 0, 0, 0, 0, 0, "-1:59:60 balances to -2 hours");
}

// No balancing if smallest unit is largest unit
{
const duration = new Temporal.Duration(0, 11, 0, 24);
const result = duration.round({ smallestUnit: "months", roundingMode, relativeTo });
TemporalHelpers.assertDuration(result, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, "12 months stays as is");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// 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.tostring
description: Rounding can cross unit boundaries up to days
features: [Temporal]
---*/

const roundingMode = "expand";

// Positive, time units
{
const duration = new Temporal.Duration(0, 0, 0, 0, 1, 59, 59, 900);
assert.sameValue(duration.toString({ fractionalSecondDigits: 0, roundingMode }), "PT2H0S", "1:59:60 balances to 2 hours");
}

// Negative, time units
{
const duration = new Temporal.Duration(0, 0, 0, 0, -1, -59, -59, -900);
assert.sameValue(duration.toString({ fractionalSecondDigits: 0, roundingMode }), "-PT2H0S", "-1:59:60 balances to -2 hours");
}

// Positive, date and time units
{
const duration = new Temporal.Duration(1, 11, 0, 30, 23, 59, 59, 999, 999, 999);
assert.sameValue(duration.toString({ fractionalSecondDigits: 8, roundingMode }), "P1Y11M31DT0.00000000S", "units balance only up to days (positive)");
}

// Negative, date and time units
{
const duration = new Temporal.Duration(-1, -11, 0, -30, -23, -59, -59, -999, -999, -999);
assert.sameValue(duration.toString({ fractionalSecondDigits: 8, roundingMode }), "-P1Y11M31DT0.00000000S", "units balance only up to days (negative)");
}

// No balancing if smallest unit is largest unit
{
const duration = new Temporal.Duration(0, 0, 0, 0, 0, 0, 59, 900);
assert.sameValue(duration.toString({ fractionalSecondDigits: 0, roundingMode }), "PT60S", "60 seconds stays as is");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// 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.instant.prototype.since
description: Rounding can cross unit boundaries up to largestUnit
includes: [temporalHelpers.js]
features: [Temporal]
---*/

const earlier = new Temporal.Instant(0n);
const later = new Temporal.Instant(7199_000_000_000n);
const duration = earlier.since(later, { largestUnit: "hours", smallestUnit: "minutes", roundingMode: "expand" });
TemporalHelpers.assertDuration(duration, 0, 0, 0, 0, -2, 0, 0, 0, 0, 0, "-1:59 balances to -2 hours");
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// 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.instant.prototype.until
description: Rounding can cross unit boundaries up to largestUnit
includes: [temporalHelpers.js]
features: [Temporal]
---*/

const earlier = new Temporal.Instant(0n);
const later = new Temporal.Instant(7199_000_000_000n);
const duration = earlier.until(later, { largestUnit: "hours", smallestUnit: "minutes", roundingMode: "expand" });
TemporalHelpers.assertDuration(duration, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, "1:59 balances to 2 hours");
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,13 @@ const expectedOpsForYearRounding = expected.concat([
"call this.calendar.dateAdd", // 7.g
"call this.calendar.dateUntil", // 7.o
"call this.calendar.dateAdd", // 7.y MoveRelativeDate
]); // (7.s not called because other units can't add up to >1 year at this point)
// (7.s not called because other units can't add up to >1 year at this point)
// BalanceDurationRelative
"call this.calendar.dateAdd", // 11.c MoveRelativeDate
"call this.calendar.dateAdd", // 11.g MoveRelativeDate
"call this.calendar.dateAdd", // 11.k
"call this.calendar.dateUntil" // 11.n
]);
instance.since(otherDatePropertyBag, createOptionsObserver({ smallestUnit: "years" }));
assert.compareArray(actual, expectedOpsForYearRounding, "order of operations with smallestUnit = years");
actual.splice(0); // clear
Expand All @@ -159,7 +165,13 @@ const expectedOpsForYearRoundingSameMonth = expected.concat([
"call this.calendar.dateAdd", // 7.e
"call this.calendar.dateAdd", // 7.g
"call this.calendar.dateAdd", // 7.y MoveRelativeDate
]); // (7.o not called because months and weeks == 0)
// (7.o not called because months and weeks == 0)
// BalanceDurationRelative
"call this.calendar.dateAdd", // 11.c MoveRelativeDate
"call this.calendar.dateAdd", // 11.g MoveRelativeDate
"call this.calendar.dateAdd", // 11.k
"call this.calendar.dateUntil" // 11.n
]);
instance.since(otherDatePropertyBagSameMonth, createOptionsObserver({ smallestUnit: "years" }));
assert.compareArray(actual, expectedOpsForYearRoundingSameMonth, "order of operations with smallestUnit = years and no excess months/weeks");
actual.splice(0); // clear
Expand All @@ -175,7 +187,10 @@ const expectedOpsForMonthRounding = expected.concat([
"call this.calendar.dateAdd", // 10.c
"call this.calendar.dateAdd", // 10.e
"call this.calendar.dateAdd", // 10.k MoveRelativeDate
]); // (10.n.iii MoveRelativeDate not called because weeks == 0)
// (10.n.iii MoveRelativeDate not called because weeks == 0)
// BalanceDurationRelative
"call this.calendar.dateAdd", // 12.b MoveRelativeDate
]);
instance.since(otherDatePropertyBag, createOptionsObserver({ smallestUnit: "months" }));
assert.compareArray(actual, expectedOpsForMonthRounding, "order of operations with smallestUnit = months");
actual.splice(0); // clear
Expand All @@ -189,6 +204,9 @@ const expectedOpsForWeekRounding = expected.concat([
"call this.calendar.dateUntil",
// RoundDuration
"call this.calendar.dateAdd", // 11.d MoveRelativeDate
]); // (11.g.iii MoveRelativeDate not called because days already balanced)
// (11.g.iii MoveRelativeDate not called because days already balanced)
// BalanceDurationRelative
"call this.calendar.dateAdd", // 13.c MoveRelativeDate
]);
instance.since(otherDatePropertyBag, createOptionsObserver({ smallestUnit: "weeks" }));
assert.compareArray(actual, expectedOpsForWeekRounding, "order of operations with smallestUnit = weeks");
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// 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.plaindate.prototype.since
description: Rounding can cross unit boundaries up to largestUnit
includes: [temporalHelpers.js]
features: [Temporal]
---*/

const earlier = new Temporal.PlainDate(2022, 1, 1);
const later = new Temporal.PlainDate(2023, 12, 25);
const duration = earlier.since(later, { largestUnit: "years", smallestUnit: "months", roundingMode: "expand" });
TemporalHelpers.assertDuration(duration, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, "-1 year -11 months balances to -2 years");
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,13 @@ const expectedOpsForYearRounding = expected.concat([
"call this.calendar.dateAdd", // 7.g
"call this.calendar.dateUntil", // 7.o
"call this.calendar.dateAdd", // 7.y MoveRelativeDate
]); // (7.s not called because other units can't add up to >1 year at this point)
// (7.s not called because other units can't add up to >1 year at this point)
// BalanceDurationRelative
"call this.calendar.dateAdd", // 11.c MoveRelativeDate
"call this.calendar.dateAdd", // 11.g MoveRelativeDate
"call this.calendar.dateAdd", // 11.k
"call this.calendar.dateUntil" // 11.n
]);
instance.until(otherDatePropertyBag, createOptionsObserver({ smallestUnit: "years" }));
assert.compareArray(actual, expectedOpsForYearRounding, "order of operations with smallestUnit = years");
actual.splice(0); // clear
Expand All @@ -160,7 +166,13 @@ const expectedOpsForYearRoundingSameMonth = expected.concat([
"call this.calendar.dateAdd", // 7.e
"call this.calendar.dateAdd", // 7.g
"call this.calendar.dateAdd", // 7.y MoveRelativeDate
]); // (7.o not called because months and weeks == 0)
// (7.o not called because months and weeks == 0)
// BalanceDurationRelative
"call this.calendar.dateAdd", // 11.c MoveRelativeDate
"call this.calendar.dateAdd", // 11.g MoveRelativeDate
"call this.calendar.dateAdd", // 11.k
"call this.calendar.dateUntil" // 11.n
]);
instance.until(otherDatePropertyBagSameMonth, createOptionsObserver({ smallestUnit: "years" }));
assert.compareArray(actual, expectedOpsForYearRoundingSameMonth, "order of operations with smallestUnit = years and no excess months/weeks");
actual.splice(0); // clear
Expand All @@ -176,7 +188,10 @@ const expectedOpsForMonthRounding = expected.concat([
"call this.calendar.dateAdd", // 10.c
"call this.calendar.dateAdd", // 10.e
"call this.calendar.dateAdd", // 10.k MoveRelativeDate
]); // (10.n.iii MoveRelativeDate not called because weeks == 0)
// (10.n.iii MoveRelativeDate not called because weeks == 0)
// BalanceDurationRelative
"call this.calendar.dateAdd", // 12.b MoveRelativeDate
]);
instance.until(otherDatePropertyBag, createOptionsObserver({ smallestUnit: "months" }));
assert.compareArray(actual, expectedOpsForMonthRounding, "order of operations with smallestUnit = months");
actual.splice(0); // clear
Expand All @@ -190,6 +205,9 @@ const expectedOpsForWeekRounding = expected.concat([
"call this.calendar.dateUntil",
// RoundDuration
"call this.calendar.dateAdd", // 11.d MoveRelativeDate
]); // (11.g.iii MoveRelativeDate not called because days already balanced)
// (11.g.iii MoveRelativeDate not called because days already balanced)
// BalanceDurationRelative
"call this.calendar.dateAdd", // 13.c MoveRelativeDate
]);
instance.until(otherDatePropertyBag, createOptionsObserver({ smallestUnit: "weeks" }));
assert.compareArray(actual, expectedOpsForWeekRounding, "order of operations with smallestUnit = weeks");
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// 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.plaindate.prototype.until
description: Rounding can cross unit boundaries up to largestUnit
includes: [temporalHelpers.js]
features: [Temporal]
---*/

const earlier = new Temporal.PlainDate(2022, 1, 1);
const later = new Temporal.PlainDate(2023, 12, 25);
const duration = earlier.until(later, { largestUnit: "years", smallestUnit: "months", roundingMode: "expand" });
TemporalHelpers.assertDuration(duration, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, "1 year 11 months balances to 2 years");
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,13 @@ const expectedOpsForYearRounding = expected.concat([
"call this.calendar.dateAdd", // 7.g
"call this.calendar.dateUntil", // 7.o
"call this.calendar.dateAdd", // 7.y MoveRelativeDate
]); // (7.s not called because other units can't add up to >1 year at this point)
// (7.s not called because other units can't add up to >1 year at this point)
// BalanceDurationRelative
"call this.calendar.dateAdd", // 11.c MoveRelativeDate
"call this.calendar.dateAdd", // 11.g MoveRelativeDate
"call this.calendar.dateAdd", // 11.k
"call this.calendar.dateUntil" // 11.n
]);
instance.since(otherDateTimePropertyBag, createOptionsObserver({ smallestUnit: "years" }));
assert.compareArray(actual, expectedOpsForYearRounding, "order of operations with smallestUnit = years");
actual.splice(0); // clear
Expand Down Expand Up @@ -195,7 +201,13 @@ const expectedOpsForYearRoundingSameMonth = expected.concat([
"call this.calendar.dateAdd", // 7.e
"call this.calendar.dateAdd", // 7.g
"call this.calendar.dateAdd", // 7.y MoveRelativeDate
]); // (7.o not called because months and weeks == 0)
// (7.o not called because months and weeks == 0)
// BalanceDurationRelative
"call this.calendar.dateAdd", // 11.c MoveRelativeDate
"call this.calendar.dateAdd", // 11.g MoveRelativeDate
"call this.calendar.dateAdd", // 11.k
"call this.calendar.dateUntil" // 11.n
]);
instance.until(otherDatePropertyBagSameMonth, createOptionsObserver({ smallestUnit: "years" }));
assert.compareArray(actual, expectedOpsForYearRoundingSameMonth, "order of operations with smallestUnit = years and no excess months/weeks");
actual.splice(0); // clear
Expand All @@ -211,7 +223,10 @@ const expectedOpsForMonthRounding = expected.concat([
"call this.calendar.dateAdd", // 10.c
"call this.calendar.dateAdd", // 10.e
"call this.calendar.dateAdd", // 10.k MoveRelativeDate
]); // (10.n.iii MoveRelativeDate not called because weeks == 0)
// (10.n.iii MoveRelativeDate not called because weeks == 0)
// BalanceDurationRelative
"call this.calendar.dateAdd", // 12.b MoveRelativeDate
]);
instance.since(otherDateTimePropertyBag, createOptionsObserver({ smallestUnit: "months" }));
assert.compareArray(actual, expectedOpsForMonthRounding, "order of operations with smallestUnit = months");
actual.splice(0); // clear
Expand All @@ -225,6 +240,9 @@ const expectedOpsForWeekRounding = expected.concat([
"call this.calendar.dateUntil",
// RoundDuration
"call this.calendar.dateAdd", // 11.d MoveRelativeDate
]); // (11.g.iii MoveRelativeDate not called because days already balanced)
// (11.g.iii MoveRelativeDate not called because days already balanced)
// BalanceDurationRelative
"call this.calendar.dateAdd", // 13.c MoveRelativeDate
]);
instance.since(otherDateTimePropertyBag, createOptionsObserver({ smallestUnit: "weeks" }));
assert.compareArray(actual, expectedOpsForWeekRounding, "order of operations with smallestUnit = weeks");
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// 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.plaindatetime.prototype.since
description: Rounding can cross unit boundaries up to largestUnit
includes: [temporalHelpers.js]
features: [Temporal]
---*/

// Date units
{
const earlier = new Temporal.PlainDateTime(2022, 1, 1);
const later = new Temporal.PlainDateTime(2023, 12, 25);
const duration = earlier.since(later, { largestUnit: "years", smallestUnit: "months", roundingMode: "expand" });
TemporalHelpers.assertDuration(duration, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, "-1 year -11 months balances to -2 years");
}

// Time units
{
const earlier = new Temporal.PlainDateTime(2000, 5, 2);
const later = new Temporal.PlainDateTime(2000, 5, 2, 1, 59, 59);
const duration = earlier.since(later, { largestUnit: "hours", smallestUnit: "minutes", roundingMode: "expand" });
TemporalHelpers.assertDuration(duration, 0, 0, 0, 0, -2, 0, 0, 0, 0, 0, "-1:59 balances to -2 hours");
}

// Both
{
const earlier = new Temporal.PlainDateTime(1970, 1, 1);
const later = new Temporal.PlainDateTime(1971, 12, 31, 23, 59, 59, 999, 999, 999);
const duration = earlier.since(later, { largestUnit: "years", smallestUnit: "microseconds", roundingMode: "expand" });
TemporalHelpers.assertDuration(duration, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, "rounding down 1 ns balances to -2 years");
}
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,13 @@ const expectedOpsForYearRounding = expected.concat([
"call this.calendar.dateAdd", // 7.g
"call this.calendar.dateUntil", // 7.o
"call this.calendar.dateAdd", // 7.y MoveRelativeDate
]); // (7.s not called because other units can't add up to >1 year at this point)
// (7.s not called because other units can't add up to >1 year at this point)
// BalanceDurationRelative
"call this.calendar.dateAdd", // 11.c MoveRelativeDate
"call this.calendar.dateAdd", // 11.g MoveRelativeDate
"call this.calendar.dateAdd", // 11.k
"call this.calendar.dateUntil" // 11.n
]);
instance.until(otherDateTimePropertyBag, createOptionsObserver({ smallestUnit: "years" }));
assert.compareArray(actual, expectedOpsForYearRounding, "order of operations with smallestUnit = years");
actual.splice(0); // clear
Expand Down Expand Up @@ -195,7 +201,13 @@ const expectedOpsForYearRoundingSameMonth = expected.concat([
"call this.calendar.dateAdd", // 7.e
"call this.calendar.dateAdd", // 7.g
"call this.calendar.dateAdd", // 7.y MoveRelativeDate
]); // (7.o not called because months and weeks == 0)
// (7.o not called because months and weeks == 0)
// BalanceDurationRelative
"call this.calendar.dateAdd", // 11.c MoveRelativeDate
"call this.calendar.dateAdd", // 11.g MoveRelativeDate
"call this.calendar.dateAdd", // 11.k
"call this.calendar.dateUntil" // 11.n
]);
instance.until(otherDatePropertyBagSameMonth, createOptionsObserver({ smallestUnit: "years" }));
assert.compareArray(actual, expectedOpsForYearRoundingSameMonth, "order of operations with smallestUnit = years and no excess months/weeks");
actual.splice(0); // clear
Expand All @@ -211,7 +223,10 @@ const expectedOpsForMonthRounding = expected.concat([
"call this.calendar.dateAdd", // 10.c
"call this.calendar.dateAdd", // 10.e
"call this.calendar.dateAdd", // 10.k MoveRelativeDate
]); // (10.n.iii MoveRelativeDate not called because weeks == 0)
// (10.n.iii MoveRelativeDate not called because weeks == 0)
// BalanceDurationRelative
"call this.calendar.dateAdd", // 12.b MoveRelativeDate
]);
instance.until(otherDateTimePropertyBag, createOptionsObserver({ smallestUnit: "months" }));
assert.compareArray(actual, expectedOpsForMonthRounding, "order of operations with smallestUnit = years");
actual.splice(0); // clear
Expand All @@ -225,6 +240,9 @@ const expectedOpsForWeekRounding = expected.concat([
"call this.calendar.dateUntil",
// RoundDuration
"call this.calendar.dateAdd", // 11.d MoveRelativeDate
]); // (11.g.iii MoveRelativeDate not called because days already balanced)
// (11.g.iii MoveRelativeDate not called because days already balanced)
// BalanceDurationRelative
"call this.calendar.dateAdd", // 13.c MoveRelativeDate
]);
instance.until(otherDateTimePropertyBag, createOptionsObserver({ smallestUnit: "weeks" }));
assert.compareArray(actual, expectedOpsForWeekRounding, "order of operations with smallestUnit = weeks");
Loading