Temporal: PlainDateTime: Port Demitasse until and since tests

Co-authored-by: Philip Chimento <philip.chimento@gmail.com>
This commit is contained in:
Jesse Alama 2022-03-25 12:40:12 +01:00 committed by Philip Chimento
parent 84679fd7ed
commit 33a5433d1b
44 changed files with 1111 additions and 38 deletions

View File

@ -0,0 +1,17 @@
// 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.since
description: Plain objects are accepted as an argument
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const dt = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789);
TemporalHelpers.assertDuration(
dt.since({ year: 2019, month: 10, day: 29, hour: 10 }),
0, 0, 0, -15684, -18, -36, -29, -876, -543, -211,
"casts argument (plain object)"
);

View File

@ -0,0 +1,17 @@
// 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.since
description: Date-like string arguments are acceptable
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const dt = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789);
TemporalHelpers.assertDuration(
dt.since("2019-10-29T10:46:38.271986102"),
0, 0, 0, -15684, -19, -23, -8, -148, -529, -313,
"casts argument (string)"
);

View File

@ -0,0 +1,17 @@
// 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.since
description: Fail if the argument is a PlainDateTime with a different calendar
features: [Temporal]
---*/
const dt1 = new Temporal.PlainDateTime(2000, 1, 1, 0, 0, 0, 0, 0, 0);
const dt2 = new Temporal.PlainDateTime(2000, 1, 1, 0, 0, 0, 0, 0, 0, {});
assert.throws(
RangeError,
() => dt1.since(dt2),
"different calendars not allowed"
);

View File

@ -0,0 +1,30 @@
// 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.since
description: Do not return Durations with unnecessary units
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const feb2 = new Temporal.PlainDateTime(2020, 2, 2, 0, 0);
const feb28 = new Temporal.PlainDateTime(2021, 2, 28, 0, 0);
TemporalHelpers.assertDuration(
feb28.since(feb2),
0, 0, 0, 392, 0, 0, 0, 0, 0, 0,
"does not include higher units than necessary (no largest unit)"
);
TemporalHelpers.assertDuration(
feb28.since(feb2, { largestUnit: "months" }),
0, 12, 0, 26, 0, 0, 0, 0, 0, 0,
"does not include higher units than necessary (largest unit = months)"
);
TemporalHelpers.assertDuration(
feb28.since(feb2, { largestUnit: "years" }),
1, 0, 0, 26, 0, 0, 0, 0, 0, 0,
"does not include higher units than necessary (largest unit = years)"
);

View File

@ -0,0 +1,24 @@
// 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.since
description: Empty objects are acceptable
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const feb20 = new Temporal.PlainDateTime(2020, 2, 1, 0, 0);
const feb21 = new Temporal.PlainDateTime(2021, 2, 1, 0, 0);
TemporalHelpers.assertDuration(
feb21.since(feb20, {}),
0, 0, 0, 366, 0, 0, 0, 0, 0, 0,
"empty plain object options"
);
TemporalHelpers.assertDuration(
feb21.since(feb20, () => {}),
0, 0, 0, 366, 0, 0, 0, 0, 0, 0,
"empty function object options"
);

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.plaindatetime.prototype.since
description: A variety of bad options (type error thrown)
features: [Temporal, Symbol]
---*/
const feb20 = new Temporal.PlainDateTime(2020, 2, 1, 0, 0);
const feb21 = new Temporal.PlainDateTime(2021, 2, 1, 0, 0);
const badOptions = [null, 1, 'hello', true, Symbol('foo'), 1n];
badOptions.forEach((bad) => {
assert.throws(
TypeError,
() => feb21.since(feb20, bad),
`bad options (${typeof bad})`
);
});

View File

@ -0,0 +1,44 @@
// 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.since
description: Days are the default level of specificity
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const feb_1_2020 = new Temporal.PlainDateTime(2020, 2, 1, 0, 0);
const feb_1_2021 = new Temporal.PlainDateTime(2021, 2, 1, 0, 0);
TemporalHelpers.assertDuration(
feb_1_2021.since(feb_1_2020),
0, 0, 0, 366, 0, 0, 0, 0, 0, 0,
"defaults to returning days (no options)"
);
TemporalHelpers.assertDuration(
feb_1_2021.since(feb_1_2020, { largestUnit: "auto" }),
0, 0, 0, 366, 0, 0, 0, 0, 0, 0,
"defaults to returning days (largest unit = auto)"
);
TemporalHelpers.assertDuration(
feb_1_2021.since(feb_1_2020, { largestUnit: "days" }),
0, 0, 0, 366, 0, 0, 0, 0, 0, 0,
"defaults to returning days (largest unit = days)"
);
const dt = new Temporal.PlainDateTime(2020, 2, 1, 0, 0, 0, 0, 0, 1);
TemporalHelpers.assertDuration(
dt.since(feb_1_2020),
0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
"defaults to returning days (nanosecond)"
);
TemporalHelpers.assertDuration(
feb_1_2021.since(dt),
0, 0, 0, 365, 23, 59, 59, 999, 999, 999,
"defaults to returning days (nanosecond)"
);

View File

@ -0,0 +1,24 @@
// 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.since
description: Values are rounded relative to the receiver
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const dt1 = new Temporal.PlainDateTime(2019, 1, 1);
const dt2 = new Temporal.PlainDateTime(2020, 7, 2);
TemporalHelpers.assertDuration(
dt2.since(dt1, { smallestUnit: "years", roundingMode: "halfExpand" }),
1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
"rounds relative to the receiver (positive case)"
);
TemporalHelpers.assertDuration(
dt1.since(dt2, { smallestUnit: "years", roundingMode: "halfExpand" }),
-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
"rounds relative to the receiver (negative case)"
);

View File

