// GENERATED, DO NOT EDIT // file: temporalHelpers.js // Copyright (C) 2021 Igalia, S.L. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. /*--- description: | This defines helper objects and functions for testing Temporal. defines: [TemporalHelpers] features: [Symbol.species, Symbol.iterator, Temporal]
---*/
/* * Return the canonical era code.
*/
canonicalizeCalendarEra(calendarId, eraName) { assert.sameValue(typeof calendarId, "string", "calendar must be string in canonicalizeCalendarEra");
if (eraName === undefined) { return undefined;
} assert.sameValue(typeof eraName, "string", "eraName must be string or undefined in canonicalizeCalendarEra");
for (let {era, aliases = []} of TemporalHelpers.CalendarEras[calendarId]) { if (era === eraName || aliases.includes(eraName)) { return era;
}
} thrownew Test262Error(`Unsupported era name: ${eraName}`);
},
/* * assertDuration(duration, years, ..., nanoseconds[, description]): * * Shorthand for asserting that each field of a Temporal.Duration is equal to * an expected value.
*/
assertDuration(duration, years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds, description = "") { const prefix = description ? `${description}: ` : ""; assert(duration instanceof Temporal.Duration, `${prefix}instanceof`); assert.sameValue(duration.years, years, `${prefix}years result:`); assert.sameValue(duration.months, months, `${prefix}months result:`); assert.sameValue(duration.weeks, weeks, `${prefix}weeks result:`); assert.sameValue(duration.days, days, `${prefix}days result:`); assert.sameValue(duration.hours, hours, `${prefix}hours result:`); assert.sameValue(duration.minutes, minutes, `${prefix}minutes result:`); assert.sameValue(duration.seconds, seconds, `${prefix}seconds result:`); assert.sameValue(duration.milliseconds, milliseconds, `${prefix}milliseconds result:`); assert.sameValue(duration.microseconds, microseconds, `${prefix}microseconds result:`); assert.sameValue(duration.nanoseconds, nanoseconds, `${prefix}nanoseconds result`);
},
/* * assertDateDuration(duration, years, months, weeks, days, [, description]): * * Shorthand for asserting that each date field of a Temporal.Duration is * equal to an expected value.
*/
assertDateDuration(duration, years, months, weeks, days, description = "") { const prefix = description ? `${description}: ` : ""; assert(duration instanceof Temporal.Duration, `${prefix}instanceof`); assert.sameValue(duration.years, years, `${prefix}years result:`); assert.sameValue(duration.months, months, `${prefix}months result:`); assert.sameValue(duration.weeks, weeks, `${prefix}weeks result:`); assert.sameValue(duration.days, days, `${prefix}days result:`); assert.sameValue(duration.hours, 0, `${prefix}hours result should be zero:`); assert.sameValue(duration.minutes, 0, `${prefix}minutes result should be zero:`); assert.sameValue(duration.seconds, 0, `${prefix}seconds result should be zero:`); assert.sameValue(duration.milliseconds, 0, `${prefix}milliseconds result should be zero:`); assert.sameValue(duration.microseconds, 0, `${prefix}microseconds result should be zero:`); assert.sameValue(duration.nanoseconds, 0, `${prefix}nanoseconds result should be zero:`);
},
/* * assertDurationsEqual(actual, expected[, description]): * * Shorthand for asserting that each field of a Temporal.Duration is equal to * the corresponding field in another Temporal.Duration.
*/
assertDurationsEqual(actual, expected, description = "") { const prefix = description ? `${description}: ` : ""; assert(expected instanceof Temporal.Duration, `${prefix}expected value should be a Temporal.Duration`);
TemporalHelpers.assertDuration(actual, expected.years, expected.months, expected.weeks, expected.days, expected.hours, expected.minutes, expected.seconds, expected.milliseconds, expected.microseconds, expected.nanoseconds, description);
},
/* * assertInstantsEqual(actual, expected[, description]): * * Shorthand for asserting that two Temporal.Instants are of the correct type * and equal according to their equals() methods.
*/
assertInstantsEqual(actual, expected, description = "") { const prefix = description ? `${description}: ` : ""; assert(expected instanceof Temporal.Instant, `${prefix}expected value should be a Temporal.Instant`); assert(actual instanceof Temporal.Instant, `${prefix}instanceof`); assert(actual.equals(expected), `${prefix}equals method`);
},
/* * assertPlainDate(date, year, ..., nanosecond[, description[, era, eraYear]]): * * Shorthand for asserting that each field of a Temporal.PlainDate is equal to * an expected value. (Except the `calendar` property, since callers may want * to assert either object equality with an object they put in there, or the * value of date.calendarId.)
*/
assertPlainDate(date, year, month, monthCode, day, description = "", era = undefined, eraYear = undefined) { const prefix = description ? `${description}: ` : ""; assert(date instanceof Temporal.PlainDate, `${prefix}instanceof`); assert.sameValue(
TemporalHelpers.canonicalizeCalendarEra(date.calendarId, date.era),
TemporalHelpers.canonicalizeCalendarEra(date.calendarId, era),
`${prefix}era result:`
); assert.sameValue(date.eraYear, eraYear, `${prefix}eraYear result:`); assert.sameValue(date.year, year, `${prefix}year result:`); assert.sameValue(date.month, month, `${prefix}month result:`); assert.sameValue(date.monthCode, monthCode, `${prefix}monthCode result:`); assert.sameValue(date.day, day, `${prefix}day result:`);
},
/* * assertPlainDateTime(datetime, year, ..., nanosecond[, description[, era, eraYear]]): * * Shorthand for asserting that each field of a Temporal.PlainDateTime is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the value of datetime.calendarId.)
*/
assertPlainDateTime(datetime, year, month, monthCode, day, hour, minute, second, millisecond, microsecond, nanosecond, description = "", era = undefined, eraYear = undefined) { const prefix = description ? `${description}: ` : ""; assert(datetime instanceof Temporal.PlainDateTime, `${prefix}instanceof`); assert.sameValue(
TemporalHelpers.canonicalizeCalendarEra(datetime.calendarId, datetime.era),
TemporalHelpers.canonicalizeCalendarEra(datetime.calendarId, era),
`${prefix}era result:`
); assert.sameValue(datetime.eraYear, eraYear, `${prefix}eraYear result:`); assert.sameValue(datetime.year, year, `${prefix}year result:`); assert.sameValue(datetime.month, month, `${prefix}month result:`); assert.sameValue(datetime.monthCode, monthCode, `${prefix}monthCode result:`); assert.sameValue(datetime.day, day, `${prefix}day result:`); assert.sameValue(datetime.hour, hour, `${prefix}hour result:`); assert.sameValue(datetime.minute, minute, `${prefix}minute result:`); assert.sameValue(datetime.second, second, `${prefix}second result:`); assert.sameValue(datetime.millisecond, millisecond, `${prefix}millisecond result:`); assert.sameValue(datetime.microsecond, microsecond, `${prefix}microsecond result:`); assert.sameValue(datetime.nanosecond, nanosecond, `${prefix}nanosecond result:`);
},
/* * assertPlainDateTimesEqual(actual, expected[, description]): * * Shorthand for asserting that two Temporal.PlainDateTimes are of the correct * type, equal according to their equals() methods, and additionally that * their calendar internal slots are the same value.
*/
assertPlainDateTimesEqual(actual, expected, description = "") { const prefix = description ? `${description}: ` : ""; assert(expected instanceof Temporal.PlainDateTime, `${prefix}expected value should be a Temporal.PlainDateTime`); assert(actual instanceof Temporal.PlainDateTime, `${prefix}instanceof`); assert(actual.equals(expected), `${prefix}equals method`); assert.sameValue(
actual.calendarId,
expected.calendarId,
`${prefix}calendar same value:`
);
},
/* * assertPlainMonthDay(monthDay, monthCode, day[, description [, referenceISOYear]]): * * Shorthand for asserting that each field of a Temporal.PlainMonthDay is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the value of monthDay.calendarId().)
*/
assertPlainMonthDay(monthDay, monthCode, day, description = "", referenceISOYear = 1972) { const prefix = description ? `${description}: ` : ""; assert(monthDay instanceof Temporal.PlainMonthDay, `${prefix}instanceof`); assert.sameValue(monthDay.monthCode, monthCode, `${prefix}monthCode result:`); assert.sameValue(monthDay.day, day, `${prefix}day result:`); const isoYear = Number(monthDay.toString({ calendarName: "always" }).split("-")[0]); assert.sameValue(isoYear, referenceISOYear, `${prefix}referenceISOYear result:`);
},
/* * assertPlainTime(time, hour, ..., nanosecond[, description]): * * Shorthand for asserting that each field of a Temporal.PlainTime is equal to * an expected value.
*/
assertPlainTime(time, hour, minute, second, millisecond, microsecond, nanosecond, description = "") { const prefix = description ? `${description}: ` : ""; assert(time instanceof Temporal.PlainTime, `${prefix}instanceof`); assert.sameValue(time.hour, hour, `${prefix}hour result:`); assert.sameValue(time.minute, minute, `${prefix}minute result:`); assert.sameValue(time.second, second, `${prefix}second result:`); assert.sameValue(time.millisecond, millisecond, `${prefix}millisecond result:`); assert.sameValue(time.microsecond, microsecond, `${prefix}microsecond result:`); assert.sameValue(time.nanosecond, nanosecond, `${prefix}nanosecond result:`);
},
/* * assertPlainTimesEqual(actual, expected[, description]): * * Shorthand for asserting that two Temporal.PlainTimes are of the correct * type and equal according to their equals() methods.
*/
assertPlainTimesEqual(actual, expected, description = "") { const prefix = description ? `${description}: ` : ""; assert(expected instanceof Temporal.PlainTime, `${prefix}expected value should be a Temporal.PlainTime`); assert(actual instanceof Temporal.PlainTime, `${prefix}instanceof`); assert(actual.equals(expected), `${prefix}equals method`);
},
/* * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the value of yearMonth.calendarId.)
*/
assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { const prefix = description ? `${description}: ` : ""; assert(yearMonth instanceof Temporal.PlainYearMonth, `${prefix}instanceof`); assert.sameValue(
TemporalHelpers.canonicalizeCalendarEra(yearMonth.calendarId, yearMonth.era),
TemporalHelpers.canonicalizeCalendarEra(yearMonth.calendarId, era),
`${prefix}era result:`
); assert.sameValue(yearMonth.eraYear, eraYear, `${prefix}eraYear result:`); assert.sameValue(yearMonth.year, year, `${prefix}year result:`); assert.sameValue(yearMonth.month, month, `${prefix}month result:`); assert.sameValue(yearMonth.monthCode, monthCode, `${prefix}monthCode result:`); const isoDay = Number(yearMonth.toString({ calendarName: "always" }).slice(1).split('-')[2].slice(0, 2)); assert.sameValue(isoDay, referenceISODay, `${prefix}referenceISODay result:`);
},
/* * assertZonedDateTimesEqual(actual, expected[, description]): * * Shorthand for asserting that two Temporal.ZonedDateTimes are of the correct * type, equal according to their equals() methods, and additionally that * their time zones and calendar internal slots are the same value.
*/
assertZonedDateTimesEqual(actual, expected, description = "") { const prefix = description ? `${description}: ` : ""; assert(expected instanceof Temporal.ZonedDateTime, `${prefix}expected value should be a Temporal.ZonedDateTime`); assert(actual instanceof Temporal.ZonedDateTime, `${prefix}instanceof`); assert(actual.equals(expected), `${prefix}equals method`); assert.sameValue(actual.timeZone, expected.timeZone, `${prefix}time zone same value:`); assert.sameValue(
actual.calendarId,
expected.calendarId,
`${prefix}calendar same value:`
);
},
/* * assertUnreachable(description): * * Helper for asserting that code is not executed.
*/
assertUnreachable(description) {
let message = "This code should not be executed"; if (description) {
message = `${message}: ${description}`;
} thrownew Test262Error(message);
},
/* * checkPlainDateTimeConversionFastPath(func): * * ToTemporalDate and ToTemporalTime should both, if given a * Temporal.PlainDateTime instance, convert to the desired type by reading the * PlainDateTime's internal slots, rather than calling any getters. * * func(datetime) is the actual operation to test, that must * internally call the abstract operation ToTemporalDate or ToTemporalTime. * It is passed a Temporal.PlainDateTime instance.
*/
checkPlainDateTimeConversionFastPath(func, message = "checkPlainDateTimeConversionFastPath") { const actual = []; const expected = [];
func(datetime); assert.compareArray(actual, expected, `${message}: property getters not called`);
},
/* * Check that an options bag that accepts units written in the singular form, * also accepts the same units written in the plural form. * func(unit) should call the method with the appropriate options bag * containing unit as a value. This will be called twice for each element of * validSingularUnits, once with singular and once with plural, and the * results of each pair should be the same (whether a Temporal object or a * primitive value.)
*/
checkPluralUnitsAccepted(func, validSingularUnits) { const plurals = {
year: 'years',
month: 'months',
week: 'weeks',
day: 'days',
hour: 'hours',
minute: 'minutes',
second: 'seconds',
millisecond: 'milliseconds',
microsecond: 'microseconds',
nanosecond: 'nanoseconds',
};
/* * checkRoundingIncrementOptionWrongType(checkFunc, assertTrueResultFunc, assertObjectResultFunc): * * Checks the type handling of the roundingIncrement option. * checkFunc(roundingIncrement) is a function which takes the value of * roundingIncrement to test, and calls the method under test with it, * returning the result. assertTrueResultFunc(result, description) should * assert that result is the expected result with roundingIncrement: true, and * assertObjectResultFunc(result, description) should assert that result is * the expected result with roundingIncrement being an object with a valueOf() * method.
*/
checkRoundingIncrementOptionWrongType(checkFunc, assertTrueResultFunc, assertObjectResultFunc) { // null converts to 0, which is out of range assert.throws(RangeError, () => checkFunc(null), "null"); // Booleans convert to either 0 or 1, and 1 is allowed const trueResult = checkFunc(true);
assertTrueResultFunc(trueResult, "true"); assert.throws(RangeError, () => checkFunc(false), "false"); // Symbols and BigInts cannot convert to numbers assert.throws(TypeError, () => checkFunc(Symbol()), "symbol"); assert.throws(TypeError, () => checkFunc(2n), "bigint");
// Objects prefer their valueOf() methods when converting to a number assert.throws(RangeError, () => checkFunc({}), "plain object");
/* * checkStringOptionWrongType(propertyName, value, checkFunc, assertFunc): * * Checks the type handling of a string option, of which there are several in * Temporal. * propertyName is the name of the option, and value is the value that * assertFunc should expect it to have. * checkFunc(value) is a function which takes the value of the option to test, * and calls the method under test with it, returning the result. * assertFunc(result, description) should assert that result is the expected * result with the option value being an object with a toString() method * which returns the given value.
*/
checkStringOptionWrongType(propertyName, value, checkFunc, assertFunc) { // null converts to the string "null", which is an invalid string value assert.throws(RangeError, () => checkFunc(null), "null"); // Booleans convert to the strings "true" or "false", which are invalid assert.throws(RangeError, () => checkFunc(true), "true"); assert.throws(RangeError, () => checkFunc(false), "false"); // Symbols cannot convert to strings assert.throws(TypeError, () => checkFunc(Symbol()), "symbol"); // Numbers convert to strings which are invalid assert.throws(RangeError, () => checkFunc(2), "number"); // BigInts convert to strings which are invalid assert.throws(RangeError, () => checkFunc(2n), "bigint");
// Objects prefer their toString() methods when converting to a string assert.throws(RangeError, () => checkFunc({}), "plain object");
const expected = [
`get ${propertyName}.toString`,
`call ${propertyName}.toString`,
]; const actual = []; const observer = TemporalHelpers.toPrimitiveObserver(actual, value, propertyName); const result = checkFunc(observer);
assertFunc(result, "object with toString"); assert.compareArray(actual, expected, "order of operations");
},
/* * checkSubclassingIgnored(construct, constructArgs, method, methodArgs, * resultAssertions): * * Methods of Temporal classes that return a new instance of the same class, * must not take the constructor of a subclass into account, nor the @@species * property. This helper runs tests to ensure this. * * construct(...constructArgs) must yield a valid instance of the Temporal * class. instance[method](...methodArgs) is the method call under test, which * must also yield a valid instance of the same Temporal class, not a * subclass. See below for the individual tests that this runs. * resultAssertions() is a function that performs additional assertions on the * instance returned by the method under test.
*/
checkSubclassingIgnored(...args) { this.checkSubclassConstructorNotObject(...args); this.checkSubclassConstructorUndefined(...args); this.checkSubclassConstructorThrows(...args); this.checkSubclassConstructorNotCalled(...args); this.checkSubclassSpeciesInvalidResult(...args); this.checkSubclassSpeciesNotAConstructor(...args); this.checkSubclassSpeciesNull(...args); this.checkSubclassSpeciesUndefined(...args); this.checkSubclassSpeciesThrows(...args);
},
/* * Checks that replacing the 'constructor' property of the instance with * various primitive values does not affect the returned new instance.
*/
checkSubclassConstructorNotObject(construct, constructArgs, method, methodArgs, resultAssertions) { function check(value, description) { const instance = new construct(...constructArgs);
instance.constructor = value; const result = instance[method](...methodArgs); assert.sameValue(Object.getPrototypeOf(result), construct.prototype, description);
resultAssertions(result);
}
/* * Checks that replacing the 'constructor' property of the subclass with * undefined does not affect the returned new instance.
*/
checkSubclassConstructorUndefined(construct, constructArgs, method, methodArgs, resultAssertions) {
let called = 0;
const instance = new MySubclass(); assert.sameValue(called, 1);
MySubclass.prototype.constructor = undefined;
const result = instance[method](...methodArgs); assert.sameValue(called, 1); assert.sameValue(Object.getPrototypeOf(result), construct.prototype);
resultAssertions(result);
},
/* * Checks that making the 'constructor' property of the instance throw when * called does not affect the returned new instance.
*/
checkSubclassConstructorThrows(construct, constructArgs, method, methodArgs, resultAssertions) { function CustomError() {} const instance = new construct(...constructArgs);
Object.defineProperty(instance, "constructor", {
get() { thrownew CustomError();
}
}); const result = instance[method](...methodArgs); assert.sameValue(Object.getPrototypeOf(result), construct.prototype);
resultAssertions(result);
},
/* * Checks that when subclassing, the subclass constructor is not called by * the method under test.
*/
checkSubclassConstructorNotCalled(construct, constructArgs, method, methodArgs, resultAssertions) {
let called = 0;
/* * Check that the constructor's @@species property is ignored when it's null.
*/
checkSubclassSpeciesNull(construct, constructArgs, method, methodArgs, resultAssertions) {
let called = 0;
const result = instance[method](...methodArgs); assert.sameValue(called, 1); assert.sameValue(Object.getPrototypeOf(result), construct.prototype);
resultAssertions(result);
},
/* * Check that the constructor's @@species property is ignored when it's * undefined.
*/
checkSubclassSpeciesUndefined(construct, constructArgs, method, methodArgs, resultAssertions) {
let called = 0;
const result = instance[method](...methodArgs); assert.sameValue(called, 1); assert.sameValue(Object.getPrototypeOf(result), construct.prototype);
resultAssertions(result);
},
/* * Check that the constructor's @@species property is ignored when it throws, * i.e. it is not called at all.
*/
checkSubclassSpeciesThrows(construct, constructArgs, method, methodArgs, resultAssertions) { function CustomError() {}
const instance = new construct(...constructArgs);
instance.constructor = {
get [Symbol.species]() { thrownew CustomError();
},
};
const result = instance[method](...methodArgs); assert.sameValue(Object.getPrototypeOf(result), construct.prototype);
},
/* * checkSubclassingIgnoredStatic(construct, method, methodArgs, resultAssertions): * * Static methods of Temporal classes that return a new instance of the class, * must not use the this-value as a constructor. This helper runs tests to * ensure this. * * construct[method](...methodArgs) is the static method call under test, and * must yield a valid instance of the Temporal class, not a subclass. See * below for the individual tests that this runs. * resultAssertions() is a function that performs additional assertions on the * instance returned by the method under test.
*/
checkSubclassingIgnoredStatic(...args) { this.checkStaticInvalidReceiver(...args); this.checkStaticReceiverNotCalled(...args); this.checkThisValueNotCalled(...args);
},
/* * Check that calling the static method with a receiver that's not callable, * still calls the intrinsic constructor.
*/
checkStaticInvalidReceiver(construct, method, methodArgs, resultAssertions) { function check(value, description) { const result = construct[method].apply(value, methodArgs); assert.sameValue(Object.getPrototypeOf(result), construct.prototype);
resultAssertions(result);
}
/* * Check that calling the static method with a receiver that returns a value * that's not callable, still calls the intrinsic constructor.
*/
checkStaticReceiverNotCalled(construct, method, methodArgs, resultAssertions) { function check(value, description) { const receiver = function () { return value;
}; const result = construct[method].apply(receiver, methodArgs); assert.sameValue(Object.getPrototypeOf(result), construct.prototype);
resultAssertions(result);
}
/* * Check that the receiver isn't called.
*/
checkThisValueNotCalled(construct, method, methodArgs, resultAssertions) {
let called = false;
class MySubclass extends construct {
constructor(...args) {
called = true; super(...args);
}
}
const result = MySubclass[method](...methodArgs); assert.sameValue(called, false); assert.sameValue(Object.getPrototypeOf(result), construct.prototype);
resultAssertions(result);
},
/* * Check that any calendar-carrying Temporal object has its [[Calendar]] * internal slot read by ToTemporalCalendar, and does not fetch the calendar * by calling getters.
*/
checkToTemporalCalendarFastPath(func) { const plainDate = new Temporal.PlainDate(2000, 5, 2, "iso8601"); const plainDateTime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, "iso8601"); const plainMonthDay = new Temporal.PlainMonthDay(5, 2, "iso8601"); const plainYearMonth = new Temporal.PlainYearMonth(2000, 5, "iso8601"); const zonedDateTime = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601");
func(date); assert.compareArray(actual, expected, "property getters not called");
},
/* * observeProperty(calls, object, propertyName, value): * * Defines an own property @object.@propertyName with value @value, that * will log any calls to its accessors to the array @calls.
*/
observeProperty(calls, object, propertyName, value, objectName = "") {
Object.defineProperty(object, propertyName, {
get() {
calls.push(`get ${formatPropertyName(propertyName, objectName)}`); return value;
},
set(v) {
calls.push(`set ${formatPropertyName(propertyName, objectName)}`);
}
});
},
/* * observeMethod(calls, object, propertyName, value): * * Defines an own property @object.@propertyName with value @value, that * will log any calls of @value to the array @calls.
*/
observeMethod(calls, object, propertyName, objectName = "") { const method = object[propertyName];
object[propertyName] = function () {
calls.push(`call ${formatPropertyName(propertyName, objectName)}`); return method.apply(object, arguments);
};
},
/* * Used for substituteMethod to indicate default behavior instead of a * substituted value
*/
SUBSTITUTE_SKIP: SKIP_SYMBOL,
/* * substituteMethod(object, propertyName, values): * * Defines an own property @object.@propertyName that will, for each * subsequent call to the method previously defined as * @object.@propertyName: * - Call the method, if no more values remain * - Call the method, if the value in @values for the corresponding call * is SUBSTITUTE_SKIP * - Otherwise, return the corresponding value in @value
*/
substituteMethod(object, propertyName, values) {
let calls = 0; const method = object[propertyName];
object[propertyName] = function () { if (calls >= values.length) { return method.apply(object, arguments);
} elseif (values[calls] === SKIP_SYMBOL) {
calls++; return method.apply(object, arguments);
} else { return values[calls++];
}
};
},
/* * propertyBagObserver(): * Returns an object that behaves like the given propertyBag but tracks Get * and Has operations on any of its properties, by appending messages to an * array. If the value of a property in propertyBag is a primitive, the value * of the returned object's property will additionally be a * TemporalHelpers.toPrimitiveObserver that will track calls to its toString * and valueOf methods in the same array. This is for the purpose of testing * order of operations that are observable from user code. objectName is used * in the log. * If skipToPrimitive is given, it must be an array of property keys. Those * properties will not have a TemporalHelpers.toPrimitiveObserver returned, * and instead just be returned directly.
*/
propertyBagObserver(calls, propertyBag, objectName, skipToPrimitive) { returnnew Proxy(propertyBag, {
ownKeys(target) {
calls.push(`ownKeys ${objectName}`); return Reflect.ownKeys(target);
},
getOwnPropertyDescriptor(target, key) {
calls.push(`getOwnPropertyDescriptor ${formatPropertyName(key, objectName)}`); return Reflect.getOwnPropertyDescriptor(target, key);
},
get(target, key, receiver) {
calls.push(`get ${formatPropertyName(key, objectName)}`); const result = Reflect.get(target, key, receiver); if (result === undefined) { return undefined;
} if ((result !== null && typeof result === "object") || typeof result === "function") { return result;
} if (skipToPrimitive && skipToPrimitive.indexOf(key) >= 0) { return result;
} return TemporalHelpers.toPrimitiveObserver(calls, result, `${formatPropertyName(key, objectName)}`);
},
has(target, key) {
calls.push(`has ${formatPropertyName(key, objectName)}`); return Reflect.has(target, key);
},
});
},
/* * Returns an object that will append logs of any Gets or Calls of its valueOf * or toString properties to the array calls. Both valueOf and toString will * return the actual primitiveValue. propertyName is used in the log.
*/
toPrimitiveObserver(calls, primitiveValue, propertyName) { return {
get valueOf() {
calls.push(`get ${propertyName}.valueOf`); returnfunction () {
calls.push(`call ${propertyName}.valueOf`); return primitiveValue;
};
},
get toString() {
calls.push(`get ${propertyName}.toString`); returnfunction () {
calls.push(`call ${propertyName}.toString`); if (primitiveValue === undefined) return undefined; return primitiveValue.toString();
};
},
};
},
/* * An object containing further methods that return arrays of ISO strings, for * testing parsers.
*/
ISO: { /* * PlainMonthDay strings that are not valid.
*/
plainMonthDayStringsInvalid() { return [ "11-18junk", "11-18[u-ca=gregory]", "11-18[u-ca=hebrew]", "11-18[U-CA=iso8601]", "11-18[u-CA=iso8601]", "11-18[FOO=bar]",
];
},
/* * PlainMonthDay strings that are valid and that should produce October 1st.
*/
plainMonthDayStringsValid() { return [ "10-01", "1001", "1965-10-01", "1976-10-01T152330.1+00:00", "19761001T15:23:30.1+00:00", "1976-10-01T15:23:30.1+0000", "1976-10-01T152330.1+0000", "19761001T15:23:30.1+0000", "19761001T152330.1+00:00", "19761001T152330.1+0000", "+001976-10-01T152330.1+00:00", "+0019761001T15:23:30.1+00:00", "+001976-10-01T15:23:30.1+0000", "+001976-10-01T152330.1+0000", "+0019761001T15:23:30.1+0000", "+0019761001T152330.1+00:00", "+0019761001T152330.1+0000", "1976-10-01T15:23:00", "1976-10-01T15:23", "1976-10-01T15", "1976-10-01", "--10-01", "--1001",
];
},
/* * PlainTime strings that may be mistaken for PlainMonthDay or * PlainYearMonth strings, and so require a time designator.
*/
plainTimeStringsAmbiguous() { const ambiguousStrings = [ "2021-12", // ambiguity between YYYY-MM and HHMM-UU "2021-12[-12:00]", // ditto, TZ does not disambiguate "1214", // ambiguity between MMDD and HHMM "0229", // ditto, including MMDD that doesn't occur every year "1130", // ditto, including DD that doesn't occur in every month "12-14", // ambiguity between MM-DD and HH-UU "12-14[-14:00]", // ditto, TZ does not disambiguate "202112", // ambiguity between YYYYMM and HHMMSS "202112[UTC]", // ditto, TZ does not disambiguate
]; // Adding a calendar annotation to one of these strings must not cause // disambiguation in favour of time. const stringsWithCalendar = ambiguousStrings.map((s) => s + '[u-ca=iso8601]'); return ambiguousStrings.concat(stringsWithCalendar);
},
/* * PlainTime strings that are of similar form to PlainMonthDay and * PlainYearMonth strings, but are not ambiguous due to components that * aren't valid as months or days.
*/
plainTimeStringsUnambiguous() { return [ "2021-13", // 13 is not a month "202113", // ditto "2021-13[-13:00]", // ditto "202113[-13:00]", // ditto "0000-00", // 0 is not a month "000000", // ditto "0000-00[UTC]", // ditto "000000[UTC]", // ditto "1314", // 13 is not a month "13-14", // ditto "1232", // 32 is not a day "0230", // 30 is not a day in February "0631", // 31 is not a day in June "0000", // 0 is neither a month nor a day "00-00", // ditto
];
},
/* * PlainYearMonth-like strings that are not valid.
*/
plainYearMonthStringsInvalid() { return [ "2020-13", "1976-11[u-ca=gregory]", "1976-11[u-ca=hebrew]", "1976-11[U-CA=iso8601]", "1976-11[u-CA=iso8601]", "1976-11[FOO=bar]",
];
},
/* * PlainYearMonth-like strings that are valid and should produce November * 1976 in the ISO 8601 calendar.
*/
plainYearMonthStringsValid() { return [ "1976-11", "1976-11-10", "1976-11-01T09:00:00+00:00", "1976-11-01T00:00:00+05:00", "197611", "+00197611", "1976-11-18T15:23:30.1-02:00", "1976-11-18T152330.1+00:00", "19761118T15:23:30.1+00:00", "1976-11-18T15:23:30.1+0000", "1976-11-18T152330.1+0000", "19761118T15:23:30.1+0000", "19761118T152330.1+00:00", "19761118T152330.1+0000", "+001976-11-18T152330.1+00:00", "+0019761118T15:23:30.1+00:00", "+001976-11-18T15:23:30.1+0000", "+001976-11-18T152330.1+0000", "+0019761118T15:23:30.1+0000", "+0019761118T152330.1+00:00", "+0019761118T152330.1+0000", "1976-11-18T15:23", "1976-11-18T15", "1976-11-18",
];
},
/* * PlainYearMonth-like strings that are valid and should produce November of * the ISO year -9999.
*/
plainYearMonthStringsValidNegativeYear() { return [ "-009999-11",
];
},
}
};
Messung V0.5
¤ Dauer der Verarbeitung: 0.19 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.