tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

shell.js (47677B)


      1 // GENERATED, DO NOT EDIT
      2 // file: temporalHelpers.js
      3 // Copyright (C) 2021 Igalia, S.L. All rights reserved.
      4 // This code is governed by the BSD license found in the LICENSE file.
      5 /*---
      6 description: |
      7    This defines helper objects and functions for testing Temporal.
      8 defines: [TemporalHelpers]
      9 features: [Symbol.species, Symbol.iterator, Temporal]
     10 ---*/
     11 
     12 const ASCII_IDENTIFIER = /^[$_a-zA-Z][$_a-zA-Z0-9]*$/u;
     13 
     14 function formatPropertyName(propertyKey, objectName = "") {
     15  switch (typeof propertyKey) {
     16    case "symbol":
     17      if (Symbol.keyFor(propertyKey) !== undefined) {
     18        return `${objectName}[Symbol.for('${Symbol.keyFor(propertyKey)}')]`;
     19      } else if (propertyKey.description.startsWith("Symbol.")) {
     20        return `${objectName}[${propertyKey.description}]`;
     21      } else {
     22        return `${objectName}[Symbol('${propertyKey.description}')]`;
     23      }
     24    case "string":
     25      if (propertyKey !== String(Number(propertyKey))) {
     26        if (ASCII_IDENTIFIER.test(propertyKey)) {
     27          return objectName ? `${objectName}.${propertyKey}` : propertyKey;
     28        }
     29        return `${objectName}['${propertyKey.replace(/'/g, "\\'")}']`;
     30      }
     31      // fall through
     32    default:
     33      // integer or string integer-index
     34      return `${objectName}[${propertyKey}]`;
     35  }
     36 }
     37 
     38 const SKIP_SYMBOL = Symbol("Skip");
     39 
     40 var TemporalHelpers = {
     41  /*
     42   * Codes and maximum lengths of months in the ISO 8601 calendar.
     43   */
     44  ISOMonths: [
     45    { month: 1, monthCode: "M01", daysInMonth: 31 },
     46    { month: 2, monthCode: "M02", daysInMonth: 29 },
     47    { month: 3, monthCode: "M03", daysInMonth: 31 },
     48    { month: 4, monthCode: "M04", daysInMonth: 30 },
     49    { month: 5, monthCode: "M05", daysInMonth: 31 },
     50    { month: 6, monthCode: "M06", daysInMonth: 30 },
     51    { month: 7, monthCode: "M07", daysInMonth: 31 },
     52    { month: 8, monthCode: "M08", daysInMonth: 31 },
     53    { month: 9, monthCode: "M09", daysInMonth: 30 },
     54    { month: 10, monthCode: "M10", daysInMonth: 31 },
     55    { month: 11, monthCode: "M11", daysInMonth: 30 },
     56    { month: 12, monthCode: "M12", daysInMonth: 31 }
     57  ],
     58 
     59  /*
     60   * List of known calendar eras and their possible aliases.
     61   *
     62   * https://tc39.es/proposal-intl-era-monthcode/#table-eras
     63   */
     64  CalendarEras: {
     65    buddhist: [
     66      { era: "be" },
     67    ],
     68    coptic: [
     69      { era: "am" },
     70    ],
     71    ethiopic: [
     72      { era: "aa", aliases: ["mundi"] },
     73      { era: "am", aliases: ["incar"] },
     74    ],
     75    ethioaa: [
     76      { era: "aa", aliases: ["mundi"] },
     77    ],
     78    gregory: [
     79      { era: "bce", aliases: ["bc"] },
     80      { era: "ce", aliases: ["ad"] },
     81    ],
     82    hebrew: [
     83      { era: "am" },
     84    ],
     85    indian: [
     86      { era: "shaka" },
     87    ],
     88    islamic: [
     89      { era: "ah" },
     90      { era: "bh" },
     91    ],
     92    "islamic-civil": [
     93      { era: "bh" },
     94      { era: "ah" },
     95    ],
     96    "islamic-rgsa": [
     97      { era: "bh" },
     98      { era: "ah" },
     99    ],
    100    "islamic-tbla": [
    101      { era: "bh" },
    102      { era: "ah" },
    103    ],
    104    "islamic-umalqura": [
    105      { era: "bh" },
    106      { era: "ah" },
    107    ],
    108    japanese: [
    109      { era: "bce", aliases: ["bc"] },
    110      { era: "ce", aliases: ["ad"] },
    111      { era: "heisei" },
    112      { era: "meiji" },
    113      { era: "reiwa" },
    114      { era: "showa" },
    115      { era: "taisho" },
    116    ],
    117    persian: [
    118      { era: "ap" },
    119    ],
    120    roc: [
    121      { era: "roc", aliases: ["minguo"] },
    122      { era: "broc", aliases: ["before-roc", "minguo-qian"] },
    123    ],
    124  },
    125 
    126  /*
    127   * Return the canonical era code.
    128   */
    129  canonicalizeCalendarEra(calendarId, eraName) {
    130    assert.sameValue(typeof calendarId, "string", "calendar must be string in canonicalizeCalendarEra");
    131 
    132    if (!Object.prototype.hasOwnProperty.call(TemporalHelpers.CalendarEras, calendarId)) {
    133      assert.sameValue(eraName, undefined);
    134      return undefined;
    135    }
    136 
    137    assert.sameValue(typeof eraName, "string", "eraName must be string or undefined in canonicalizeCalendarEra");
    138 
    139    for (let {era, aliases = []} of TemporalHelpers.CalendarEras[calendarId]) {
    140      if (era === eraName || aliases.includes(eraName)) {
    141        return era;
    142      }
    143    }
    144    throw new Test262Error(`Unsupported era name: ${eraName}`);
    145  },
    146 
    147  /*
    148   * assertDuration(duration, years, ...,  nanoseconds[, description]):
    149   *
    150   * Shorthand for asserting that each field of a Temporal.Duration is equal to
    151   * an expected value.
    152   */
    153  assertDuration(duration, years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds, description = "") {
    154    const prefix = description ? `${description}: ` : "";
    155    assert(duration instanceof Temporal.Duration, `${prefix}instanceof`);
    156    assert.sameValue(duration.years, years, `${prefix}years result:`);
    157    assert.sameValue(duration.months, months, `${prefix}months result:`);
    158    assert.sameValue(duration.weeks, weeks, `${prefix}weeks result:`);
    159    assert.sameValue(duration.days, days, `${prefix}days result:`);
    160    assert.sameValue(duration.hours, hours, `${prefix}hours result:`);
    161    assert.sameValue(duration.minutes, minutes, `${prefix}minutes result:`);
    162    assert.sameValue(duration.seconds, seconds, `${prefix}seconds result:`);
    163    assert.sameValue(duration.milliseconds, milliseconds, `${prefix}milliseconds result:`);
    164    assert.sameValue(duration.microseconds, microseconds, `${prefix}microseconds result:`);
    165    assert.sameValue(duration.nanoseconds, nanoseconds, `${prefix}nanoseconds result`);
    166  },
    167 
    168  /*
    169   * assertDateDuration(duration, years, months, weeks, days, [, description]):
    170   *
    171   * Shorthand for asserting that each date field of a Temporal.Duration is
    172   * equal to an expected value.
    173   */
    174  assertDateDuration(duration, years, months, weeks, days, description = "") {
    175    const prefix = description ? `${description}: ` : "";
    176    assert(duration instanceof Temporal.Duration, `${prefix}instanceof`);
    177    assert.sameValue(duration.years, years, `${prefix}years result:`);
    178    assert.sameValue(duration.months, months, `${prefix}months result:`);
    179    assert.sameValue(duration.weeks, weeks, `${prefix}weeks result:`);
    180    assert.sameValue(duration.days, days, `${prefix}days result:`);
    181    assert.sameValue(duration.hours, 0, `${prefix}hours result should be zero:`);
    182    assert.sameValue(duration.minutes, 0, `${prefix}minutes result should be zero:`);
    183    assert.sameValue(duration.seconds, 0, `${prefix}seconds result should be zero:`);
    184    assert.sameValue(duration.milliseconds, 0, `${prefix}milliseconds result should be zero:`);
    185    assert.sameValue(duration.microseconds, 0, `${prefix}microseconds result should be zero:`);
    186    assert.sameValue(duration.nanoseconds, 0, `${prefix}nanoseconds result should be zero:`);
    187  },
    188 
    189  /*
    190   * assertDurationsEqual(actual, expected[, description]):
    191   *
    192   * Shorthand for asserting that each field of a Temporal.Duration is equal to
    193   * the corresponding field in another Temporal.Duration.
    194   */
    195  assertDurationsEqual(actual, expected, description = "") {
    196    const prefix = description ? `${description}: ` : "";
    197    assert(expected instanceof Temporal.Duration, `${prefix}expected value should be a Temporal.Duration`);
    198    TemporalHelpers.assertDuration(actual, expected.years, expected.months, expected.weeks, expected.days, expected.hours, expected.minutes, expected.seconds, expected.milliseconds, expected.microseconds, expected.nanoseconds, description);
    199  },
    200 
    201  /*
    202   * assertInstantsEqual(actual, expected[, description]):
    203   *
    204   * Shorthand for asserting that two Temporal.Instants are of the correct type
    205   * and equal according to their equals() methods.
    206   */
    207  assertInstantsEqual(actual, expected, description = "") {
    208    const prefix = description ? `${description}: ` : "";
    209    assert(expected instanceof Temporal.Instant, `${prefix}expected value should be a Temporal.Instant`);
    210    assert(actual instanceof Temporal.Instant, `${prefix}instanceof`);
    211    assert(actual.equals(expected), `${prefix}equals method`);
    212  },
    213 
    214  /*
    215   * assertPlainDate(date, year, ..., nanosecond[, description[, era, eraYear]]):
    216   *
    217   * Shorthand for asserting that each field of a Temporal.PlainDate is equal to
    218   * an expected value. (Except the `calendar` property, since callers may want
    219   * to assert either object equality with an object they put in there, or the
    220   * value of date.calendarId.)
    221   */
    222  assertPlainDate(date, year, month, monthCode, day, description = "", era = undefined, eraYear = undefined) {
    223    const prefix = description ? `${description}: ` : "";
    224    assert(date instanceof Temporal.PlainDate, `${prefix}instanceof`);
    225    assert.sameValue(
    226      TemporalHelpers.canonicalizeCalendarEra(date.calendarId, date.era),
    227      TemporalHelpers.canonicalizeCalendarEra(date.calendarId, era),
    228      `${prefix}era result:`
    229    );
    230    assert.sameValue(date.eraYear, eraYear, `${prefix}eraYear result:`);
    231    assert.sameValue(date.year, year, `${prefix}year result:`);
    232    assert.sameValue(date.month, month, `${prefix}month result:`);
    233    assert.sameValue(date.monthCode, monthCode, `${prefix}monthCode result:`);
    234    assert.sameValue(date.day, day, `${prefix}day result:`);
    235  },
    236 
    237  /*
    238   * assertPlainDateTime(datetime, year, ..., nanosecond[, description[, era, eraYear]]):
    239   *
    240   * Shorthand for asserting that each field of a Temporal.PlainDateTime is
    241   * equal to an expected value. (Except the `calendar` property, since callers
    242   * may want to assert either object equality with an object they put in there,
    243   * or the value of datetime.calendarId.)
    244   */
    245  assertPlainDateTime(datetime, year, month, monthCode, day, hour, minute, second, millisecond, microsecond, nanosecond, description = "", era = undefined, eraYear = undefined) {
    246    const prefix = description ? `${description}: ` : "";
    247    assert(datetime instanceof Temporal.PlainDateTime, `${prefix}instanceof`);
    248    assert.sameValue(
    249      TemporalHelpers.canonicalizeCalendarEra(datetime.calendarId, datetime.era),
    250      TemporalHelpers.canonicalizeCalendarEra(datetime.calendarId, era),
    251      `${prefix}era result:`
    252    );
    253    assert.sameValue(datetime.eraYear, eraYear, `${prefix}eraYear result:`);
    254    assert.sameValue(datetime.year, year, `${prefix}year result:`);
    255    assert.sameValue(datetime.month, month, `${prefix}month result:`);
    256    assert.sameValue(datetime.monthCode, monthCode, `${prefix}monthCode result:`);
    257    assert.sameValue(datetime.day, day, `${prefix}day result:`);
    258    assert.sameValue(datetime.hour, hour, `${prefix}hour result:`);
    259    assert.sameValue(datetime.minute, minute, `${prefix}minute result:`);
    260    assert.sameValue(datetime.second, second, `${prefix}second result:`);
    261    assert.sameValue(datetime.millisecond, millisecond, `${prefix}millisecond result:`);
    262    assert.sameValue(datetime.microsecond, microsecond, `${prefix}microsecond result:`);
    263    assert.sameValue(datetime.nanosecond, nanosecond, `${prefix}nanosecond result:`);
    264  },
    265 
    266  /*
    267   * assertPlainDateTimesEqual(actual, expected[, description]):
    268   *
    269   * Shorthand for asserting that two Temporal.PlainDateTimes are of the correct
    270   * type, equal according to their equals() methods, and additionally that
    271   * their calendar internal slots are the same value.
    272   */
    273  assertPlainDateTimesEqual(actual, expected, description = "") {
    274    const prefix = description ? `${description}: ` : "";
    275    assert(expected instanceof Temporal.PlainDateTime, `${prefix}expected value should be a Temporal.PlainDateTime`);
    276    assert(actual instanceof Temporal.PlainDateTime, `${prefix}instanceof`);
    277    assert(actual.equals(expected), `${prefix}equals method`);
    278    assert.sameValue(
    279      actual.calendarId,
    280      expected.calendarId,
    281      `${prefix}calendar same value:`
    282    );
    283  },
    284 
    285  /*
    286   * assertPlainMonthDay(monthDay, monthCode, day[, description [, referenceISOYear]]):
    287   *
    288   * Shorthand for asserting that each field of a Temporal.PlainMonthDay is
    289   * equal to an expected value. (Except the `calendar` property, since callers
    290   * may want to assert either object equality with an object they put in there,
    291   * or the value of monthDay.calendarId().)
    292   */
    293  assertPlainMonthDay(monthDay, monthCode, day, description = "", referenceISOYear = 1972) {
    294    const prefix = description ? `${description}: ` : "";
    295    assert(monthDay instanceof Temporal.PlainMonthDay, `${prefix}instanceof`);
    296    assert.sameValue(monthDay.monthCode, monthCode, `${prefix}monthCode result:`);
    297    assert.sameValue(monthDay.day, day, `${prefix}day result:`);
    298    const isoYear = Number(monthDay.toString({ calendarName: "always" }).split("-")[0]);
    299    assert.sameValue(isoYear, referenceISOYear, `${prefix}referenceISOYear result:`);
    300  },
    301 
    302  /*
    303   * assertPlainTime(time, hour, ..., nanosecond[, description]):
    304   *
    305   * Shorthand for asserting that each field of a Temporal.PlainTime is equal to
    306   * an expected value.
    307   */
    308  assertPlainTime(time, hour, minute, second, millisecond, microsecond, nanosecond, description = "") {
    309    const prefix = description ? `${description}: ` : "";
    310    assert(time instanceof Temporal.PlainTime, `${prefix}instanceof`);
    311    assert.sameValue(time.hour, hour, `${prefix}hour result:`);
    312    assert.sameValue(time.minute, minute, `${prefix}minute result:`);
    313    assert.sameValue(time.second, second, `${prefix}second result:`);
    314    assert.sameValue(time.millisecond, millisecond, `${prefix}millisecond result:`);
    315    assert.sameValue(time.microsecond, microsecond, `${prefix}microsecond result:`);
    316    assert.sameValue(time.nanosecond, nanosecond, `${prefix}nanosecond result:`);
    317  },
    318 
    319  /*
    320   * assertPlainTimesEqual(actual, expected[, description]):
    321   *
    322   * Shorthand for asserting that two Temporal.PlainTimes are of the correct
    323   * type and equal according to their equals() methods.
    324   */
    325  assertPlainTimesEqual(actual, expected, description = "") {
    326    const prefix = description ? `${description}: ` : "";
    327    assert(expected instanceof Temporal.PlainTime, `${prefix}expected value should be a Temporal.PlainTime`);
    328    assert(actual instanceof Temporal.PlainTime, `${prefix}instanceof`);
    329    assert(actual.equals(expected), `${prefix}equals method`);
    330  },
    331 
    332  /*
    333   * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]):
    334   *
    335   * Shorthand for asserting that each field of a Temporal.PlainYearMonth is
    336   * equal to an expected value. (Except the `calendar` property, since callers
    337   * may want to assert either object equality with an object they put in there,
    338   * or the value of yearMonth.calendarId.)
    339   *
    340   * Pass null as the referenceISODay if you don't want to give it explicitly.
    341   * In that case, the expected referenceISODay will be computed using PlainDate
    342   * and only verified for consistency, not for equality with a specific value.
    343   */
    344  assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) {
    345    const prefix = description ? `${description}: ` : "";
    346    assert(typeof referenceISODay === "number" || referenceISODay === null,
    347      `TemporalHelpers.assertPlainYearMonth() referenceISODay argument should be a number or null, not ${referenceISODay}`);
    348    assert(yearMonth instanceof Temporal.PlainYearMonth, `${prefix}instanceof`);
    349    assert.sameValue(
    350      TemporalHelpers.canonicalizeCalendarEra(yearMonth.calendarId, yearMonth.era),
    351      TemporalHelpers.canonicalizeCalendarEra(yearMonth.calendarId, era),
    352      `${prefix}era result:`
    353    );
    354    assert.sameValue(yearMonth.eraYear, eraYear, `${prefix}eraYear result:`);
    355    assert.sameValue(yearMonth.year, year, `${prefix}year result:`);
    356    assert.sameValue(yearMonth.month, month, `${prefix}month result:`);
    357    assert.sameValue(yearMonth.monthCode, monthCode, `${prefix}monthCode result:`);
    358    const isoDay = Number(yearMonth.toString({ calendarName: "always" }).slice(1).split("-")[2].slice(0, 2));
    359    const expectedISODay = referenceISODay ?? yearMonth.toPlainDate({ day: 1 }).withCalendar("iso8601").day;
    360    assert.sameValue(isoDay, expectedISODay, `${prefix}referenceISODay result:`);
    361  },
    362 
    363  /*
    364   * assertZonedDateTimesEqual(actual, expected[, description]):
    365   *
    366   * Shorthand for asserting that two Temporal.ZonedDateTimes are of the correct
    367   * type, equal according to their equals() methods, and additionally that
    368   * their time zones and calendar internal slots are the same value.
    369   */
    370  assertZonedDateTimesEqual(actual, expected, description = "") {
    371    const prefix = description ? `${description}: ` : "";
    372    assert(expected instanceof Temporal.ZonedDateTime, `${prefix}expected value should be a Temporal.ZonedDateTime`);
    373    assert(actual instanceof Temporal.ZonedDateTime, `${prefix}instanceof`);
    374    assert(actual.equals(expected), `${prefix}equals method`);
    375    assert.sameValue(actual.timeZoneId, expected.timeZoneId, `${prefix}time zone same value:`);
    376    assert.sameValue(
    377      actual.calendarId,
    378      expected.calendarId,
    379      `${prefix}calendar same value:`
    380    );
    381  },
    382 
    383  /*
    384   * assertUnreachable(description):
    385   *
    386   * Helper for asserting that code is not executed.
    387   */
    388  assertUnreachable(description) {
    389    let message = "This code should not be executed";
    390    if (description) {
    391      message = `${message}: ${description}`;
    392    }
    393    throw new Test262Error(message);
    394  },
    395 
    396  /*
    397   * checkPlainDateTimeConversionFastPath(func):
    398   *
    399   * ToTemporalDate and ToTemporalTime should both, if given a
    400   * Temporal.PlainDateTime instance, convert to the desired type by reading the
    401   * PlainDateTime's internal slots, rather than calling any getters.
    402   *
    403   * func(datetime) is the actual operation to test, that must
    404   * internally call the abstract operation ToTemporalDate or ToTemporalTime.
    405   * It is passed a Temporal.PlainDateTime instance.
    406   */
    407  checkPlainDateTimeConversionFastPath(func, message = "checkPlainDateTimeConversionFastPath") {
    408    const actual = [];
    409    const expected = [];
    410 
    411    const calendar = "iso8601";
    412    const datetime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, calendar);
    413    const prototypeDescrs = Object.getOwnPropertyDescriptors(Temporal.PlainDateTime.prototype);
    414    ["year", "month", "monthCode", "day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond"].forEach((property) => {
    415      Object.defineProperty(datetime, property, {
    416        get() {
    417          actual.push(`get ${formatPropertyName(property)}`);
    418          const value = prototypeDescrs[property].get.call(this);
    419          return {
    420            toString() {
    421              actual.push(`toString ${formatPropertyName(property)}`);
    422              return value.toString();
    423            },
    424            valueOf() {
    425              actual.push(`valueOf ${formatPropertyName(property)}`);
    426              return value;
    427            },
    428          };
    429        },
    430      });
    431    });
    432    Object.defineProperty(datetime, "calendar", {
    433      get() {
    434        actual.push("get calendar");
    435        return calendar;
    436      },
    437    });
    438 
    439    func(datetime);
    440    assert.compareArray(actual, expected, `${message}: property getters not called`);
    441  },
    442 
    443  /*
    444   * Check that an options bag that accepts units written in the singular form,
    445   * also accepts the same units written in the plural form.
    446   * func(unit) should call the method with the appropriate options bag
    447   * containing unit as a value. This will be called twice for each element of
    448   * validSingularUnits, once with singular and once with plural, and the
    449   * results of each pair should be the same (whether a Temporal object or a
    450   * primitive value.)
    451   */
    452  checkPluralUnitsAccepted(func, validSingularUnits) {
    453    const plurals = {
    454      year: "years",
    455      month: "months",
    456      week: "weeks",
    457      day: "days",
    458      hour: "hours",
    459      minute: "minutes",
    460      second: "seconds",
    461      millisecond: "milliseconds",
    462      microsecond: "microseconds",
    463      nanosecond: "nanoseconds",
    464    };
    465 
    466    validSingularUnits.forEach((unit) => {
    467      const singularValue = func(unit);
    468      const pluralValue = func(plurals[unit]);
    469      const desc = `Plural ${plurals[unit]} produces the same result as singular ${unit}`;
    470      if (singularValue instanceof Temporal.Duration) {
    471        TemporalHelpers.assertDurationsEqual(pluralValue, singularValue, desc);
    472      } else if (singularValue instanceof Temporal.Instant) {
    473        TemporalHelpers.assertInstantsEqual(pluralValue, singularValue, desc);
    474      } else if (singularValue instanceof Temporal.PlainDateTime) {
    475        TemporalHelpers.assertPlainDateTimesEqual(pluralValue, singularValue, desc);
    476      } else if (singularValue instanceof Temporal.PlainTime) {
    477        TemporalHelpers.assertPlainTimesEqual(pluralValue, singularValue, desc);
    478      } else if (singularValue instanceof Temporal.ZonedDateTime) {
    479        TemporalHelpers.assertZonedDateTimesEqual(pluralValue, singularValue, desc);
    480      } else {
    481        assert.sameValue(pluralValue, singularValue);
    482      }
    483    });
    484  },
    485 
    486  /*
    487   * checkRoundingIncrementOptionWrongType(checkFunc, assertTrueResultFunc, assertObjectResultFunc):
    488   *
    489   * Checks the type handling of the roundingIncrement option.
    490   * checkFunc(roundingIncrement) is a function which takes the value of
    491   * roundingIncrement to test, and calls the method under test with it,
    492   * returning the result. assertTrueResultFunc(result, description) should
    493   * assert that result is the expected result with roundingIncrement: true, and
    494   * assertObjectResultFunc(result, description) should assert that result is
    495   * the expected result with roundingIncrement being an object with a valueOf()
    496   * method.
    497   */
    498  checkRoundingIncrementOptionWrongType(checkFunc, assertTrueResultFunc, assertObjectResultFunc) {
    499    // null converts to 0, which is out of range
    500    assert.throws(RangeError, () => checkFunc(null), "null");
    501    // Booleans convert to either 0 or 1, and 1 is allowed
    502    const trueResult = checkFunc(true);
    503    assertTrueResultFunc(trueResult, "true");
    504    assert.throws(RangeError, () => checkFunc(false), "false");
    505    // Symbols and BigInts cannot convert to numbers
    506    assert.throws(TypeError, () => checkFunc(Symbol()), "symbol");
    507    assert.throws(TypeError, () => checkFunc(2n), "bigint");
    508 
    509    // Objects prefer their valueOf() methods when converting to a number
    510    assert.throws(RangeError, () => checkFunc({}), "plain object");
    511 
    512    const expected = [
    513      "get roundingIncrement.valueOf",
    514      "call roundingIncrement.valueOf",
    515    ];
    516    const actual = [];
    517    const observer = TemporalHelpers.toPrimitiveObserver(actual, 2, "roundingIncrement");
    518    const objectResult = checkFunc(observer);
    519    assertObjectResultFunc(objectResult, "object with valueOf");
    520    assert.compareArray(actual, expected, "order of operations");
    521  },
    522 
    523  /*
    524   * checkStringOptionWrongType(propertyName, value, checkFunc, assertFunc):
    525   *
    526   * Checks the type handling of a string option, of which there are several in
    527   * Temporal.
    528   * propertyName is the name of the option, and value is the value that
    529   * assertFunc should expect it to have.
    530   * checkFunc(value) is a function which takes the value of the option to test,
    531   * and calls the method under test with it, returning the result.
    532   * assertFunc(result, description) should assert that result is the expected
    533   * result with the option value being an object with a toString() method
    534   * which returns the given value.
    535   */
    536  checkStringOptionWrongType(propertyName, value, checkFunc, assertFunc) {
    537    // null converts to the string "null", which is an invalid string value
    538    assert.throws(RangeError, () => checkFunc(null), "null");
    539    // Booleans convert to the strings "true" or "false", which are invalid
    540    assert.throws(RangeError, () => checkFunc(true), "true");
    541    assert.throws(RangeError, () => checkFunc(false), "false");
    542    // Symbols cannot convert to strings
    543    assert.throws(TypeError, () => checkFunc(Symbol()), "symbol");
    544    // Numbers convert to strings which are invalid
    545    assert.throws(RangeError, () => checkFunc(2), "number");
    546    // BigInts convert to strings which are invalid
    547    assert.throws(RangeError, () => checkFunc(2n), "bigint");
    548 
    549    // Objects prefer their toString() methods when converting to a string
    550    assert.throws(RangeError, () => checkFunc({}), "plain object");
    551 
    552    const expected = [
    553      `get ${propertyName}.toString`,
    554      `call ${propertyName}.toString`,
    555    ];
    556    const actual = [];
    557    const observer = TemporalHelpers.toPrimitiveObserver(actual, value, propertyName);
    558    const result = checkFunc(observer);
    559    assertFunc(result, "object with toString");
    560    assert.compareArray(actual, expected, "order of operations");
    561  },
    562 
    563  /*
    564   * checkSubclassingIgnored(construct, constructArgs, method, methodArgs,
    565   *   resultAssertions):
    566   *
    567   * Methods of Temporal classes that return a new instance of the same class,
    568   * must not take the constructor of a subclass into account, nor the @@species
    569   * property. This helper runs tests to ensure this.
    570   *
    571   * construct(...constructArgs) must yield a valid instance of the Temporal
    572   * class. instance[method](...methodArgs) is the method call under test, which
    573   * must also yield a valid instance of the same Temporal class, not a
    574   * subclass. See below for the individual tests that this runs.
    575   * resultAssertions() is a function that performs additional assertions on the
    576   * instance returned by the method under test.
    577   */
    578  checkSubclassingIgnored(...args) {
    579    this.checkSubclassConstructorNotObject(...args);
    580    this.checkSubclassConstructorUndefined(...args);
    581    this.checkSubclassConstructorThrows(...args);
    582    this.checkSubclassConstructorNotCalled(...args);
    583    this.checkSubclassSpeciesInvalidResult(...args);
    584    this.checkSubclassSpeciesNotAConstructor(...args);
    585    this.checkSubclassSpeciesNull(...args);
    586    this.checkSubclassSpeciesUndefined(...args);
    587    this.checkSubclassSpeciesThrows(...args);
    588  },
    589 
    590  /*
    591   * Checks that replacing the 'constructor' property of the instance with
    592   * various primitive values does not affect the returned new instance.
    593   */
    594  checkSubclassConstructorNotObject(construct, constructArgs, method, methodArgs, resultAssertions) {
    595    function check(value, description) {
    596      const instance = new construct(...constructArgs);
    597      instance.constructor = value;
    598      const result = instance[method](...methodArgs);
    599      assert.sameValue(Object.getPrototypeOf(result), construct.prototype, description);
    600      resultAssertions(result);
    601    }
    602 
    603    check(null, "null");
    604    check(true, "true");
    605    check("test", "string");
    606    check(Symbol(), "Symbol");
    607    check(7, "number");
    608    check(7n, "bigint");
    609  },
    610 
    611  /*
    612   * Checks that replacing the 'constructor' property of the subclass with
    613   * undefined does not affect the returned new instance.
    614   */
    615  checkSubclassConstructorUndefined(construct, constructArgs, method, methodArgs, resultAssertions) {
    616    let called = 0;
    617 
    618    class MySubclass extends construct {
    619      constructor() {
    620        ++called;
    621        super(...constructArgs);
    622      }
    623    }
    624 
    625    const instance = new MySubclass();
    626    assert.sameValue(called, 1);
    627 
    628    MySubclass.prototype.constructor = undefined;
    629 
    630    const result = instance[method](...methodArgs);
    631    assert.sameValue(called, 1);
    632    assert.sameValue(Object.getPrototypeOf(result), construct.prototype);
    633    resultAssertions(result);
    634  },
    635 
    636  /*
    637   * Checks that making the 'constructor' property of the instance throw when
    638   * called does not affect the returned new instance.
    639   */
    640  checkSubclassConstructorThrows(construct, constructArgs, method, methodArgs, resultAssertions) {
    641    function CustomError() {}
    642    const instance = new construct(...constructArgs);
    643    Object.defineProperty(instance, "constructor", {
    644      get() {
    645        throw new CustomError();
    646      }
    647    });
    648    const result = instance[method](...methodArgs);
    649    assert.sameValue(Object.getPrototypeOf(result), construct.prototype);
    650    resultAssertions(result);
    651  },
    652 
    653  /*
    654   * Checks that when subclassing, the subclass constructor is not called by
    655   * the method under test.
    656   */
    657  checkSubclassConstructorNotCalled(construct, constructArgs, method, methodArgs, resultAssertions) {
    658    let called = 0;
    659 
    660    class MySubclass extends construct {
    661      constructor() {
    662        ++called;
    663        super(...constructArgs);
    664      }
    665    }
    666 
    667    const instance = new MySubclass();
    668    assert.sameValue(called, 1);
    669 
    670    const result = instance[method](...methodArgs);
    671    assert.sameValue(called, 1);
    672    assert.sameValue(Object.getPrototypeOf(result), construct.prototype);
    673    resultAssertions(result);
    674  },
    675 
    676  /*
    677   * Check that the constructor's @@species property is ignored when it's a
    678   * constructor that returns a non-object value.
    679   */
    680  checkSubclassSpeciesInvalidResult(construct, constructArgs, method, methodArgs, resultAssertions) {
    681    function check(value, description) {
    682      const instance = new construct(...constructArgs);
    683      instance.constructor = {
    684        [Symbol.species]: function() {
    685          return value;
    686        },
    687      };
    688      const result = instance[method](...methodArgs);
    689      assert.sameValue(Object.getPrototypeOf(result), construct.prototype, description);
    690      resultAssertions(result);
    691    }
    692 
    693    check(undefined, "undefined");
    694    check(null, "null");
    695    check(true, "true");
    696    check("test", "string");
    697    check(Symbol(), "Symbol");
    698    check(7, "number");
    699    check(7n, "bigint");
    700    check({}, "plain object");
    701  },
    702 
    703  /*
    704   * Check that the constructor's @@species property is ignored when it's not a
    705   * constructor.
    706   */
    707  checkSubclassSpeciesNotAConstructor(construct, constructArgs, method, methodArgs, resultAssertions) {
    708    function check(value, description) {
    709      const instance = new construct(...constructArgs);
    710      instance.constructor = {
    711        [Symbol.species]: value,
    712      };
    713      const result = instance[method](...methodArgs);
    714      assert.sameValue(Object.getPrototypeOf(result), construct.prototype, description);
    715      resultAssertions(result);
    716    }
    717 
    718    check(true, "true");
    719    check("test", "string");
    720    check(Symbol(), "Symbol");
    721    check(7, "number");
    722    check(7n, "bigint");
    723    check({}, "plain object");
    724  },
    725 
    726  /*
    727   * Check that the constructor's @@species property is ignored when it's null.
    728   */
    729  checkSubclassSpeciesNull(construct, constructArgs, method, methodArgs, resultAssertions) {
    730    let called = 0;
    731 
    732    class MySubclass extends construct {
    733      constructor() {
    734        ++called;
    735        super(...constructArgs);
    736      }
    737    }
    738 
    739    const instance = new MySubclass();
    740    assert.sameValue(called, 1);
    741 
    742    MySubclass.prototype.constructor = {
    743      [Symbol.species]: null,
    744    };
    745 
    746    const result = instance[method](...methodArgs);
    747    assert.sameValue(called, 1);
    748    assert.sameValue(Object.getPrototypeOf(result), construct.prototype);
    749    resultAssertions(result);
    750  },
    751 
    752  /*
    753   * Check that the constructor's @@species property is ignored when it's
    754   * undefined.
    755   */
    756  checkSubclassSpeciesUndefined(construct, constructArgs, method, methodArgs, resultAssertions) {
    757    let called = 0;
    758 
    759    class MySubclass extends construct {
    760      constructor() {
    761        ++called;
    762        super(...constructArgs);
    763      }
    764    }
    765 
    766    const instance = new MySubclass();
    767    assert.sameValue(called, 1);
    768 
    769    MySubclass.prototype.constructor = {
    770      [Symbol.species]: undefined,
    771    };
    772 
    773    const result = instance[method](...methodArgs);
    774    assert.sameValue(called, 1);
    775    assert.sameValue(Object.getPrototypeOf(result), construct.prototype);
    776    resultAssertions(result);
    777  },
    778 
    779  /*
    780   * Check that the constructor's @@species property is ignored when it throws,
    781   * i.e. it is not called at all.
    782   */
    783  checkSubclassSpeciesThrows(construct, constructArgs, method, methodArgs, resultAssertions) {
    784    function CustomError() {}
    785 
    786    const instance = new construct(...constructArgs);
    787    instance.constructor = {
    788      get [Symbol.species]() {
    789        throw new CustomError();
    790      },
    791    };
    792 
    793    const result = instance[method](...methodArgs);
    794    assert.sameValue(Object.getPrototypeOf(result), construct.prototype);
    795  },
    796 
    797  /*
    798   * checkSubclassingIgnoredStatic(construct, method, methodArgs, resultAssertions):
    799   *
    800   * Static methods of Temporal classes that return a new instance of the class,
    801   * must not use the this-value as a constructor. This helper runs tests to
    802   * ensure this.
    803   *
    804   * construct[method](...methodArgs) is the static method call under test, and
    805   * must yield a valid instance of the Temporal class, not a subclass. See
    806   * below for the individual tests that this runs.
    807   * resultAssertions() is a function that performs additional assertions on the
    808   * instance returned by the method under test.
    809   */
    810  checkSubclassingIgnoredStatic(...args) {
    811    this.checkStaticInvalidReceiver(...args);
    812    this.checkStaticReceiverNotCalled(...args);
    813    this.checkThisValueNotCalled(...args);
    814  },
    815 
    816  /*
    817   * Check that calling the static method with a receiver that's not callable,
    818   * still calls the intrinsic constructor.
    819   */
    820  checkStaticInvalidReceiver(construct, method, methodArgs, resultAssertions) {
    821    function check(value, description) {
    822      const result = construct[method].apply(value, methodArgs);
    823      assert.sameValue(Object.getPrototypeOf(result), construct.prototype);
    824      resultAssertions(result);
    825    }
    826 
    827    check(undefined, "undefined");
    828    check(null, "null");
    829    check(true, "true");
    830    check("test", "string");
    831    check(Symbol(), "symbol");
    832    check(7, "number");
    833    check(7n, "bigint");
    834    check({}, "Non-callable object");
    835  },
    836 
    837  /*
    838   * Check that calling the static method with a receiver that returns a value
    839   * that's not callable, still calls the intrinsic constructor.
    840   */
    841  checkStaticReceiverNotCalled(construct, method, methodArgs, resultAssertions) {
    842    function check(value, description) {
    843      const receiver = function () {
    844        return value;
    845      };
    846      const result = construct[method].apply(receiver, methodArgs);
    847      assert.sameValue(Object.getPrototypeOf(result), construct.prototype);
    848      resultAssertions(result);
    849    }
    850 
    851    check(undefined, "undefined");
    852    check(null, "null");
    853    check(true, "true");
    854    check("test", "string");
    855    check(Symbol(), "symbol");
    856    check(7, "number");
    857    check(7n, "bigint");
    858    check({}, "Non-callable object");
    859  },
    860 
    861  /*
    862   * Check that the receiver isn't called.
    863   */
    864  checkThisValueNotCalled(construct, method, methodArgs, resultAssertions) {
    865    let called = false;
    866 
    867    class MySubclass extends construct {
    868      constructor(...args) {
    869        called = true;
    870        super(...args);
    871      }
    872    }
    873 
    874    const result = MySubclass[method](...methodArgs);
    875    assert.sameValue(called, false);
    876    assert.sameValue(Object.getPrototypeOf(result), construct.prototype);
    877    resultAssertions(result);
    878  },
    879 
    880  /*
    881   * Check that any calendar-carrying Temporal object has its [[Calendar]]
    882   * internal slot read by ToTemporalCalendar, and does not fetch the calendar
    883   * by calling getters.
    884   */
    885  checkToTemporalCalendarFastPath(func) {
    886    const plainDate = new Temporal.PlainDate(2000, 5, 2, "iso8601");
    887    const plainDateTime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, "iso8601");
    888    const plainMonthDay = new Temporal.PlainMonthDay(5, 2, "iso8601");
    889    const plainYearMonth = new Temporal.PlainYearMonth(2000, 5, "iso8601");
    890    const zonedDateTime = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601");
    891 
    892    [plainDate, plainDateTime, plainMonthDay, plainYearMonth, zonedDateTime].forEach((temporalObject) => {
    893      Object.defineProperty(temporalObject, "calendar", {
    894        get() {
    895          throw new Test262Error("should not get 'calendar' property");
    896        },
    897      });
    898      Object.defineProperty(temporalObject, "calendarId", {
    899        get() {
    900          throw new Test262Error("should not get 'calendarId' property");
    901        },
    902      });
    903 
    904      func(temporalObject);
    905    });
    906  },
    907 
    908  checkToTemporalInstantFastPath(func) {
    909    const actual = [];
    910    const expected = [];
    911 
    912    const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, "UTC");
    913    Object.defineProperty(datetime, "toString", {
    914      get() {
    915        actual.push("get toString");
    916        return function (options) {
    917          actual.push("call toString");
    918          return Temporal.ZonedDateTime.prototype.toString.call(this, options);
    919        };
    920      },
    921    });
    922 
    923    func(datetime);
    924    assert.compareArray(actual, expected, "toString not called");
    925  },
    926 
    927  checkToTemporalPlainDateTimeFastPath(func) {
    928    const actual = [];
    929    const expected = [];
    930 
    931    const date = new Temporal.PlainDate(2000, 5, 2, "iso8601");
    932    const prototypeDescrs = Object.getOwnPropertyDescriptors(Temporal.PlainDate.prototype);
    933    ["year", "month", "monthCode", "day"].forEach((property) => {
    934      Object.defineProperty(date, property, {
    935        get() {
    936          actual.push(`get ${formatPropertyName(property)}`);
    937          const value = prototypeDescrs[property].get.call(this);
    938          return TemporalHelpers.toPrimitiveObserver(actual, value, property);
    939        },
    940      });
    941    });
    942    ["hour", "minute", "second", "millisecond", "microsecond", "nanosecond"].forEach((property) => {
    943      Object.defineProperty(date, property, {
    944        get() {
    945          actual.push(`get ${formatPropertyName(property)}`);
    946          return undefined;
    947        },
    948      });
    949    });
    950    Object.defineProperty(date, "calendar", {
    951      get() {
    952        actual.push("get calendar");
    953        return "iso8601";
    954      },
    955    });
    956 
    957    func(date);
    958    assert.compareArray(actual, expected, "property getters not called");
    959  },
    960 
    961  /*
    962   * observeProperty(calls, object, propertyName, value):
    963   *
    964   * Defines an own property @object.@propertyName with value @value, that
    965   * will log any calls to its accessors to the array @calls.
    966   */
    967  observeProperty(calls, object, propertyName, value, objectName = "") {
    968    Object.defineProperty(object, propertyName, {
    969      get() {
    970        calls.push(`get ${formatPropertyName(propertyName, objectName)}`);
    971        return value;
    972      },
    973      set() {
    974        calls.push(`set ${formatPropertyName(propertyName, objectName)}`);
    975      }
    976    });
    977  },
    978 
    979  /*
    980   * observeMethod(calls, object, propertyName, value):
    981   *
    982   * Defines an own property @object.@propertyName with value @value, that
    983   * will log any calls of @value to the array @calls.
    984   */
    985  observeMethod(calls, object, propertyName, objectName = "") {
    986    const method = object[propertyName];
    987    object[propertyName] = function () {
    988      calls.push(`call ${formatPropertyName(propertyName, objectName)}`);
    989      return method.apply(object, arguments);
    990    };
    991  },
    992 
    993  /*
    994   * Used for substituteMethod to indicate default behavior instead of a
    995   * substituted value
    996   */
    997  SUBSTITUTE_SKIP: SKIP_SYMBOL,
    998 
    999  /*
   1000   * substituteMethod(object, propertyName, values):
   1001   *
   1002   * Defines an own property @object.@propertyName that will, for each
   1003   * subsequent call to the method previously defined as
   1004   * @object.@propertyName:
   1005   *  - Call the method, if no more values remain
   1006   *  - Call the method, if the value in @values for the corresponding call
   1007   *    is SUBSTITUTE_SKIP
   1008   *  - Otherwise, return the corresponding value in @value
   1009   */
   1010  substituteMethod(object, propertyName, values) {
   1011    let calls = 0;
   1012    const method = object[propertyName];
   1013    object[propertyName] = function () {
   1014      if (calls >= values.length) {
   1015        return method.apply(object, arguments);
   1016      } else if (values[calls] === SKIP_SYMBOL) {
   1017        calls++;
   1018        return method.apply(object, arguments);
   1019      } else {
   1020        return values[calls++];
   1021      }
   1022    };
   1023  },
   1024 
   1025  /*
   1026   * propertyBagObserver():
   1027   * Returns an object that behaves like the given propertyBag but tracks Get
   1028   * and Has operations on any of its properties, by appending messages to an
   1029   * array. If the value of a property in propertyBag is a primitive, the value
   1030   * of the returned object's property will additionally be a
   1031   * TemporalHelpers.toPrimitiveObserver that will track calls to its toString
   1032   * and valueOf methods in the same array. This is for the purpose of testing
   1033   * order of operations that are observable from user code. objectName is used
   1034   * in the log.
   1035   * If skipToPrimitive is given, it must be an array of property keys. Those
   1036   * properties will not have a TemporalHelpers.toPrimitiveObserver returned,
   1037   * and instead just be returned directly.
   1038   */
   1039  propertyBagObserver(calls, propertyBag, objectName, skipToPrimitive) {
   1040    return new Proxy(propertyBag, {
   1041      ownKeys(target) {
   1042        calls.push(`ownKeys ${objectName}`);
   1043        return Reflect.ownKeys(target);
   1044      },
   1045      getOwnPropertyDescriptor(target, key) {
   1046        calls.push(`getOwnPropertyDescriptor ${formatPropertyName(key, objectName)}`);
   1047        return Reflect.getOwnPropertyDescriptor(target, key);
   1048      },
   1049      get(target, key, receiver) {
   1050        calls.push(`get ${formatPropertyName(key, objectName)}`);
   1051        const result = Reflect.get(target, key, receiver);
   1052        if (result === undefined) {
   1053          return undefined;
   1054        }
   1055        if ((result !== null && typeof result === "object") || typeof result === "function") {
   1056          return result;
   1057        }
   1058        if (skipToPrimitive && skipToPrimitive.indexOf(key) >= 0) {
   1059          return result;
   1060        }
   1061        return TemporalHelpers.toPrimitiveObserver(calls, result, `${formatPropertyName(key, objectName)}`);
   1062      },
   1063      has(target, key) {
   1064        calls.push(`has ${formatPropertyName(key, objectName)}`);
   1065        return Reflect.has(target, key);
   1066      },
   1067    });
   1068  },
   1069 
   1070  /*
   1071   * Returns an object that will append logs of any Gets or Calls of its valueOf
   1072   * or toString properties to the array calls. Both valueOf and toString will
   1073   * return the actual primitiveValue. propertyName is used in the log.
   1074   */
   1075  toPrimitiveObserver(calls, primitiveValue, propertyName) {
   1076    return {
   1077      get valueOf() {
   1078        calls.push(`get ${propertyName}.valueOf`);
   1079        return function () {
   1080          calls.push(`call ${propertyName}.valueOf`);
   1081          return primitiveValue;
   1082        };
   1083      },
   1084      get toString() {
   1085        calls.push(`get ${propertyName}.toString`);
   1086        return function () {
   1087          calls.push(`call ${propertyName}.toString`);
   1088          if (primitiveValue === undefined) return undefined;
   1089          return primitiveValue.toString();
   1090        };
   1091      },
   1092    };
   1093  },
   1094 
   1095  /*
   1096   * An object containing further methods that return arrays of ISO strings, for
   1097   * testing parsers.
   1098   */
   1099  ISO: {
   1100    /*
   1101     * PlainMonthDay strings that are not valid.
   1102     */
   1103    plainMonthDayStringsInvalid() {
   1104      return [
   1105        "11-18junk",
   1106        "11-18[u-ca=gregory]",
   1107        "11-18[u-ca=hebrew]",
   1108        "11-18[U-CA=iso8601]",
   1109        "11-18[u-CA=iso8601]",
   1110        "11-18[FOO=bar]",
   1111        "-999999-01-01[u-ca=gregory]",
   1112        "-999999-01-01[u-ca=chinese]",
   1113        "+999999-01-01[u-ca=gregory]",
   1114        "+999999-01-01[u-ca=chinese]",
   1115      ];
   1116    },
   1117 
   1118    /*
   1119     * PlainMonthDay strings that are valid and that should produce October 1st.
   1120     */
   1121    plainMonthDayStringsValid() {
   1122      return [
   1123        "10-01",
   1124        "1001",
   1125        "1965-10-01",
   1126        "1976-10-01T152330.1+00:00",
   1127        "19761001T15:23:30.1+00:00",
   1128        "1976-10-01T15:23:30.1+0000",
   1129        "1976-10-01T152330.1+0000",
   1130        "19761001T15:23:30.1+0000",
   1131        "19761001T152330.1+00:00",
   1132        "19761001T152330.1+0000",
   1133        "+001976-10-01T152330.1+00:00",
   1134        "+0019761001T15:23:30.1+00:00",
   1135        "+001976-10-01T15:23:30.1+0000",
   1136        "+001976-10-01T152330.1+0000",
   1137        "+0019761001T15:23:30.1+0000",
   1138        "+0019761001T152330.1+00:00",
   1139        "+0019761001T152330.1+0000",
   1140        "1976-10-01T15:23:00",
   1141        "1976-10-01T15:23",
   1142        "1976-10-01T15",
   1143        "1976-10-01",
   1144        "--10-01",
   1145        "--1001",
   1146        "-999999-10-01",
   1147        "-999999-10-01[u-ca=iso8601]",
   1148        "+999999-10-01",
   1149        "+999999-10-01[u-ca=iso8601]",
   1150      ];
   1151    },
   1152 
   1153    /*
   1154     * PlainTime strings that may be mistaken for PlainMonthDay or
   1155     * PlainYearMonth strings, and so require a time designator.
   1156     */
   1157    plainTimeStringsAmbiguous() {
   1158      const ambiguousStrings = [
   1159        "2021-12",  // ambiguity between YYYY-MM and HHMM-UU
   1160        "2021-12[-12:00]",  // ditto, TZ does not disambiguate
   1161        "1214",     // ambiguity between MMDD and HHMM
   1162        "0229",     //   ditto, including MMDD that doesn't occur every year
   1163        "1130",     //   ditto, including DD that doesn't occur in every month
   1164        "12-14",    // ambiguity between MM-DD and HH-UU
   1165        "12-14[-14:00]",  // ditto, TZ does not disambiguate
   1166        "202112",   // ambiguity between YYYYMM and HHMMSS
   1167        "202112[UTC]",  // ditto, TZ does not disambiguate
   1168      ];
   1169      // Adding a calendar annotation to one of these strings must not cause
   1170      // disambiguation in favour of time.
   1171      const stringsWithCalendar = ambiguousStrings.map((s) => s + "[u-ca=iso8601]");
   1172      return ambiguousStrings.concat(stringsWithCalendar);
   1173    },
   1174 
   1175    /*
   1176     * PlainTime strings that are of similar form to PlainMonthDay and
   1177     * PlainYearMonth strings, but are not ambiguous due to components that
   1178     * aren't valid as months or days.
   1179     */
   1180    plainTimeStringsUnambiguous() {
   1181      return [
   1182        "2021-13",          // 13 is not a month
   1183        "202113",           //   ditto
   1184        "2021-13[-13:00]",  //   ditto
   1185        "202113[-13:00]",   //   ditto
   1186        "0000-00",          // 0 is not a month
   1187        "000000",           //   ditto
   1188        "0000-00[UTC]",     //   ditto
   1189        "000000[UTC]",      //   ditto
   1190        "1314",             // 13 is not a month
   1191        "13-14",            //   ditto
   1192        "1232",             // 32 is not a day
   1193        "0230",             // 30 is not a day in February
   1194        "0631",             // 31 is not a day in June
   1195        "0000",             // 0 is neither a month nor a day
   1196        "00-00",            //   ditto
   1197      ];
   1198    },
   1199 
   1200    /*
   1201     * PlainYearMonth-like strings that are not valid.
   1202     */
   1203    plainYearMonthStringsInvalid() {
   1204      return [
   1205        "2020-13",
   1206        "1976-11[u-ca=gregory]",
   1207        "1976-11[u-ca=hebrew]",
   1208        "1976-11[U-CA=iso8601]",
   1209        "1976-11[u-CA=iso8601]",
   1210        "1976-11[FOO=bar]",
   1211        "+999999-01",
   1212        "-999999-01",
   1213      ];
   1214    },
   1215 
   1216    /*
   1217     * PlainYearMonth-like strings that are valid and should produce November
   1218     * 1976 in the ISO 8601 calendar.
   1219     */
   1220    plainYearMonthStringsValid() {
   1221      return [
   1222        "1976-11",
   1223        "1976-11-10",
   1224        "1976-11-01T09:00:00+00:00",
   1225        "1976-11-01T00:00:00+05:00",
   1226        "197611",
   1227        "+00197611",
   1228        "1976-11-18T15:23:30.1-02:00",
   1229        "1976-11-18T152330.1+00:00",
   1230        "19761118T15:23:30.1+00:00",
   1231        "1976-11-18T15:23:30.1+0000",
   1232        "1976-11-18T152330.1+0000",
   1233        "19761118T15:23:30.1+0000",
   1234        "19761118T152330.1+00:00",
   1235        "19761118T152330.1+0000",
   1236        "+001976-11-18T152330.1+00:00",
   1237        "+0019761118T15:23:30.1+00:00",
   1238        "+001976-11-18T15:23:30.1+0000",
   1239        "+001976-11-18T152330.1+0000",
   1240        "+0019761118T15:23:30.1+0000",
   1241        "+0019761118T152330.1+00:00",
   1242        "+0019761118T152330.1+0000",
   1243        "1976-11-18T15:23",
   1244        "1976-11-18T15",
   1245        "1976-11-18",
   1246      ];
   1247    },
   1248 
   1249    /*
   1250     * PlainYearMonth-like strings that are valid and should produce November of
   1251     * the ISO year -9999.
   1252     */
   1253    plainYearMonthStringsValidNegativeYear() {
   1254      return [
   1255        "-009999-11",
   1256      ];
   1257    },
   1258  }
   1259 };