@ -0,0 +1,48 @@
// 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.since
description: Round to different smallest increments
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const earlier = new Temporal.PlainDateTime(2019, 1, 8, 8, 22, 36, 123, 456, 789);
const later = new Temporal.PlainDateTime(2021, 9, 7, 12, 39, 40, 987, 654, 321);
TemporalHelpers.assertDuration(
later.since(earlier, { smallestUnit: "hours", roundingIncrement: 3, roundingMode: "halfExpand" }),
0, 0, 0, 973, 3, 0, 0, 0, 0, 0,
"rounds to an increment of hours"
);
TemporalHelpers.assertDuration(
later.since(earlier, { smallestUnit: "minutes", roundingIncrement: 30, roundingMode: "halfExpand" }),
0, 0, 0, 973, 4, 30, 0, 0, 0,0,
"rounds to an increment of minutes"
);
TemporalHelpers.assertDuration(
later.since(earlier, { smallestUnit: "seconds", roundingIncrement: 15, roundingMode: "halfExpand" }),
0, 0, 0, 973, 4, 17, 0, 0, 0, 0,
"rounds to an increment of seconds"
);
TemporalHelpers.assertDuration(
later.since(earlier, { smallestUnit: "milliseconds", roundingIncrement: 10, roundingMode: "halfExpand" }),
0, 0, 0, 973, 4, 17, 4, 860, 0, 0,
"rounds to an increment of milliseconds"
);
TemporalHelpers.assertDuration(
later.since(earlier, { smallestUnit: "microseconds", roundingIncrement: 10, roundingMode: "halfExpand" }),
0, 0, 0, 973, 4, 17, 4, 864, 200, 0,
"rounds to an increment of microseconds"
);
TemporalHelpers.assertDuration(
later.since(earlier, { smallestUnit: "nanoseconds", roundingIncrement: 10, roundingMode: "halfExpand" }),
0, 0, 0, 973, 4, 17, 4, 864, 197, 530,
"rounds to an increment of nanoseconds"
);

View File

@ -0,0 +1,39 @@
// 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.since
description: Rounding argument cleanly divides the relevant smallest unit
features: [Temporal]
---*/
const earlier = new Temporal.PlainDateTime(2019, 1, 8, 8, 22, 36, 123, 456, 789);
const later = new Temporal.PlainDateTime(2021, 9, 7, 12, 39, 40, 987, 654, 321);
[1, 2, 3, 4, 6, 8, 12].forEach((roundingIncrement) => {
const options = { smallestUnit: "hours", roundingIncrement };
assert(
later.since(earlier, options) instanceof Temporal.Duration,
`valid hour increments divide into 24 (rounding increment = ${roundingIncrement}, smallest unit = hours)`
);
});
["minutes", "seconds"].forEach((smallestUnit) => {
[1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30].forEach((roundingIncrement) => {
const options = { smallestUnit, roundingIncrement };
assert(
later.since(earlier, options) instanceof Temporal.Duration,
`valid ${smallestUnit} increments divide into 60 (rounding increment = ${roundingIncrement})`
);
});
});
["milliseconds", "microseconds", "nanoseconds"].forEach((smallestUnit) => {
[1, 2, 4, 5, 8, 10, 20, 25, 40, 50, 100, 125, 200, 250, 500].forEach((roundingIncrement) => {
const options = { smallestUnit, roundingIncrement };
assert(
later.since(earlier, options) instanceof Temporal.Duration,
`valid ${smallestUnit} increments divide into 1000 (rounding increment = ${roundingIncrement})`
);
});
});

View File

@ -0,0 +1,45 @@
// 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.since
description: Throw if rounding increment does not cleanly divide the relevant unit
features: [Temporal]
---*/
const earlier = new Temporal.PlainDateTime(2019, 1, 8, 8, 22, 36, 123, 456, 789);
const later = new Temporal.PlainDateTime(2021, 9, 7, 12, 39, 40, 987, 654, 321);
const badIncrements = {
"hours": 11,
"minutes": 29,
"seconds": 29,
"milliseconds": 29,
"microseconds": 29,
"nanoseconds": 29
};
Object.entries(badIncrements).forEach(([unit, bad]) => {
assert.throws(
RangeError,
() => later.since(earlier, { smallestUnit: unit, roundingIncrement: bad }),
`throws on increments that do not divide evenly into the next highest (unit = ${unit}, increment = ${bad})`
);
});
const fullIncrements = {
"hours": 24,
"minutes": 60,
"seconds": 60,
"milliseconds": 1000,
"microseconds": 1000,
"nanoseconds": 1000
};
Object.entries(fullIncrements).forEach(([unit, bad]) => {
assert.throws(
RangeError,
() => later.since(earlier, { smallestUnit: unit, roundingIncrement: bad }),
`throws on increments that are equal to the next highest (unit = ${unit}, rounding increment = ${bad}`
);
});

View File

@ -0,0 +1,40 @@
// 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.since
description: Ceiling rounding mode basic tests
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const earlier = new Temporal.PlainDateTime(2019, 1, 8, 8, 22, 36, 123, 456, 789);
const later = new Temporal.PlainDateTime(2021, 9, 7, 12, 39, 40, 987, 654, 321);
const incrementOneCeil = [
["years", [3], [-2]],
["months", [0, 32], [0, -31]],
["weeks", [0, 0, 140], [0, 0, -139]],
["days", [0, 0, 0, 974], [0, 0, 0, -973]],
["hours", [0, 0, 0, 973, 5], [0, 0, 0, -973, -4]],
["minutes", [0, 0, 0, 973, 4, 18], [0, 0, 0, -973, -4, -17]],
["seconds", [0, 0, 0, 973, 4, 17, 5], [0, 0, 0, -973, -4, -17, -4]],
["milliseconds", [0, 0, 0, 973, 4, 17, 4, 865], [0, 0, 0, -973, -4, -17, -4, -864]],
["microseconds", [0, 0, 0, 973, 4, 17, 4, 864, 198], [0, 0, 0, -973, -4, -17, -4, -864, -197]],
["nanoseconds", [0, 0, 0, 973, 4, 17, 4, 864, 197, 532], [0, 0, 0, -973, -4, -17, -4, -864, -197, -532]]
];
const roundingMode = "ceil";
incrementOneCeil.forEach(([smallestUnit, expectedPositive, expectedNegative]) => {
const [py, pm = 0, pw = 0, pd = 0, ph = 0, pmin = 0, ps = 0, pms = 0, pµs = 0, pns = 0] = expectedPositive;
const [ny, nm = 0, nw = 0, nd = 0, nh = 0, nmin = 0, ns = 0, nms = 0, nµs = 0, nns = 0] = expectedNegative;
TemporalHelpers.assertDuration(
earlier.until(later, { smallestUnit, roundingMode }),
py, pm, pw, pd, ph, pmin, ps, pms, pµs, pns,
`rounds up to ${smallestUnit} (roundingMode = ceil, positive case)`
);
TemporalHelpers.assertDuration(
later.until(earlier, { smallestUnit, roundingMode }),
ny, nm, nw, nd, nh, nmin, ns, nms, nµs, nns,
`rounds up to ${smallestUnit} (rounding mode = ceil, negative case)`
);
});

