mirror of https://github.com/tc39/test262.git
Temporal: Add TemporalHelpers.calendarObserver
Similar to the previous commits with property bags and time zones, there are also some existing tests that use a Proxy to test the order of observable operations which involve user code passed in as part of a Temporal.TimeZone object. I am going to write several more tests that do this, as well. This seems like a good thing to put into TemporalHelpers, where it can be implemented consistently so that we don't get discrepancies in which operations are tracked, or bugs due to a Symbol-valued property. Updates existing tests to use this helper.
This commit is contained in:
parent
12f919e45d
commit
ae52931aae
|
@ -1381,6 +1381,97 @@ var TemporalHelpers = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* calendarObserver:
|
||||||
|
* A custom calendar that behaves exactly like the ISO 8601 calendar but
|
||||||
|
* tracks calls to any of its methods, and Get/Has operations on its
|
||||||
|
* properties, by appending messages to an array. This is for the purpose of
|
||||||
|
* testing order of operations that are observable from user code.
|
||||||
|
* objectName is used in the log.
|
||||||
|
*/
|
||||||
|
calendarObserver(calls, objectName, methodOverrides = {}) {
|
||||||
|
const iso8601 = new Temporal.Calendar("iso8601");
|
||||||
|
const trackingMethods = {
|
||||||
|
dateFromFields(...args) {
|
||||||
|
calls.push(`call ${objectName}.dateFromFields`);
|
||||||
|
if ('dateFromFields' in methodOverrides) {
|
||||||
|
const value = methodOverrides.dateFromFields;
|
||||||
|
return typeof value === "function" ? value(...args) : value;
|
||||||
|
}
|
||||||
|
const originalResult = iso8601.dateFromFields(...args);
|
||||||
|
// Replace the calendar in the result with the call-tracking calendar
|
||||||
|
const {isoYear, isoMonth, isoDay} = originalResult.getISOFields();
|
||||||
|
const result = new Temporal.PlainDate(isoYear, isoMonth, isoDay, this);
|
||||||
|
// Remove the HasProperty check resulting from the above constructor call
|
||||||
|
assert.sameValue(calls.pop(), `has ${objectName}.calendar`);
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
yearMonthFromFields(...args) {
|
||||||
|
calls.push(`call ${objectName}.yearMonthFromFields`);
|
||||||
|
if ('yearMonthFromFields' in methodOverrides) {
|
||||||
|
const value = methodOverrides.yearMonthFromFields;
|
||||||
|
return typeof value === "function" ? value(...args) : value;
|
||||||
|
}
|
||||||
|
const originalResult = iso8601.yearMonthFromFields(...args);
|
||||||
|
// Replace the calendar in the result with the call-tracking calendar
|
||||||
|
const {isoYear, isoMonth, isoDay} = originalResult.getISOFields();
|
||||||
|
const result = new Temporal.PlainYearMonth(isoYear, isoMonth, this, isoDay);
|
||||||
|
// Remove the HasProperty check resulting from the above constructor call
|
||||||
|
assert.sameValue(calls.pop(), `has ${objectName}.calendar`);
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
monthDayFromFields(...args) {
|
||||||
|
calls.push(`call ${objectName}.monthDayFromFields`);
|
||||||
|
if ('monthDayFromFields' in methodOverrides) {
|
||||||
|
const value = methodOverrides.monthDayFromFields;
|
||||||
|
return typeof value === "function" ? value(...args) : value;
|
||||||
|
}
|
||||||
|
const originalResult = iso8601.monthDayFromFields(...args);
|
||||||
|
// Replace the calendar in the result with the call-tracking calendar
|
||||||
|
const {isoYear, isoMonth, isoDay} = originalResult.getISOFields();
|
||||||
|
const result = new Temporal.PlainMonthDay(isoMonth, isoDay, this, isoYear);
|
||||||
|
// Remove the HasProperty check resulting from the above constructor call
|
||||||
|
assert.sameValue(calls.pop(), `has ${objectName}.calendar`);
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
dateAdd(...args) {
|
||||||
|
calls.push(`call ${objectName}.dateAdd`);
|
||||||
|
if ('dateAdd' in methodOverrides) {
|
||||||
|
const value = methodOverrides.dateAdd;
|
||||||
|
return typeof value === "function" ? value(...args) : value;
|
||||||
|
}
|
||||||
|
const originalResult = iso8601.dateAdd(...args);
|
||||||
|
const {isoYear, isoMonth, isoDay} = originalResult.getISOFields();
|
||||||
|
const result = new Temporal.PlainDate(isoYear, isoMonth, isoDay, this);
|
||||||
|
// Remove the HasProperty check resulting from the above constructor call
|
||||||
|
assert.sameValue(calls.pop(), `has ${objectName}.calendar`);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Automatically generate the other methods that don't need any custom code
|
||||||
|
["toString", "dateUntil", "era", "eraYear", "year", "month", "monthCode", "day", "fields", "mergeFields"].forEach((methodName) => {
|
||||||
|
trackingMethods[methodName] = function (...args) {
|
||||||
|
actual.push(`call ${formatPropertyName(methodName, objectName)}`);
|
||||||
|
if (methodName in methodOverrides) {
|
||||||
|
const value = methodOverrides[methodName];
|
||||||
|
return typeof value === "function" ? value(...args) : value;
|
||||||
|
}
|
||||||
|
return iso8601[methodName](...args);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
return new Proxy(trackingMethods, {
|
||||||
|
get(target, key, receiver) {
|
||||||
|
const result = Reflect.get(target, key, receiver);
|
||||||
|
actual.push(`get ${formatPropertyName(key, objectName)}`);
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
has(target, key) {
|
||||||
|
actual.push(`has ${formatPropertyName(key, objectName)}`);
|
||||||
|
return Reflect.has(target, key);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A custom calendar that does not allow any of its methods to be called, for
|
* A custom calendar that does not allow any of its methods to be called, for
|
||||||
* the purpose of asserting that a particular operation does not call into
|
* the purpose of asserting that a particular operation does not call into
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
/*---
|
/*---
|
||||||
esid: sec-temporal.now.plaindatetime
|
esid: sec-temporal.now.plaindatetime
|
||||||
description: Observable interactions with the provided calendar-like object
|
description: Observable interactions with the provided calendar-like object
|
||||||
includes: [compareArray.js]
|
includes: [compareArray.js, temporalHelpers.js]
|
||||||
features: [Proxy, Temporal]
|
features: [Proxy, Temporal]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
|
@ -18,41 +18,17 @@ const expectedWith = [
|
||||||
'has calendar.calendar',
|
'has calendar.calendar',
|
||||||
'get calendar.calendar',
|
'get calendar.calendar',
|
||||||
'has nestedCalendar.calendar',
|
'has nestedCalendar.calendar',
|
||||||
'get nestedCalendar.Symbol(Symbol.toPrimitive)',
|
'get nestedCalendar[Symbol.toPrimitive]',
|
||||||
'get nestedCalendar.toString',
|
'get nestedCalendar.toString',
|
||||||
'call nestedCalendar.toString'
|
'call nestedCalendar.toString'
|
||||||
];
|
];
|
||||||
const nestedCalendar = new Proxy({
|
const nestedCalendar = TemporalHelpers.calendarObserver(actual, "nestedCalendar", {
|
||||||
toString: function() {
|
toString: "iso8601",
|
||||||
actual.push('call nestedCalendar.toString');
|
|
||||||
return 'iso8601';
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
has(target, property) {
|
|
||||||
actual.push(`has nestedCalendar.${String(property)}`);
|
|
||||||
return property in target;
|
|
||||||
},
|
|
||||||
get(target, property) {
|
|
||||||
actual.push(`get nestedCalendar.${String(property)}`);
|
|
||||||
return target[property];
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
const calendar = new Proxy({
|
const calendar = TemporalHelpers.calendarObserver(actual, "calendar", {
|
||||||
calendar: nestedCalendar,
|
toString: "iso8601",
|
||||||
toString: function() {
|
|
||||||
actual.push('call calendar.toString');
|
|
||||||
return 'iso8601';
|
|
||||||
},
|
|
||||||
}, {
|
|
||||||
has(target, property) {
|
|
||||||
actual.push(`has calendar.${String(property)}`);
|
|
||||||
return property in target;
|
|
||||||
},
|
|
||||||
get(target, property) {
|
|
||||||
actual.push(`get calendar.${String(property)}`);
|
|
||||||
return target[property];
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
calendar.calendar = nestedCalendar;
|
||||||
|
|
||||||
Object.defineProperty(Temporal.Calendar, 'from', {
|
Object.defineProperty(Temporal.Calendar, 'from', {
|
||||||
get() {
|
get() {
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
/*---
|
/*---
|
||||||
esid: sec-temporal.now.zoneddatetime
|
esid: sec-temporal.now.zoneddatetime
|
||||||
description: Observable interactions with the provided calendar-like object
|
description: Observable interactions with the provided calendar-like object
|
||||||
includes: [compareArray.js]
|
includes: [compareArray.js, temporalHelpers.js]
|
||||||
features: [Proxy, Temporal]
|
features: [Proxy, Temporal]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
|
@ -18,41 +18,17 @@ const expectedWith = [
|
||||||
'has calendar.calendar',
|
'has calendar.calendar',
|
||||||
'get calendar.calendar',
|
'get calendar.calendar',
|
||||||
'has nestedCalendar.calendar',
|
'has nestedCalendar.calendar',
|
||||||
'get nestedCalendar.Symbol(Symbol.toPrimitive)',
|
'get nestedCalendar[Symbol.toPrimitive]',
|
||||||
'get nestedCalendar.toString',
|
'get nestedCalendar.toString',
|
||||||
'call nestedCalendar.toString'
|
'call nestedCalendar.toString'
|
||||||
];
|
];
|
||||||
const nestedCalendar = new Proxy({
|
const nestedCalendar = TemporalHelpers.calendarObserver(actual, "nestedCalendar", {
|
||||||
toString: function() {
|
toString: "iso8601",
|
||||||
actual.push('call nestedCalendar.toString');
|
|
||||||
return 'iso8601';
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
has(target, property) {
|
|
||||||
actual.push(`has nestedCalendar.${String(property)}`);
|
|
||||||
return property in target;
|
|
||||||
},
|
|
||||||
get(target, property) {
|
|
||||||
actual.push(`get nestedCalendar.${String(property)}`);
|
|
||||||
return target[property];
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
const calendar = new Proxy({
|
const calendar = TemporalHelpers.calendarObserver(actual, "calendar", {
|
||||||
calendar: nestedCalendar,
|
toString: "iso8601",
|
||||||
toString: function() {
|
|
||||||
actual.push('call calendar.toString');
|
|
||||||
return 'iso8601';
|
|
||||||
},
|
|
||||||
}, {
|
|
||||||
has(target, property) {
|
|
||||||
actual.push(`has calendar.${String(property)}`);
|
|
||||||
return property in target;
|
|
||||||
},
|
|
||||||
get(target, property) {
|
|
||||||
actual.push(`get calendar.${String(property)}`);
|
|
||||||
return target[property];
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
calendar.calendar = nestedCalendar;
|
||||||
|
|
||||||
Object.defineProperty(Temporal.Calendar, 'from', {
|
Object.defineProperty(Temporal.Calendar, 'from', {
|
||||||
get() {
|
get() {
|
||||||
|
|
Loading…
Reference in New Issue