Skip to content

Commit

Permalink
Change Temporal.Calendar compare semantics to use .id
Browse files Browse the repository at this point in the history
Compare semantics for custom calendars that _don't_ extend
Temporal.Calendar (and therefore don't have the internal slot) use the
value of the .id property, instead of calling toString().

Normative PR: tc39/proposal-temporal#2482
  • Loading branch information
ptomato committed Feb 17, 2023
1 parent 3204783 commit 6c8c3d8
Show file tree
Hide file tree
Showing 92 changed files with 278 additions and 271 deletions.
3 changes: 2 additions & 1 deletion harness/temporalHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -1519,7 +1519,8 @@ var TemporalHelpers = {
// Remove the HasProperty check resulting from the above constructor call
assert.sameValue(calls.pop(), `has ${objectName}.calendar`);
return result;
}
},
id: "iso8601",
};
// Automatically generate the other methods that don't need any custom code
["toString", "dateUntil", "era", "eraYear", "year", "month", "monthCode", "day", "daysInMonth", "fields", "mergeFields"].forEach((methodName) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ const instance = new Temporal.PlainDate(2000, 5, 2);
assert.sameValue(instance.equals({ year: 2000, month: 5, day: 2 }), true, "same date");
assert.sameValue(instance.equals({ year: 2000, month: 5, day: 4 }), false, "different date");

const calendar = { toString() { return "a" } };
const calendar = { id: "a" };
assert.sameValue(instance.withCalendar(calendar).equals({ year: 2000, month: 5, day: 2 }),
false, "different calendar");
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ const instance = new Temporal.PlainDate(2000, 5, 2);
assert.sameValue(instance.equals("2000-05-02"), true, "same date");
assert.sameValue(instance.equals("2000-05-04"), false, "different date");

const calendar = { toString() { return "a" } };
const calendar = { id: "a" };
assert.sameValue(instance.withCalendar(calendar).equals("2000-05-02"), false, "different calendar");
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,31 @@
/*---
esid: sec-temporal.plaindate.protoype.equals
description: test if the calendar is compared
includes: [temporalHelpers.js]
features: [Temporal]
---*/

class CalendarTraceToString extends Temporal.Calendar {
class CalendarTraceId extends Temporal.Calendar {
constructor(id) {
super("iso8601");
this.id_ = id;
this.calls = 0;
}
toString() {
get id() {
++this.calls;
return this.id_;
}
toString() {
TemporalHelpers.assertUnreachable('toString should not be called');
}
};

const calendar1 = new CalendarTraceToString("a");
const calendar1 = new CalendarTraceId("a");
const date1 = new Temporal.PlainDate(1914, 2, 23, calendar1);

const calendar2 = new CalendarTraceToString("b");
const calendar2 = new CalendarTraceId("b");
const date2 = new Temporal.PlainDate(1914, 2, 23, calendar2);

assert.sameValue(date1.equals(date2), false, "different calendars");
assert.sameValue(calendar1.calls, 1, "calendar1 toString() calls");
assert.sameValue(calendar2.calls, 1, "calendar2 toString() calls");
assert.sameValue(calendar1.calls, 1, "calendar1 id getter calls");
assert.sameValue(calendar2.calls, 1, "calendar2 id getter calls");
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
/*---
esid: sec-temporal.plaindate.protoype.equals
description: test if the calendar is compared
includes: [temporalHelpers.js]
features: [Temporal]
---*/

Expand All @@ -13,10 +14,13 @@ class CalendarTraceToString extends Temporal.Calendar {
this.id_ = id;
this.calls = 0;
}
toString() {
get id() {
++this.calls;
return this.id_;
}
toString() {
TemporalHelpers.assertUnreachable('toString should not be called');
}
};

const calendar1 = new CalendarTraceToString("a");
Expand All @@ -26,5 +30,5 @@ const calendar2 = new CalendarTraceToString("a");
const date2 = new Temporal.PlainDate(1914, 2, 23, calendar2);

assert.sameValue(date1.equals(date2), true, "same calendar id");
assert.sameValue(calendar1.calls, 1, "calendar1 toString() calls");
assert.sameValue(calendar2.calls, 1, "calendar2 toString() calls");
assert.sameValue(calendar1.calls, 1, "calendar1 id getter calls");
assert.sameValue(calendar2.calls, 1, "calendar2 id getter calls");
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@

/*---
esid: sec-temporal.plaindate.prototype.since
description: RangeError thrown if calendars' toString results do not match
description: RangeError thrown if calendars' id properties do not match
features: [Temporal]
---*/

const calendar1 = { toString() { return "A"; } };
const calendar2 = { toString() { return "B"; } };
const calendar1 = { id: "A" };
const calendar2 = { id: "B" };

const plainDate1 = new Temporal.PlainDate(2000, 1, 1, calendar1);
const plainDate2 = new Temporal.PlainDate(2000, 1, 1, calendar2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,8 @@ const expected = [
"get other.calendar.dateFromFields",
"call other.calendar.dateFromFields",
// CalendarEquals
"get this.calendar[Symbol.toPrimitive]",
"get this.calendar.toString",
"call this.calendar.toString",
"get other.calendar[Symbol.toPrimitive]",
"get other.calendar.toString",
"call other.calendar.toString",
"get this.calendar.id",
"get other.calendar.id",
// CopyDataProperties
"ownKeys options",
"getOwnPropertyDescriptor options.roundingIncrement",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@
/*---
esid: sec-temporal.plaindate.protoype.tostring
description: Number of observable 'toString' calls on the calendar for each value of calendarName
includes: [temporalHelpers.js]
features: [Temporal]
---*/

let calls;
const customCalendar = {
toString() {
get id() {
++calls;
return "custom";
},
toString() {
TemporalHelpers.assertUnreachable('toString should not be called');
}
};
const date = new Temporal.PlainDate(2000, 5, 2, customCalendar);
Expand All @@ -24,6 +28,6 @@ const date = new Temporal.PlainDate(2000, 5, 2, customCalendar);
].forEach(([calendarName, expectedResult, expectedCalls]) => {
calls = 0;
const result = date.toString({ calendarName });
assert.sameValue(result, expectedResult, `toString output for calendarName = ${calendarName}`);
assert.sameValue(calls, expectedCalls, `calls to toString for calendarName = ${calendarName}`);
assert.sameValue(result, expectedResult, `id for calendarName = ${calendarName}`);
assert.sameValue(calls, expectedCalls, `calls to id getter for calendarName = ${calendarName}`);
});
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ features: [Temporal]

const tests = [
[[], "2000-05-02[u-ca=iso8601]", "built-in ISO"],
[[{ toString() { return "custom"; } }], "2000-05-02[u-ca=custom]", "custom"],
[[{ toString() { return "iso8601"; } }], "2000-05-02[u-ca=iso8601]", "custom with iso8601 toString"],
[[{ toString() { return "ISO8601"; } }], "2000-05-02[u-ca=ISO8601]", "custom with caps toString"],
[[{ toString() { return "\u0131so8601"; } }], "2000-05-02[u-ca=\u0131so8601]", "custom with dotless i toString"],
[[{ id: "custom" }], "2000-05-02[u-ca=custom]", "custom"],
[[{ id: "iso8601" }], "2000-05-02[u-ca=iso8601]", "custom with iso8601 id"],
[[{ id: "ISO8601" }], "2000-05-02[u-ca=ISO8601]", "custom with caps id"],
[[{ id: "\u0131so8601" }], "2000-05-02[u-ca=\u0131so8601]", "custom with dotless i id"],
];

for (const [args, expected, description] of tests) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ features: [Temporal]

const tests = [
[[], "2000-05-02", "built-in ISO"],
[[{ toString() { return "custom"; } }], "2000-05-02[u-ca=custom]", "custom"],
[[{ toString() { return "iso8601"; } }], "2000-05-02", "custom with iso8601 toString"],
[[{ toString() { return "ISO8601"; } }], "2000-05-02[u-ca=ISO8601]", "custom with caps toString"],
[[{ toString() { return "\u0131so8601"; } }], "2000-05-02[u-ca=\u0131so8601]", "custom with dotless i toString"],
[[{ id: "custom" }], "2000-05-02[u-ca=custom]", "custom"],
[[{ id: "iso8601" }], "2000-05-02", "custom with iso8601 id"],
[[{ id: "ISO8601" }], "2000-05-02[u-ca=ISO8601]", "custom with caps id"],
[[{ id: "\u0131so8601" }], "2000-05-02[u-ca=\u0131so8601]", "custom with dotless i id"],
];

for (const [args, expected, description] of tests) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ features: [Temporal]

const tests = [
[[], "2000-05-02[!u-ca=iso8601]", "built-in ISO"],
[[{ toString() { return "custom"; } }], "2000-05-02[!u-ca=custom]", "custom"],
[[{ toString() { return "iso8601"; } }], "2000-05-02[!u-ca=iso8601]", "custom with iso8601 toString"],
[[{ toString() { return "ISO8601"; } }], "2000-05-02[!u-ca=ISO8601]", "custom with caps toString"],
[[{ toString() { return "\u0131so8601"; } }], "2000-05-02[!u-ca=\u0131so8601]", "custom with dotless i toString"],
[[{ id: "custom" }], "2000-05-02[!u-ca=custom]", "custom"],
[[{ id: "iso8601" }], "2000-05-02[!u-ca=iso8601]", "custom with iso8601 id"],
[[{ id: "ISO8601" }], "2000-05-02[!u-ca=ISO8601]", "custom with caps id"],
[[{ id: "\u0131so8601" }], "2000-05-02[!u-ca=\u0131so8601]", "custom with dotless i id"],
];

for (const [args, expected, description] of tests) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ features: [Temporal]

const tests = [
[[], "2000-05-02", "built-in ISO"],
[[{ toString() { return "custom"; } }], "2000-05-02", "custom"],
[[{ toString() { return "iso8601"; } }], "2000-05-02", "custom with iso8601 toString"],
[[{ toString() { return "ISO8601"; } }], "2000-05-02", "custom with caps toString"],
[[{ toString() { return "\u0131so8601"; } }], "2000-05-02", "custom with dotless i toString"],
[[{ id: "custom" }], "2000-05-02", "custom"],
[[{ id: "iso8601" }], "2000-05-02", "custom with iso8601 id"],
[[{ id: "ISO8601" }], "2000-05-02", "custom with caps id"],
[[{ id: "\u0131so8601" }], "2000-05-02", "custom with dotless i id"],
];

for (const [args, expected, description] of tests) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ features: [Temporal]

const tests = [
[[], "2000-05-02", "built-in ISO"],
[[{ toString() { return "custom"; } }], "2000-05-02[u-ca=custom]", "custom"],
[[{ toString() { return "iso8601"; } }], "2000-05-02", "custom with iso8601 toString"],
[[{ toString() { return "ISO8601"; } }], "2000-05-02[u-ca=ISO8601]", "custom with caps toString"],
[[{ toString() { return "\u0131so8601"; } }], "2000-05-02[u-ca=\u0131so8601]", "custom with dotless i toString"],
[[{ id: "custom" }], "2000-05-02[u-ca=custom]", "custom"],
[[{ id: "iso8601" }], "2000-05-02", "custom with iso8601 id"],
[[{ id: "ISO8601" }], "2000-05-02[u-ca=ISO8601]", "custom with caps id"],
[[{ id: "\u0131so8601" }], "2000-05-02[u-ca=\u0131so8601]", "custom with dotless i id"],
];

for (const [args, expected, description] of tests) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ features: [Temporal]
---*/

const calendar = {
toString() { return "custom"; }
id: "custom",
};
const date = new Temporal.PlainDate(2000, 5, 2, calendar);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ features: [Temporal]
---*/

const calendar = {
toString() { return "custom"; }
id: "custom",
};
const date1 = new Temporal.PlainDate(2000, 5, 2);
const date2 = new Temporal.PlainDate(2000, 5, 2, calendar);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ const expected = [
"get options.calendarName",
"get options.calendarName.toString",
"call options.calendarName.toString",
"get this.calendar[Symbol.toPrimitive]",
"get this.calendar.toString",
"call this.calendar.toString",
"get this.calendar.id",
];
const actual = [];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@

/*---
esid: sec-temporal.plaindate.prototype.until
description: RangeError thrown if calendars' toString results do not match
description: RangeError thrown if calendars' id properties do not match
features: [Temporal]
---*/

const calendar1 = { toString() { return "A"; } };
const calendar2 = { toString() { return "B"; } };
const calendar1 = { id: "A" };
const calendar2 = { id: "B" };

const plainDate1 = new Temporal.PlainDate(2000, 1, 1, calendar1);
const plainDate2 = new Temporal.PlainDate(2000, 1, 1, calendar2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,8 @@ const expected = [
"get other.calendar.dateFromFields",
"call other.calendar.dateFromFields",
// CalendarEquals
"get this.calendar[Symbol.toPrimitive]",
"get this.calendar.toString",
"call this.calendar.toString",
"get other.calendar[Symbol.toPrimitive]",
"get other.calendar.toString",
"call other.calendar.toString",
"get this.calendar.id",
"get other.calendar.id",
// CopyDataProperties
"ownKeys options",
"getOwnPropertyDescriptor options.roundingIncrement",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,38 @@ features: [Temporal]
---*/

const actual = [];
const calendar1 = TemporalHelpers.toPrimitiveObserver(actual, "A", "calendar1");
const calendar2 = TemporalHelpers.toPrimitiveObserver(actual, "A", "calendar2");
const calendar3 = TemporalHelpers.toPrimitiveObserver(actual, "B", "calendar3");

function makeCalendar(id, objectName) {
const calendar = {};
TemporalHelpers.observeProperty(actual, calendar, "id", id, objectName);
return calendar;
}

const calendar1 = makeCalendar("A", "calendar1");
const calendar2 = makeCalendar("A", "calendar2");
const calendar3 = makeCalendar("B", "calendar3");
const dt1 = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789, calendar1);
const dt1b = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789, calendar1);
const dt2 = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789, calendar2);
const dt3 = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789, calendar3);
actual.splice(0); // disregard the HasProperty checks done in the constructor

assert.sameValue(dt1.equals(dt1b), true, "same calendar object");
assert.compareArray(actual, []);

assert.sameValue(dt1.equals(dt2), true, "same calendar string");
assert.compareArray(actual, ["get calendar1.toString", "call calendar1.toString", "get calendar2.toString", "call calendar2.toString"]);
assert.compareArray(actual, ["get calendar1.id", "get calendar2.id"]);

actual.splice(0); // empty it for the next check
assert.sameValue(dt1.equals(dt3), false, "different calendar string");
assert.compareArray(actual, ["get calendar1.toString", "call calendar1.toString", "get calendar3.toString", "call calendar3.toString"]);
assert.compareArray(actual, ["get calendar1.id", "get calendar3.id"]);

const calendar4 = { toString() { throw new Test262Error("should not call calendar4.toString") } };
const calendar5 = { toString() { throw new Test262Error("should not call calendar5.toString") } };
const calendar4 = {
get id() { TemporalHelpers.assertUnreachable('should not get calendar4.id'); },
};
const calendar5 = {
get id() { TemporalHelpers.assertUnreachable('should not get calendar5.id'); },
};
const dt4 = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789, calendar4);
const dt5 = new Temporal.PlainDateTime(2019, 10, 29, 10, 46, 38, 271, 986, 102, calendar4);
const dt6 = new Temporal.PlainDateTime(2019, 10, 29, 10, 46, 38, 271, 986, 102, calendar5);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ 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, {});
const dt2 = new Temporal.PlainDateTime(2000, 1, 1, 0, 0, 0, 0, 0, 0, { id: "custom" });

assert.throws(
RangeError,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,8 @@ const expected = [
"get other.calendar.dateFromFields",
"call other.calendar.dateFromFields",
// CalendarEquals
"get this.calendar[Symbol.toPrimitive]",
"get this.calendar.toString",
"call this.calendar.toString",
"get other.calendar[Symbol.toPrimitive]",
"get other.calendar.toString",
"call other.calendar.toString",
"get this.calendar.id",
"get other.calendar.id",
// CopyDataProperties
"ownKeys options",
"getOwnPropertyDescriptor options.roundingIncrement",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@
/*---
esid: sec-temporal.plaindatetime.protoype.tostring
description: Number of observable 'toString' calls on the calendar for each value of calendarName
includes: [temporalHelpers.js]
features: [Temporal]
---*/

let calls;
const customCalendar = {
toString() {
get id() {
++calls;
return "custom";
},
toString() {
TemporalHelpers.assertUnreachable('toString should not be called');
}
};
const date = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, customCalendar);
Expand All @@ -24,6 +28,6 @@ const date = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, c
].forEach(([calendarName, expectedResult, expectedCalls]) => {
calls = 0;
const result = date.toString({ calendarName });
assert.sameValue(result, expectedResult, `toString output for calendarName = ${calendarName}`);
assert.sameValue(calls, expectedCalls, `calls to toString for calendarName = ${calendarName}`);
assert.sameValue(result, expectedResult, `id for calendarName = ${calendarName}`);
assert.sameValue(calls, expectedCalls, `calls to id getter for calendarName = ${calendarName}`);
});
Loading

0 comments on commit 6c8c3d8

Please sign in to comment.