View File

@ -0,0 +1,42 @@
// 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.since
description: Floor rounding mode basic tests
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const earlier = new Temporal.PlainDateTime(2019, 1, 8, 8, 22, 36, 123, 456, 789);
const later = new Temporal.PlainDateTime(2021, 9, 7, 12, 39, 40, 987, 654, 321);
const incrementOneFloor = [
["years", [2], [-3]],
["months", [0, 31], [0, -32]],
["weeks", [0, 0, 139], [0, 0, -140]],
["days", [0, 0, 0, 973], [0, 0, 0, -974]],
["hours", [0, 0, 0, 973, 4], [0, 0, 0, -973, -5]],
["minutes", [0, 0, 0, 973, 4, 17], [0, 0, 0, -973, -4, -18]],
["seconds", [0, 0, 0, 973, 4, 17, 4], [0, 0, 0, -973, -4, -17, -5]],
["milliseconds", [0, 0, 0, 973, 4, 17, 4, 864], [0, 0, 0, -973, -4, -17, -4, -865]],
["microseconds", [0, 0, 0, 973, 4, 17, 4, 864, 197], [0, 0, 0, -973, -4, -17, -4, -864, -198]],
["nanoseconds", [0, 0, 0, 973, 4, 17, 4, 864, 197, 532], [0, 0, 0, -973, -4, -17, -4, -864, -197, -532]]
];
const roundingMode = "floor";
incrementOneFloor.forEach(([smallestUnit, expectedPositive, expectedNegative]) => {
const [py, pm = 0, pw = 0, pd = 0, ph = 0, pmin = 0, ps = 0, pms = 0, pµs = 0, pns = 0] = expectedPositive;
const [ny, nm = 0, nw = 0, nd = 0, nh = 0, nmin = 0, ns = 0, nms = 0, nµs = 0, nns = 0] = expectedNegative;
TemporalHelpers.assertDuration(
later.since(earlier, { smallestUnit, roundingMode }),
py, pm, pw, pd, ph, pmin, ps, pms, pµs, pns,
`rounds down to ${smallestUnit} (rounding mode = ${roundingMode}, positive case)`
);
TemporalHelpers.assertDuration(
earlier.since(later, { smallestUnit, roundingMode }),
ny, nm, nw, nd, nh, nmin, ns, nms, nµs, nns,
`rounds down to ${smallestUnit} (rounding mode = ${roundingMode}, negative case)`
);
});

View File

@ -0,0 +1,52 @@
// 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.since
description: Half-expand rounding mode basic tests
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const earlier = new Temporal.PlainDateTime(2019, 1, 8, 8, 22, 36, 123, 456, 789);
const later = new Temporal.PlainDateTime(2021, 9, 7, 12, 39, 40, 987, 654, 321);
function ensureUnsignedZero(x) {
return Object.is(x, -0) ? 0 : x;
}
const incrementOneNearest = [
["years", [3]],
["months", [0, 32]],
["weeks", [0, 0, 139]],
["days", [0, 0, 0, 973]],
["hours", [0, 0, 0, 973, 4]],
["minutes", [0, 0, 0, 973, 4, 17]],
["seconds", [0, 0, 0, 973, 4, 17, 5]],
["milliseconds", [0, 0, 0, 973, 4, 17, 4, 864]],
["microseconds", [0, 0, 0, 973, 4, 17, 4, 864, 198]],
["nanoseconds", [0, 0, 0, 973, 4, 17, 4, 864, 197, 532]]
];
const roundingMode = "halfExpand";
incrementOneNearest.forEach(([smallestUnit, expected]) => {
const [y, m = 0, w = 0, d = 0, h = 0, min = 0, s = 0, ms = 0, µs = 0, ns = 0] = expected;
TemporalHelpers.assertDuration(
later.since(earlier, { smallestUnit, roundingMode }),
y, m, w, d, h, min, s, ms, µs, ns,
`rounds to nearest ${smallestUnit} (rounding mode = ${roundingMode}, positive case)`
);
TemporalHelpers.assertDuration(
earlier.since(later, { smallestUnit, roundingMode }),
ensureUnsignedZero(-y),
ensureUnsignedZero(-m),
ensureUnsignedZero(-w),
ensureUnsignedZero(-d),
ensureUnsignedZero(-h),
ensureUnsignedZero(-min),
ensureUnsignedZero(-s),
ensureUnsignedZero(-ms),
ensureUnsignedZero(-µs),
ensureUnsignedZero(-ns),
`rounds to nearest ${smallestUnit} (rounding mode = ${roundingMode}, negative case)`
);
});

View File

@ -0,0 +1,30 @@
// 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.since
description: A different default for largest unit will be used if smallest unit is larger than "days"
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const earlier = new Temporal.PlainDateTime(2019, 1, 8, 8, 22, 36, 123, 456, 789);
const later = new Temporal.PlainDateTime(2021, 9, 7, 12, 39, 40, 987, 654, 321);
TemporalHelpers.assertDuration(
later.since(earlier, { smallestUnit: "years", roundingMode: "halfExpand" }),
3, 0, 0, 0, 0, 0, 0, 0, 0,0,
"assumes a different default for largestUnit if smallestUnit is larger than days (smallest unit = years)"
);
TemporalHelpers.assertDuration(
later.since(earlier, { smallestUnit: "months", roundingMode: "halfExpand" }),
0, 32, 0, 0, 0, 0, 0, 0, 0, 0,
"assumes a different default for largestUnit if smallestUnit is larger than days (smallest unit = months)"
);
TemporalHelpers.assertDuration(
later.since(earlier, { smallestUnit: "weeks", roundingMode: "halfExpand" }),
0, 0, 139, 0, 0, 0, 0, 0, 0, 0,
"assumes a different default for largestUnit if smallestUnit is larger than days (smallest unit = weeks)"
);

