Temporal: Fast-path differences between identical objects

This commit is contained in:
Philip Chimento 2023-03-09 16:29:20 -08:00 committed by Philip Chimento
parent 34ce4bd53a
commit 7a3944c0cc
16 changed files with 240 additions and 39 deletions

View File

@ -34,14 +34,21 @@ const expected = [
const actual = [];
const instance = new Temporal.Instant(1_000_000_000_000_000_000n);
instance.since(
TemporalHelpers.toPrimitiveObserver(actual, "1970-01-01T00:00Z", "other"),
TemporalHelpers.propertyBagObserver(actual, {
roundingIncrement: 1,
roundingMode: "halfExpand",
largestUnit: "hours",
smallestUnit: "minutes",
additional: true,
}, "options"),
);
const options = TemporalHelpers.propertyBagObserver(actual, {
roundingIncrement: 1,
roundingMode: "halfExpand",
largestUnit: "hours",
smallestUnit: "minutes",
additional: true,
}, "options");
instance.since(TemporalHelpers.toPrimitiveObserver(actual, "1970-01-01T00:00Z", "other"), options);
assert.compareArray(actual, expected, "order of operations");
actual.splice(0); // clear
// short-circuit does not skip reading options
instance.since(TemporalHelpers.toPrimitiveObserver(actual, "2001-09-09T01:46:40Z", "other"), options);
assert.compareArray(actual, expected, "order of operations with identical instants");
actual.splice(0); // clear

View File

@ -33,15 +33,22 @@ const expected = [
];
const actual = [];
const instance = new Temporal.Instant(0n);
instance.until(
TemporalHelpers.toPrimitiveObserver(actual, "2001-09-09T01:46:40Z", "other"),
TemporalHelpers.propertyBagObserver(actual, {
roundingIncrement: 1,
roundingMode: "halfExpand",
largestUnit: "hours",
smallestUnit: "minutes",
additional: true,
}, "options"),
);
const instance = new Temporal.Instant(1_000_000_000_000_000_000n);
const options = TemporalHelpers.propertyBagObserver(actual, {
roundingIncrement: 1,
roundingMode: "halfExpand",
largestUnit: "hours",
smallestUnit: "minutes",
additional: true,
}, "options");
instance.until(TemporalHelpers.toPrimitiveObserver(actual, "1970-01-01T00:00Z", "other"), options);
assert.compareArray(actual, expected, "order of operations");
actual.splice(0); // clear
// short-circuit does not skip reading options
instance.until(TemporalHelpers.toPrimitiveObserver(actual, "2001-09-09T01:46:40Z", "other"), options);
assert.compareArray(actual, expected, "order of operations with identical instants");
actual.splice(0); // clear

View File

@ -8,7 +8,7 @@ includes: [compareArray.js, temporalHelpers.js]
features: [Temporal]
---*/
const expected = [
const expectedMinimal = [
// ToTemporalDate
"get other.calendar",
"has other.calendar.dateAdd",
@ -72,10 +72,13 @@ const expected = [
"call options.roundingMode.toString",
"get options.smallestUnit.toString",
"call options.smallestUnit.toString",
];
const expected = expectedMinimal.concat([
// CalendarDateUntil
"get this.calendar.dateUntil",
"call this.calendar.dateUntil",
];
]);
const actual = [];
const ownCalendar = TemporalHelpers.calendarObserver(actual, "this.calendar");
@ -109,6 +112,19 @@ instance.since(otherDatePropertyBag, createOptionsObserver());
assert.compareArray(actual, expected, "order of operations");
actual.splice(0); // clear
// short-circuit for identical objects:
const identicalPropertyBag = TemporalHelpers.propertyBagObserver(actual, {
year: 2000,
month: 5,
monthCode: "M05",
day: 2,
calendar: TemporalHelpers.calendarObserver(actual, "other.calendar"),
}, "other");
instance.since(identicalPropertyBag, createOptionsObserver());
assert.compareArray(actual, expectedMinimal, "order of operations with identical dates");
actual.splice(0); // clear
// code path through RoundDuration that rounds to the nearest year:
const expectedOpsForYearRounding = expected.concat([
"get this.calendar.dateAdd", // 7.c.i

View File

@ -8,7 +8,7 @@ includes: [compareArray.js, temporalHelpers.js]
features: [Temporal]
---*/
const expected = [
const expectedMinimal = [
// ToTemporalDate
"get other.calendar",
"has other.calendar.dateAdd",
@ -72,10 +72,13 @@ const expected = [
"call options.roundingMode.toString",
"get options.smallestUnit.toString",
"call options.smallestUnit.toString",
];
const expected = expectedMinimal.concat([
// CalendarDateUntil
"get this.calendar.dateUntil",
"call this.calendar.dateUntil",
];
]);
const actual = [];
const ownCalendar = TemporalHelpers.calendarObserver(actual, "this.calendar");
@ -109,6 +112,20 @@ instance.until(otherDatePropertyBag, createOptionsObserver());
assert.compareArray(actual, expected, "order of operations");
actual.splice(0); // clear
// short-circuit for identical objects:
const identicalPropertyBag = TemporalHelpers.propertyBagObserver(actual, {
year: 2000,
month: 5,
monthCode: "M05",
day: 2,
calendar: TemporalHelpers.calendarObserver(actual, "other.calendar"),
}, "other");
instance.since(identicalPropertyBag, createOptionsObserver());
assert.compareArray(actual, expectedMinimal, "order of operations with identical dates");
actual.splice(0); // clear
// code path through RoundDuration that rounds to the nearest year:
const expectedOpsForYearRounding = expected.concat([
"get this.calendar.dateAdd", // 7.c.i

View File

@ -37,9 +37,8 @@ var cal = new class extends Temporal.Calendar {
}("iso8601");
var dt1 = new Temporal.PlainDateTime(1970, 1, 1, 0, 0, 0, 0, 0, 0, cal);
var dt2 = new Temporal.PlainDateTime(1970, 1, 1, 0, 0, 0, 0, 0, 0, cal);
var dt2 = new Temporal.PlainDateTime(1970, 1, 2, 0, 0, 0, 0, 0, 0, cal);
var options = {largestUnit: "nanoseconds"};
assert.throws(RangeError, () => dt1.since(dt1, options));
assert.throws(RangeError, () => dt1.since(dt2, options));
assert.throws(RangeError, () => dt2.since(dt1, options));

View File

@ -8,7 +8,7 @@ includes: [compareArray.js, temporalHelpers.js]
features: [Temporal]
---*/
const expected = [
const expectedMinimal = [
// ToTemporalDateTime
"get other.calendar",
"has other.calendar.dateAdd",
@ -90,10 +90,13 @@ const expected = [
"call options.roundingMode.toString",
"get options.smallestUnit.toString",
"call options.smallestUnit.toString",
];
const expected = expectedMinimal.concat([
// CalendarDateUntil
"get this.calendar.dateUntil",
"call this.calendar.dateUntil",
];
]);
const actual = [];
const ownCalendar = TemporalHelpers.calendarObserver(actual, "this.calendar");
@ -133,6 +136,25 @@ instance.since(otherDateTimePropertyBag, createOptionsObserver());
assert.compareArray(actual, expected, "order of operations");
actual.splice(0); // clear
// short-circuit for identical objects:
const identicalPropertyBag = TemporalHelpers.propertyBagObserver(actual, {
year: 2000,
month: 5,
monthCode: "M05",
day: 2,
hour: 12,
minute: 34,
second: 56,
millisecond: 987,
microsecond: 654,
nanosecond: 321,
calendar: TemporalHelpers.calendarObserver(actual, "other.calendar"),
}, "other");
instance.since(identicalPropertyBag, createOptionsObserver());
assert.compareArray(actual, expectedMinimal, "order of operations with identical datetimes");
actual.splice(0); // clear
// code path through RoundDuration that rounds to the nearest year:
const expectedOpsForYearRounding = expected.concat([
"get this.calendar.dateAdd", // 7.c.i

View File

@ -37,9 +37,8 @@ var cal = new class extends Temporal.Calendar {
}("iso8601");
var dt1 = new Temporal.PlainDateTime(1970, 1, 1, 0, 0, 0, 0, 0, 0, cal);
var dt2 = new Temporal.PlainDateTime(1970, 1, 1, 0, 0, 0, 0, 0, 0, cal);
var dt2 = new Temporal.PlainDateTime(1970, 1, 2, 0, 0, 0, 0, 0, 0, cal);
var options = {largestUnit: "nanoseconds"};
assert.throws(RangeError, () => dt1.until(dt1, options));
assert.throws(RangeError, () => dt1.until(dt2, options));
assert.throws(RangeError, () => dt2.until(dt1, options));

View File

@ -8,7 +8,7 @@ includes: [compareArray.js, temporalHelpers.js]
features: [Temporal]
---*/
const expected = [
const expectedMinimal = [
// ToTemporalDateTime
"get other.calendar",
"has other.calendar.dateAdd",
@ -90,10 +90,13 @@ const expected = [
"call options.roundingMode.toString",
"get options.smallestUnit.toString",
"call options.smallestUnit.toString",
];
const expected = expectedMinimal.concat([
// CalendarDateUntil
"get this.calendar.dateUntil",
"call this.calendar.dateUntil",
];
]);
const actual = [];
const ownCalendar = TemporalHelpers.calendarObserver(actual, "this.calendar");
@ -133,6 +136,25 @@ instance.until(otherDateTimePropertyBag, createOptionsObserver());
assert.compareArray(actual, expected, "order of operations");
actual.splice(0); // clear
// short-circuit for identical objects:
const identicalPropertyBag = TemporalHelpers.propertyBagObserver(actual, {
year: 2000,
month: 5,
monthCode: "M05",
day: 2,
hour: 12,
minute: 34,
second: 56,
millisecond: 987,
microsecond: 654,
nanosecond: 321,
calendar: TemporalHelpers.calendarObserver(actual, "other.calendar"),
}, "other");
instance.until(identicalPropertyBag, createOptionsObserver());
assert.compareArray(actual, expectedMinimal, "order of operations with identical datetimes");
actual.splice(0); // clear
// code path through RoundDuration that rounds to the nearest year:
const expectedOpsForYearRounding = expected.concat([
"get this.calendar.dateAdd", // 7.c.i

View File

@ -74,3 +74,19 @@ const options = TemporalHelpers.propertyBagObserver(actual, {
const result = instance.since(other, options);
assert.compareArray(actual, expected, "order of operations");
actual.splice(0); // clear
// short-circuit does not skip reading options
const identicalPropertyBag = TemporalHelpers.propertyBagObserver(actual, {
hour: 12,
minute: 34,
second: 56,
millisecond: 987,
microsecond: 654,
nanosecond: 321,
}, "other");
instance.since(identicalPropertyBag, options);
assert.compareArray(actual, expected, "order of operations with identical times");
actual.splice(0); // clear

View File

@ -74,3 +74,19 @@ const options = TemporalHelpers.propertyBagObserver(actual, {
const result = instance.until(other, options);
assert.compareArray(actual, expected, "order of operations");
actual.splice(0); // clear
// short-circuit does not skip reading options
const identicalPropertyBag = TemporalHelpers.propertyBagObserver(actual, {
hour: 12,
minute: 34,
second: 56,
millisecond: 987,
microsecond: 654,
nanosecond: 321,
}, "other");
instance.until(identicalPropertyBag, options);
assert.compareArray(actual, expected, "order of operations with identical times");
actual.splice(0); // clear

View File

@ -12,5 +12,5 @@ features: [Temporal]
const calendar = TemporalHelpers.calendarFromFieldsUndefinedOptions();
const instance = new Temporal.PlainYearMonth(2000, 5, calendar);
instance.since({ year: 2000, month: 5, day: 3, calendar });
instance.since({ year: 2000, month: 6, day: 3, calendar });
assert.sameValue(calendar.dateFromFieldsCallCount, 2);

View File

@ -8,7 +8,7 @@ includes: [compareArray.js, temporalHelpers.js]
features: [Temporal]
---*/
const expected = [
const expectedMinimal = [
// ToTemporalYearMonth
"get other.calendar",
"has other.calendar.dateAdd",
@ -69,6 +69,9 @@ const expected = [
"call options.roundingMode.toString",
"get options.smallestUnit.toString",
"call options.smallestUnit.toString",
];
const expected = expectedMinimal.concat([
// CalendarFields
"get this.calendar.fields",
"call this.calendar.fields",
@ -89,7 +92,7 @@ const expected = [
// CalendarDateUntil
"get this.calendar.dateUntil",
"call this.calendar.dateUntil",
];
]);
const actual = [];
const ownCalendar = TemporalHelpers.calendarObserver(actual, "this.calendar");
@ -122,6 +125,18 @@ instance.since(otherYearMonthPropertyBag, createOptionsObserver({ smallestUnit:
assert.compareArray(actual, expected, "order of operations with no rounding");
actual.splice(0); // clear
// short-circuit for identical objects:
const identicalPropertyBag = TemporalHelpers.propertyBagObserver(actual, {
year: 2000,
month: 5,
monthCode: "M05",
calendar: TemporalHelpers.calendarObserver(actual, "other.calendar"),
}, "other");
instance.since(identicalPropertyBag, createOptionsObserver());
assert.compareArray(actual, expectedMinimal, "order of operations with identical year-months");
actual.splice(0); // clear
// code path through RoundDuration that rounds to the nearest year:
const expectedOpsForYearRounding = expected.concat([
"get this.calendar.dateAdd", // 7.c.i

View File

@ -12,5 +12,5 @@ features: [Temporal]
const calendar = TemporalHelpers.calendarFromFieldsUndefinedOptions();
const instance = new Temporal.PlainYearMonth(2000, 5, calendar);
instance.until({ year: 2000, month: 5, day: 3, calendar });
instance.until({ year: 2000, month: 6, day: 3, calendar });
assert.sameValue(calendar.dateFromFieldsCallCount, 2);

View File

@ -8,7 +8,7 @@ includes: [compareArray.js, temporalHelpers.js]
features: [Temporal]
---*/
const expected = [
const expectedMinimal = [
// ToTemporalYearMonth
"get other.calendar",
"has other.calendar.dateAdd",
@ -69,6 +69,9 @@ const expected = [
"call options.roundingMode.toString",
"get options.smallestUnit.toString",
"call options.smallestUnit.toString",
];
const expected = expectedMinimal.concat([
// CalendarFields
"get this.calendar.fields",
"call this.calendar.fields",
@ -89,7 +92,7 @@ const expected = [
// CalendarDateUntil
"get this.calendar.dateUntil",
"call this.calendar.dateUntil",
];
]);
const actual = [];
const ownCalendar = TemporalHelpers.calendarObserver(actual, "this.calendar");
@ -122,6 +125,18 @@ instance.since(otherYearMonthPropertyBag, createOptionsObserver({ smallestUnit:
assert.compareArray(actual, expected, "order of operations with no rounding");
actual.splice(0); // clear
// short-circuit for identical objects:
const identicalPropertyBag = TemporalHelpers.propertyBagObserver(actual, {
year: 2000,
month: 5,
monthCode: "M05",
calendar: TemporalHelpers.calendarObserver(actual, "other.calendar"),
}, "other");
instance.until(identicalPropertyBag, createOptionsObserver());
assert.compareArray(actual, expectedMinimal, "order of operations with identical year-months");
actual.splice(0); // clear
// code path through RoundDuration that rounds to the nearest year:
const expectedOpsForYearRounding = expected.concat([
"get this.calendar.dateAdd", // 7.c.i

View File

@ -144,6 +144,31 @@ instance.since(otherDateTimePropertyBag, createOptionsObserver());
assert.compareArray(actual, expected, "order of operations");
actual.splice(0); // clear
// short-circuit for identical objects will still test TimeZoneEquals if
// largestUnit is a calendar unit:
const identicalPropertyBag = TemporalHelpers.propertyBagObserver(actual, {
year: 2001,
month: 9,
monthCode: "M09",
day: 9,
hour: 1,
minute: 46,
second: 40,
millisecond: 0,
microsecond: 0,
nanosecond: 0,
offset: "+00:00",
calendar: TemporalHelpers.calendarObserver(actual, "other.calendar"),
timeZone: TemporalHelpers.timeZoneObserver(actual, "other.timeZone"),
}, "other");
instance.since(identicalPropertyBag, createOptionsObserver({ largestUnit: "years" }));
assert.compareArray(actual, expected.concat([
"get this.timeZone.id",
"get other.timeZone.id",
]), "order of operations with identical dates and largestUnit a calendar unit");
actual.splice(0); // clear
// Making largestUnit a calendar unit adds the following observable operations:
const expectedOpsForCalendarDifference = [
// TimeZoneEquals

View File

@ -144,6 +144,31 @@ instance.until(otherDateTimePropertyBag, createOptionsObserver());
assert.compareArray(actual, expected, "order of operations");
actual.splice(0); // clear
// short-circuit for identical objects will still test TimeZoneEquals if
// largestUnit is a calendar unit:
const identicalPropertyBag = TemporalHelpers.propertyBagObserver(actual, {
year: 2001,
month: 9,
monthCode: "M09",
day: 9,
hour: 1,
minute: 46,
second: 40,
millisecond: 0,
microsecond: 0,
nanosecond: 0,
offset: "+00:00",
calendar: TemporalHelpers.calendarObserver(actual, "other.calendar"),
timeZone: TemporalHelpers.timeZoneObserver(actual, "other.timeZone"),
}, "other");
instance.until(identicalPropertyBag, createOptionsObserver({ largestUnit: "years" }));
assert.compareArray(actual, expected.concat([
"get this.timeZone.id",
"get other.timeZone.id",
]), "order of operations with identical dates and largestUnit a calendar unit");
actual.splice(0); // clear
// Making largestUnit a calendar unit adds the following observable operations:
const expectedOpsForCalendarDifference = [
// TimeZoneEquals