View File

@ -0,0 +1,54 @@
// 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.since
description: Truncation rounding mode basic tests
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const earlier = new Temporal.PlainDateTime(2019, 1, 8, 8, 22, 36, 123, 456, 789);
const later = new Temporal.PlainDateTime(2021, 9, 7, 12, 39, 40, 987, 654, 321);
function ensureUnsignedZero(x) {
return Object.is(x, -0) ? 0 : x;
}
const incrementOneTrunc = [
["years", [2]],
["months", [0, 31]],
["weeks", [0, 0, 139]],
["days", [0, 0, 0, 973]],
["hours", [0, 0, 0, 973, 4]],
["minutes", [0, 0, 0, 973, 4, 17]],
["seconds", [0, 0, 0, 973, 4, 17, 4]],
["milliseconds", [0, 0, 0, 973, 4, 17, 4, 864]],
["microseconds", [0, 0, 0, 973, 4, 17, 4, 864, 197]],
["nanoseconds", [0, 0, 0, 973, 4, 17, 4, 864, 197, 532]]
];
const roundingMode = "trunc";
incrementOneTrunc.forEach(([smallestUnit, expected]) => {
const [y, m = 0, w = 0, d = 0, h = 0, min = 0, s = 0, ms = 0, µs = 0, ns = 0] = expected;
TemporalHelpers.assertDuration(
later.since(earlier, { smallestUnit, roundingMode }),
y, m, w, d, h, min, s, ms, µs, ns,
`truncates to ${smallestUnit} (rounding mode = ${roundingMode}, positive case)`
);
TemporalHelpers.assertDuration(
earlier.since(later, { smallestUnit, roundingMode }),
ensureUnsignedZero(-y),
ensureUnsignedZero(-m),
ensureUnsignedZero(-w),
ensureUnsignedZero(-d),
ensureUnsignedZero(-h),
ensureUnsignedZero(-min),
ensureUnsignedZero(-s),
ensureUnsignedZero(-ms),
ensureUnsignedZero(-µs),
ensureUnsignedZero(-ns),
`truncates to ${smallestUnit} (rounding mode = ${roundingMode}, negative case)`
);
});

View File

@ -0,0 +1,24 @@
// 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.since
description: Truncation (trunc) is the default rounding mode
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const earlier = new Temporal.PlainDateTime(2019, 1, 8, 8, 22, 36, 123, 456, 789);
const later = new Temporal.PlainDateTime(2021, 9, 7, 12, 39, 40, 987, 654, 321);
TemporalHelpers.assertDuration(
later.since(earlier, { smallestUnit: "minutes" }),
0, 0, 0, 973, 4, 17, 0, 0, 0, 0,
"trunc is the default (round up)"
);
TemporalHelpers.assertDuration(
later.since(earlier, { smallestUnit: "seconds" }),
0, 0, 0, 973, 4, 17, 4, 0, 0, 0,
"trunc is the default (round down)"
);

View File

@ -0,0 +1,30 @@
// 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.since
description: Returned granularity may be finer than seconds
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const feb20 = new Temporal.PlainDateTime(2020, 2, 1, 0, 0);
const feb21 = new Temporal.PlainDateTime(2020, 2, 2, 0, 0, 0, 250, 250, 250);
TemporalHelpers.assertDuration(
feb21.since(feb20, { largestUnit: "milliseconds" }),
0, 0, 0, 0, 0, 0, 0, 86400250, 250, 250,
"can return subseconds (milliseconds)"
);
TemporalHelpers.assertDuration(
feb21.since(feb20, { largestUnit: "microseconds" }),
0, 0, 0, 0, 0, 0, 0, 0, 86400250250, 250,
"can return subseconds (microseconds)"
);
TemporalHelpers.assertDuration(
feb21.since(feb20, { largestUnit: "nanoseconds" }),
0, 0, 0, 0, 0, 0, 0, 0, 0, 86400250250250,
"can return subseconds (nanoseconds)"
);

View File

@ -0,0 +1,24 @@
// 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.since
description: Weeks and months are mutually exclusive
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const dt = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789);
const laterDateTime = dt.add({ days: 42, hours: 3 });
TemporalHelpers.assertDuration(
laterDateTime.since(dt, { largestUnit: "weeks" }),
0, 0, 6, 0, 3, 0, 0, 0, 0, 0,
"weeks and months are mutually exclusive (prefer weeks)"
);
TemporalHelpers.assertDuration(
laterDateTime.since(dt, { largestUnit: "months" }),
0, 1, 0, 12, 3, 0, 0, 0,0, 0,
"weeks and months are mutually exclusive (prefer months)"
);

View File

@ -0,0 +1,17 @@
// 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.until
description: Plain objects are accepted as an argument
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const dt = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789);
TemporalHelpers.assertDuration(
dt.until({ year: 2019, month: 10, day: 29, hour: 10 }),
0, 0, 0, 15684, 18, 36, 29, 876, 543, 211,
"casts argument (plain object)"
);

View File

@ -0,0 +1,17 @@
// 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.until
description: Date-like strings are accepted
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const dt = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789);
TemporalHelpers.assertDuration(
dt.until("2019-10-29T10:46:38.271986102"),
0, 0, 0, 15684, 19, 23, 8, 148, 529, 313,
"casts argument (string)"
);

View File

@ -25,10 +25,10 @@ features: [Temporal]
const earlier1 = new Temporal.PlainDateTime(2000, 5, 2, 9);
const later1 = new Temporal.PlainDateTime(2000, 5, 5, 10);
const result1 = later1.until(earlier1, { largestUnit: 'day' });
const result1 = later1.until(earlier1, { largestUnit: "day" });
TemporalHelpers.assertDuration(result1, 0, 0, 0, -3, -1, 0, 0, 0, 0, 0, "date sign == time sign");
const earlier2 = new Temporal.PlainDateTime(2000, 5, 2, 10);
const later2 = new Temporal.PlainDateTime(2000, 5, 5, 9);
const result2 = later2.until(earlier2, { largestUnit: 'day' });
const result2 = later2.until(earlier2, { largestUnit: "day" });
TemporalHelpers.assertDuration(result2, 0, 0, 0, -2, -23, 0, 0, 0, 0, 0, "date sign != time sign");

View File

@ -8,18 +8,18 @@ includes: [temporalHelpers.js]
features: [Temporal]
---*/
const a = Temporal.PlainDateTime.from('2017-10-05T08:07:14+00:00[UTC]');
const b = Temporal.PlainDateTime.from('2021-03-05T03:32:45+00:00[UTC]');
const c = Temporal.PlainDateTime.from('2021-03-05T09:32:45+00:00[UTC]');
const a = Temporal.PlainDateTime.from("2017-10-05T08:07:14+00:00[UTC]");
const b = Temporal.PlainDateTime.from("2021-03-05T03:32:45+00:00[UTC]");
const c = Temporal.PlainDateTime.from("2021-03-05T09:32:45+00:00[UTC]");
const r1 = a.until(b, { largestUnit: 'months' });
const r1 = a.until(b, { largestUnit: "months" });
TemporalHelpers.assertDuration(r1, 0, 40, 0, 27, 19, 25, 31, 0, 0, 0, "r1");
assert.sameValue(a.add(r1).toString(), b.toString(), "a.add(r1)");
const r2 = b.until(a, { largestUnit: 'months' });
const r2 = b.until(a, { largestUnit: "months" });
TemporalHelpers.assertDuration(r2, 0, -40, 0, -30, -19, -25, -31, 0, 0, 0, "r2");
assert.sameValue(b.add(r2).toString(), a.toString(), "b.add(r2)");
const r3 = c.until(a, { largestUnit: 'months' });
const r3 = c.until(a, { largestUnit: "months" });
TemporalHelpers.assertDuration(r3, 0, -41, 0, 0, -1, -25, -31, 0, 0, 0, "r3");
assert.sameValue(c.add(r3).toString(), a.toString(), "c.add(r3)");

View File

@ -8,12 +8,7 @@ features: [Temporal]
---*/
const dt1 = new Temporal.PlainDateTime(2000, 1, 1, 0, 0, 0, 0, 0, 0);
const cal = {
id: 'thisisnotiso'
};
const dt2 = new Temporal.PlainDateTime(2000, 1, 1, 0, 0, 0, 0, 0, 0, cal);
const dt2 = new Temporal.PlainDateTime(2000, 1, 1, 0, 0, 0, 0, 0, 0, {});
assert.throws(
RangeError,

View File

@ -8,17 +8,17 @@ features: [Temporal]
includes: [temporalHelpers.js]
---*/
const lastFeb20 = new Temporal.PlainDateTime(2020, 2, 29, 0, 0);
const lastFeb21 = new Temporal.PlainDateTime(2021, 2, 28, 0, 0);
const feb29 = new Temporal.PlainDateTime(2020, 2, 29, 0, 0);
const feb28 = new Temporal.PlainDateTime(2021, 2, 28, 0, 0);
TemporalHelpers.assertDuration(
lastFeb20.until(lastFeb21, { largestUnit: "months" }),
feb29.until(feb28, { largestUnit: "months" }),
0, 12, 0, 0, 0, 0, 0, 0, 0, 0,
"does not include higher units than necessary (largest unit = months)"
);
TemporalHelpers.assertDuration(
lastFeb20.until(lastFeb21, { largestUnit: "years" }),
feb29.until(feb28, { largestUnit: "years" }),
1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
"does not include higher units than necessary (largest unit = years)"
);

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.plaindatetime.prototype.until
description: Empty options are valid
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const feb20 = new Temporal.PlainDateTime(2020, 2, 1, 0, 0);
const feb21 = new Temporal.PlainDateTime(2021, 2, 1, 0, 0);
TemporalHelpers.assertDuration(feb20.until(feb21, {}),
0, 0, 0, 366, 0, 0, 0, 0, 0, 0,
"empty options (plain object) are acceptable");
TemporalHelpers.assertDuration(feb20.until(feb21, () => {}),
0, 0, 0, 366, 0, 0, 0, 0, 0, 0,
"empty options (function object) are acceptable");

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.plaindatetime.prototype.until
description: A variety of invalid option arguments
features: [Temporal, Symbol]
---*/
const feb20 = new Temporal.PlainDateTime(2020, 2, 1, 0, 0);
const feb21 = new Temporal.PlainDateTime(2021, 2, 1, 0, 0);
const badOptions = [null, 1, 'obviously invalid', true, Symbol('foo'), 1n];
badOptions.forEach((bad) => {
assert.throws(
TypeError,
() => feb20.until(feb21, bad),
`unacceptable options (${typeof bad})`
);
});

View File

@ -0,0 +1,25 @@
// 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.until
description: Rounding happens relative to receiver
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const dt1 = new Temporal.PlainDateTime(2019, 1, 1);
const dt2 = new Temporal.PlainDateTime(2020, 7, 2);
const options = { smallestUnit: "years", roundingMode: "halfExpand" };
TemporalHelpers.assertDuration(
dt1.until(dt2, options),
2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
"rounds relative to the receiver (positive case)"
);
TemporalHelpers.assertDuration(
dt2.until(dt1, options),
-1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
"rounds relative to the receiver (negative case)"
);

View File

@ -0,0 +1,48 @@
// 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.until
description: A variety of rounding increments
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const earlier = new Temporal.PlainDateTime(2019, 1, 8, 8, 22, 36, 123, 456, 789);
const later = new Temporal.PlainDateTime(2021, 9, 7, 12, 39, 40, 987, 654, 321);
TemporalHelpers.assertDuration(
earlier.until(later, {smallestUnit: "hours", roundingIncrement: 3, roundingMode: "halfExpand"}),
0, 0, 0, 973, 3, 0, 0, 0, 0, 0,
"rounds to an increment of hours"
);
TemporalHelpers.assertDuration(
earlier.until(later, {smallestUnit: "minutes", roundingIncrement: 30, roundingMode: "halfExpand"}),
0, 0, 0, 973, 4, 30, 0, 0, 0, 0,
"rounds to an increment of minutes"
);
TemporalHelpers.assertDuration(
earlier.until(later, {smallestUnit: "seconds", roundingIncrement: 15, roundingMode: "halfExpand"}),
0, 0, 0, 973, 4, 17, 0, 0, 0, 0,
"rounds to an increment of seconds"
);
TemporalHelpers.assertDuration(
earlier.until(later, {smallestUnit: "milliseconds", roundingIncrement: 10, roundingMode: "halfExpand"}),
0, 0, 0, 973, 4, 17, 4, 860, 0, 0,
"rounds to an increment of milliseconds"
);
TemporalHelpers.assertDuration(
earlier.until(later, {smallestUnit: "microseconds", roundingIncrement: 10, roundingMode: "halfExpand"}),
0, 0, 0, 973, 4, 17, 4, 864, 200, 0,
"rounds to an increment of microseconds"
);
TemporalHelpers.assertDuration(
earlier.until(later, {smallestUnit: "nanoseconds", roundingIncrement: 10, roundingMode: "halfExpand"}),
0, 0, 0, 973, 4, 17, 4, 864, 197, 530,
"rounds to an increment of nanoseconds"
);

View File

@ -0,0 +1,39 @@
// 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.until
description: Rounding increments that cleanly divide relevant units
features: [Temporal]
---*/
const earlier = new Temporal.PlainDateTime(2019, 1, 8, 8, 22, 36, 123, 456, 789);
const later = new Temporal.PlainDateTime(2021, 9, 7, 12, 39, 40, 987, 654, 321);
[1, 2, 3, 4, 6, 8, 12].forEach((roundingIncrement) => {
const options = {smallestUnit: "hours", roundingIncrement};
assert(
earlier.until(later, options) instanceof Temporal.Duration,
`valid hour increments divide 24 (rounding increment = ${roundingIncrement})`
);
});
["minutes", "seconds"].forEach((smallestUnit) => {
[1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30].forEach((roundingIncrement) => {
const options = {smallestUnit, roundingIncrement};
assert(
earlier.until(later, options) instanceof Temporal.Duration,
`valid ${smallestUnit} increments divide 60 (rounding increment = ${roundingIncrement})`
);
});
});
["milliseconds", "microseconds", "nanoseconds"].forEach((smallestUnit) => {
[1, 2, 4, 5, 8, 10, 20, 25, 40, 50, 100, 125, 200, 250, 500].forEach((roundingIncrement) => {
const options = {smallestUnit, roundingIncrement};
assert(
earlier.until(later, options) instanceof Temporal.Duration,
`valid ${smallestUnit} increments divide 1000 (rounding increment = ${roundingIncrement}`
);
});
});

View File

@ -0,0 +1,45 @@
// 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.until
description: Rounding increments that do not cleanly divide the relevant unit
features: [Temporal]
---*/
const earlier = new Temporal.PlainDateTime(2019, 1, 8, 8, 22, 36, 123, 456, 789);
const later = new Temporal.PlainDateTime(2021, 9, 7, 12, 39, 40, 987, 654, 321);
const nondivisibleUnits = {
"hours": 11,
"minutes": 29,
"seconds": 29,
"milliseconds": 29,
"microseconds": 29,
"nanoseconds": 29
};
Object.entries(nondivisibleUnits).forEach(([unit, increment]) => {
assert.throws(
RangeError,
() => earlier.until(later, {smallestUnit: unit, roundingIncrement: increment}),
`throws on increments that do not divide evenly into the next highest (unit = ${unit}, increment = ${increment})`
);
});
const equalDivisibleUnits = {
"hours": 24,
"minutes": 60,
"seconds": 60,
"milliseconds": 1000,
"microseconds": 1000,
"nanoseconds": 1000
};
Object.entries(equalDivisibleUnits).forEach(([unit, increment]) => {
assert.throws(
RangeError,
() => earlier.until(later, {smallestUnit: unit, roundingIncrement: increment}),
`throws on increments that are equal to the next highest (unit = ${unit}, rounding increment = ${increment})`
);
});

View File

@ -0,0 +1,39 @@
// 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.until
description: Checking that ceiling rounding mode rounds correctly
features: [Temporal]
includes: [temporalHelpers.js]
---*/
const earlier = new Temporal.PlainDateTime(2019, 1, 8, 8, 22, 36, 123, 456, 789);
const later = new Temporal.PlainDateTime(2021, 9, 7, 12, 39, 40, 987, 654, 321);
const incrementOneCeil = [
["years", [3], [-2]],
["months", [0, 32], [0, -31]],
["weeks", [0, 0, 140], [0, 0, -139]],
["days", [0, 0, 0, 974], [0, 0, 0, -973]],
["hours", [0, 0, 0, 973, 5], [0, 0, 0, -973, -4]],
["minutes", [0, 0, 0, 973, 4, 18], [0, 0, 0, -973, -4, -17]],
["seconds", [0, 0, 0, 973, 4, 17, 5], [0, 0, 0, -973, -4, -17, -4]],
["milliseconds", [0, 0, 0, 973, 4, 17, 4, 865], [0, 0, 0, -973, -4, -17, -4, -864]],
["microseconds", [0, 0, 0, 973, 4, 17, 4, 864, 198], [0, 0, 0, -973, -4, -17, -4, -864, -197]],
["nanoseconds", [0, 0, 0, 973, 4, 17, 4, 864, 197, 532], [0, 0, 0, -973, -4, -17, -4, -864, -197, -532]]
];
incrementOneCeil.forEach(([smallestUnit, expectedPositive, expectedNegative]) => {
const [py, pm = 0, pw = 0, pd = 0, ph = 0, pmin = 0, ps = 0, pms = 0, pµs = 0, pns = 0] = expectedPositive;
const [ny, nm = 0, nw = 0, nd = 0, nh = 0, nmin = 0, ns = 0, nms = 0, nµs = 0, nns = 0] = expectedNegative;
TemporalHelpers.assertDuration(
earlier.until(later, { smallestUnit, roundingMode: "ceil" }),
py, pm, pw, pd, ph, pmin, ps, pms, pµs, pns,
`rounds up to ${smallestUnit} (roundingMode = ceil, positive case)`
);
TemporalHelpers.assertDuration(
later.until(earlier, {smallestUnit, roundingMode: "ceil"}),
ny, nm, nw, nd, nh, nmin, ns, nms, nµs, nns,
`rounds up to ${smallestUnit} (rounding mode = ceil, negative case)`
);
});

View File

@ -0,0 +1,39 @@
// 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.until
description: Checking that floor rounding mode rounds correctly
features: [Temporal]
includes: [temporalHelpers.js]
---*/
const earlier = new Temporal.PlainDateTime(2019, 1, 8, 8, 22, 36, 123, 456, 789);
const later = new Temporal.PlainDateTime(2021, 9, 7, 12, 39, 40, 987, 654, 321);
const incrementOneFloor = [
["years", [2], [-3]],
["months", [0, 31], [0, -32]],
["weeks", [0, 0, 139], [0, 0, -140]],
["days", [0, 0, 0, 973], [0, 0, 0, -974]],
["hours", [0, 0, 0, 973, 4], [0, 0, 0, -973, -5]],
["minutes", [0, 0, 0, 973, 4, 17], [0, 0, 0, -973, -4, -18]],
["seconds", [0, 0, 0, 973, 4, 17, 4], [0, 0, 0, -973, -4, -17, -5]],
["milliseconds", [0, 0, 0, 973, 4, 17, 4, 864], [0, 0, 0, -973, -4, -17, -4, -865]],
["microseconds", [0, 0, 0, 973, 4, 17, 4, 864, 197], [0, 0, 0, -973, -4, -17, -4, -864, -198]],
["nanoseconds", [0, 0, 0, 973, 4, 17, 4, 864, 197, 532], [0, 0, 0, -973, -4, -17, -4, -864, -197, -532]]
];
incrementOneFloor.forEach(([smallestUnit, expectedPositive, expectedNegative]) => {
const [py, pm = 0, pw = 0, pd = 0, ph = 0, pmin = 0, ps = 0, pms = 0, pµs = 0, pns = 0] = expectedPositive;
const [ny, nm = 0, nw = 0, nd = 0, nh = 0, nmin = 0, ns = 0, nms = 0, nµs = 0, nns = 0] = expectedNegative;
TemporalHelpers.assertDuration(
earlier.until(later, { smallestUnit, roundingMode: "floor" }),
py, pm, pw, pd, ph, pmin, ps, pms, pµs, pns,
`rounds down to ${smallestUnit} (rounding mode = floor, positive case)`
);
TemporalHelpers.assertDuration(
later.until(earlier, {smallestUnit, roundingMode: "floor"}),
ny, nm, nw, nd, nh, nmin, ns, nms, nµs, nns,
`rounds down to ${smallestUnit} (rounding mode = floor, negative case)`
);
});

View File

@ -0,0 +1,51 @@
// 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.until
description: Checking that half-expand rounding mode rounds correctly
features: [Temporal]
includes: [temporalHelpers.js]
---*/
const earlier = new Temporal.PlainDateTime(2019, 1, 8, 8, 22, 36, 123, 456, 789);
const later = new Temporal.PlainDateTime(2021, 9, 7, 12, 39, 40, 987, 654, 321);
function ensureUnsignedZero(x) {
return Object.is(x, -0) ? 0 : x;
}
const incrementOneNearest = [
["years", [3]],
["months", [0, 32]],
["weeks", [0, 0, 139]],
["days", [0, 0, 0, 973]],
["hours", [0, 0, 0, 973, 4]],
["minutes", [0, 0, 0, 973, 4, 17]],
["seconds", [0, 0, 0, 973, 4, 17, 5]],
["milliseconds", [0, 0, 0, 973, 4, 17, 4, 864]],
["microseconds", [0, 0, 0, 973, 4, 17, 4, 864, 198]],
["nanoseconds", [0, 0, 0, 973, 4, 17, 4, 864, 197, 532]]
];
incrementOneNearest.forEach(([smallestUnit, expected]) => {
const [y, m = 0, w = 0, d = 0, h = 0, min = 0, s = 0, ms = 0, µs = 0, ns = 0] = expected;
TemporalHelpers.assertDuration(
earlier.until(later, {smallestUnit, roundingMode: "halfExpand"}),
y, m, w, d, h, min, s, ms, µs, ns,
`rounds to nearest ${smallestUnit} (positive case, rounding mode = halfExpand)`
);
TemporalHelpers.assertDuration(
later.until(earlier, {smallestUnit, roundingMode: "halfExpand"}),
ensureUnsignedZero(-y),
ensureUnsignedZero(-m),
ensureUnsignedZero(-w),
ensureUnsignedZero(-d),
ensureUnsignedZero(-h),
ensureUnsignedZero(-min),
ensureUnsignedZero(-s),
ensureUnsignedZero(-ms),
ensureUnsignedZero(-µs),
ensureUnsignedZero(-ns),
`rounds to nearest ${smallestUnit} (negative case, rounding mode = halfExpand)`
);
});

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.plaindatetime.prototype.until
description: A different default for largest unit will be used if smallest unit is larger than "days"
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const earlier = new Temporal.PlainDateTime(2019, 1, 8, 8, 22, 36, 123, 456, 789);
const later = new Temporal.PlainDateTime(2021, 9, 7, 12, 39, 40, 987, 654, 321);
TemporalHelpers.assertDuration(
earlier.until(later, {smallestUnit: "years", roundingMode: "halfExpand"}),
3, 0, 0, 0, 0, 0, 0, 0, 0, 0,
"assumes a different default for largestUnit if smallestUnit is larger than days (largest unit = years)"
);
TemporalHelpers.assertDuration(
earlier.until(later, {smallestUnit: "months", roundingMode: "halfExpand"}),
0, 32, 0, 0, 0, 0, 0, 0, 0, 0,
"assumes a different default for largestUnit if smallestUnit is larger than days (largest unit = months)"
);
TemporalHelpers.assertDuration(
earlier.until(later, {smallestUnit: "weeks", roundingMode: "halfExpand"}),
0, 0, 139, 0, 0, 0, 0, 0, 0, 0,
"assumes a different default for largestUnit if smallestUnit is larger than days (largest unit = weeks)"
);

View File

@ -0,0 +1,51 @@
// 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.until
description: A variety of tests for truncation (trunc) round mode
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const earlier = new Temporal.PlainDateTime(2019, 1, 8, 8, 22, 36, 123, 456, 789);
const later = new Temporal.PlainDateTime(2021, 9, 7, 12, 39, 40, 987, 654, 321);
function ensureUnsignedZero(x) {
return Object.is(x, -0) ? 0 : x;
}
const incrementOneTrunc = [
["years", [2]],
["months", [0, 31]],
["weeks", [0, 0, 139]],
["days", [0, 0, 0, 973]],
["hours", [0, 0, 0, 973, 4]],
["minutes", [0, 0, 0, 973, 4, 17]],
["seconds", [0, 0, 0, 973, 4, 17, 4]],
["milliseconds", [0, 0, 0, 973, 4, 17, 4, 864]],
["microseconds", [0, 0, 0, 973, 4, 17, 4, 864, 197]],
["nanoseconds", [0, 0, 0, 973, 4, 17, 4, 864, 197, 532]]
];
incrementOneTrunc.forEach(([smallestUnit, expected]) => {
const [y, m = 0, w = 0, d = 0, h = 0, min = 0, s = 0, ms = 0, µs = 0, ns = 0] = expected;
TemporalHelpers.assertDuration(
earlier.until(later, {smallestUnit, roundingMode: "trunc"}),
y, m, w, d, h, min, s, ms, µs, ns,
`truncates to ${smallestUnit} (rounding mode = trunc, positive case)`
);
TemporalHelpers.assertDuration(
later.until(earlier, {smallestUnit, roundingMode: "trunc"}),
ensureUnsignedZero(-y),
ensureUnsignedZero(-m),
ensureUnsignedZero(-w),
ensureUnsignedZero(-d),
ensureUnsignedZero(-h),
ensureUnsignedZero(-min),
ensureUnsignedZero(-s),
ensureUnsignedZero(-ms),
ensureUnsignedZero(-µs),
ensureUnsignedZero(-ns),
`truncates to ${smallestUnit} (rounding mode = trunc, negative case)`
);
});

View File

@ -0,0 +1,24 @@
// 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.until
description: Show that truncation is the default rounding mode
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const earlier = new Temporal.PlainDateTime(2019, 1, 8, 8, 22, 36, 123, 456, 789);
const later = new Temporal.PlainDateTime(2021, 9, 7, 12, 39, 40, 987, 654, 321);
TemporalHelpers.assertDuration(
earlier.until(later, {smallestUnit: "minutes"}),
0, 0, 0, 973, 4, 17,0, 0, 0, 0,
"trunc is the default (round up)"
);
TemporalHelpers.assertDuration(
earlier.until(later, {smallestUnit: "seconds"}),
0, 0, 0, 973, 4, 17, 4, 0, 0, 0,
"trunc is the default (round down)"
);

View File

@ -3,34 +3,28 @@
/*---
esid: sec-temporal.plaindatetime.prototype.until
description: Largest unit is respected
description: Returned granularity may be finer than seconds
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const feb20 = new Temporal.PlainDateTime(2020, 2, 1, 0, 0);
const later = feb20.add({
days: 1,
milliseconds: 250,
microseconds: 250,
nanoseconds: 250
});
const feb21 = new Temporal.PlainDateTime(2020, 2, 2, 0, 0, 0, 250, 250, 250);
TemporalHelpers.assertDuration(
feb20.until(later, { largestUnit: "milliseconds" }),
feb20.until(feb21, { largestUnit: "milliseconds" }),
0, 0, 0, 0, 0, 0, 0, 86400250, 250, 250,
"can return subseconds (millisecond precision)"
);
TemporalHelpers.assertDuration(
feb20.until(later, { largestUnit: "microseconds" }),
feb20.until(feb21, { largestUnit: "microseconds" }),
0, 0, 0, 0, 0, 0, 0, 0, 86400250250, 250,
"can return subseconds (microsecond precision)"
);
TemporalHelpers.assertDuration(
feb20.until(later, { largestUnit: "nanoseconds" }),
feb20.until(feb21, { largestUnit: "nanoseconds" }),
0, 0, 0, 0, 0, 0, 0, 0, 0, 86400250250250,
"can return subseconds (nanosecond precision)"
);

View File

@ -14,11 +14,11 @@ const laterDateTime = dt.add({ days: 42, hours: 3 });
TemporalHelpers.assertDuration(
dt.until(laterDateTime, { largestUnit: "weeks" }),
0, 0, 6, 0, 3, 0, 0, 0, 0, 0,
"weeks and months mutually exclusive (1)"
"weeks and months mutually exclusive (prefer weeks)"
);
TemporalHelpers.assertDuration(
dt.until(laterDateTime, { largestUnit: "months" }),
0, 1, 0, 12, 3, 0, 0, 0, 0, 0,
"weeks and months mutually exclusive (2)"
"weeks and months mutually exclusive (prefer months)"
);

View File

@ -17,5 +17,5 @@ features: [Temporal]
TemporalHelpers.checkToTemporalCalendarFastPath((temporalObject, calendar) => {
const plainDateTime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321);
const result = plainDateTime.withCalendar(temporalObject);
assert.sameValue(result.calendar, calendar, 'Temporal object coerced to calendar');
assert.sameValue(result.calendar, calendar, "Temporal object coerced to calendar");
});

View File

@ -9,7 +9,7 @@ includes: [temporalHelpers.js]
---*/
const cal = {
id: 'thisisnotiso',
id: "thisisnotiso",
era() { return "the era"; },
eraYear() { return 1909; },
toString() { return "this is a string"; },

View File

@ -8,14 +8,14 @@ features: [Temporal]
---*/
const cal = {
id: 'foo',
id: "foo",
toString() { return "this is a string"; },
};
const dt = new Temporal.PlainDateTime(1995, 12, 7, 3, 24, 30, 0, 0, 0, cal);
const anotherCal = {
id: 'bar',
id: "bar",
toString() { return "this is another string"; },
};

View File

@ -32,7 +32,7 @@ ambiguousStrings.forEach((string) => {
assert.throws(
RangeError,
() => instance.withPlainTime(arg),
'space is not accepted as a substitute for T prefix'
"space is not accepted as a substitute for T prefix"
);
});

View File

@ -8,8 +8,8 @@ features: [Temporal, arrow-function]
---*/
const invalidStrings = [
'-000000-12-07T03:24:30',
'-000000-12-07T03:24:30+01:00[UTC]'
"-000000-12-07T03:24:30",
"-000000-12-07T03:24:30+01:00[UTC]"
];
const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321);
invalidStrings.forEach((arg) => {