From 47b9e32dc33662323149b1e083e32f6ed1c3d9d5 Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Thu, 3 Nov 2022 17:53:50 -0700 Subject: [PATCH] Temporal: Add some more order-of-operations tests This adds order-of-operations tests that cover all of the Temporal entry points that accept options bags, that were not already covered. We'll be using these tests in the future to verify https://github.com/tc39/proposal-temporal/issues/2254 However, the tests in this commit reflect the current state of the proposal, not the potential normative change. --- .../prototype/dateAdd/order-of-operations.js | 98 ++++++++++++ .../dateUntil/order-of-operations.js | 84 ++++++++++ .../prototype/toString/order-of-operations.js | 50 ++++++ .../prototype/since/order-of-operations.js | 39 +++++ .../prototype/toString/order-of-operations.js | 59 +++++++ .../prototype/until/order-of-operations.js | 39 +++++ .../prototype/toString/order-of-operations.js | 31 ++++ .../prototype/toString/order-of-operations.js | 61 ++++++++ .../toZonedDateTime/order-of-operations.js | 34 ++++ .../prototype/toString/order-of-operations.js | 31 ++++ .../prototype/since/order-of-operations.js | 70 +++++++++ .../prototype/toString/order-of-operations.js | 50 ++++++ .../prototype/until/order-of-operations.js | 70 +++++++++ .../prototype/toString/order-of-operations.js | 31 ++++ .../getInstantFor/order-of-operations.js | 85 ++++++++++ .../compare/order-of-operations.js | 145 ++++++++++++++++++ .../ZonedDateTime/from/order-of-operations.js | 103 +++++++++++++ .../prototype/add/order-of-operations.js | 80 ++++++++++ .../prototype/equals/order-of-operations.js | 103 +++++++++++++ .../prototype/subtract/order-of-operations.js | 80 ++++++++++ .../prototype/toString/order-of-operations.js | 79 ++++++++++ .../prototype/with/order-of-operations.js | 137 +++++++++++++++++ 22 files changed, 1559 insertions(+) create mode 100644 test/built-ins/Temporal/Calendar/prototype/dateAdd/order-of-operations.js create mode 100644 test/built-ins/Temporal/Calendar/prototype/dateUntil/order-of-operations.js create mode 100644 test/built-ins/Temporal/Duration/prototype/toString/order-of-operations.js create mode 100644 test/built-ins/Temporal/Instant/prototype/since/order-of-operations.js create mode 100644 test/built-ins/Temporal/Instant/prototype/toString/order-of-operations.js create mode 100644 test/built-ins/Temporal/Instant/prototype/until/order-of-operations.js create mode 100644 test/built-ins/Temporal/PlainDate/prototype/toString/order-of-operations.js create mode 100644 test/built-ins/Temporal/PlainDateTime/prototype/toString/order-of-operations.js create mode 100644 test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/order-of-operations.js create mode 100644 test/built-ins/Temporal/PlainMonthDay/prototype/toString/order-of-operations.js create mode 100644 test/built-ins/Temporal/PlainTime/prototype/since/order-of-operations.js create mode 100644 test/built-ins/Temporal/PlainTime/prototype/toString/order-of-operations.js create mode 100644 test/built-ins/Temporal/PlainTime/prototype/until/order-of-operations.js create mode 100644 test/built-ins/Temporal/PlainYearMonth/prototype/toString/order-of-operations.js create mode 100644 test/built-ins/Temporal/TimeZone/prototype/getInstantFor/order-of-operations.js create mode 100644 test/built-ins/Temporal/ZonedDateTime/compare/order-of-operations.js create mode 100644 test/built-ins/Temporal/ZonedDateTime/from/order-of-operations.js create mode 100644 test/built-ins/Temporal/ZonedDateTime/prototype/add/order-of-operations.js create mode 100644 test/built-ins/Temporal/ZonedDateTime/prototype/equals/order-of-operations.js create mode 100644 test/built-ins/Temporal/ZonedDateTime/prototype/subtract/order-of-operations.js create mode 100644 test/built-ins/Temporal/ZonedDateTime/prototype/toString/order-of-operations.js create mode 100644 test/built-ins/Temporal/ZonedDateTime/prototype/with/order-of-operations.js diff --git a/test/built-ins/Temporal/Calendar/prototype/dateAdd/order-of-operations.js b/test/built-ins/Temporal/Calendar/prototype/dateAdd/order-of-operations.js new file mode 100644 index 0000000000..fccca03bef --- /dev/null +++ b/test/built-ins/Temporal/Calendar/prototype/dateAdd/order-of-operations.js @@ -0,0 +1,98 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dateadd +description: Properties on an object passed to dateAdd() are accessed in the correct order +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + // ToTemporalDate → GetTemporalCalendarWithISODefault + "get date.calendar", + "has date.calendar.calendar", + // ToTemporalDate → CalendarFields + "get date.calendar.fields", + "call date.calendar.fields", + // ToTemporalDate → PrepareTemporalFields + "get date.day", + "get date.day.valueOf", + "call date.day.valueOf", + "get date.month", + "get date.month.valueOf", + "call date.month.valueOf", + "get date.monthCode", + "get date.monthCode.toString", + "call date.monthCode.toString", + "get date.year", + "get date.year.valueOf", + "call date.year.valueOf", + // ToTemporalDate → CalendarDateFromFields + "get date.calendar.dateFromFields", + "call date.calendar.dateFromFields", + // ToTemporalDuration + "get duration.days", + "get duration.days.valueOf", + "call duration.days.valueOf", + "get duration.hours", + "get duration.hours.valueOf", + "call duration.hours.valueOf", + "get duration.microseconds", + "get duration.microseconds.valueOf", + "call duration.microseconds.valueOf", + "get duration.milliseconds", + "get duration.milliseconds.valueOf", + "call duration.milliseconds.valueOf", + "get duration.minutes", + "get duration.minutes.valueOf", + "call duration.minutes.valueOf", + "get duration.months", + "get duration.months.valueOf", + "call duration.months.valueOf", + "get duration.nanoseconds", + "get duration.nanoseconds.valueOf", + "call duration.nanoseconds.valueOf", + "get duration.seconds", + "get duration.seconds.valueOf", + "call duration.seconds.valueOf", + "get duration.weeks", + "get duration.weeks.valueOf", + "call duration.weeks.valueOf", + "get duration.years", + "get duration.years.valueOf", + "call duration.years.valueOf", + // ToTemporalOverflow + "get options.overflow", + "get options.overflow.toString", + "call options.overflow.toString", +]; +const actual = []; + +const instance = new Temporal.Calendar("iso8601"); + +const date = TemporalHelpers.propertyBagObserver(actual, { + year: 2000, + month: 5, + monthCode: "M05", + day: 2, + calendar: TemporalHelpers.calendarObserver(actual, "date.calendar"), +}, "date"); + +const duration = TemporalHelpers.propertyBagObserver(actual, { + years: 1, + months: 2, + weeks: 3, + days: 4, + hours: 5, + minutes: 6, + seconds: 7, + milliseconds: 8, + microseconds: 9, + nanoseconds: 10, +}, "duration"); + +const options = TemporalHelpers.propertyBagObserver(actual, { overflow: "constrain" }, "options"); + +instance.dateAdd(date, duration, options); +assert.compareArray(actual, expected, "order of operations"); diff --git a/test/built-ins/Temporal/Calendar/prototype/dateUntil/order-of-operations.js b/test/built-ins/Temporal/Calendar/prototype/dateUntil/order-of-operations.js new file mode 100644 index 0000000000..b15bf8bc36 --- /dev/null +++ b/test/built-ins/Temporal/Calendar/prototype/dateUntil/order-of-operations.js @@ -0,0 +1,84 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dateuntil +description: Properties on an object passed to dateUntil() are accessed in the correct order +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + // ToTemporalDate 1 → GetTemporalCalendarWithISODefault + "get one.calendar", + "has one.calendar.calendar", + // ToTemporalDate 1 → CalendarFields + "get one.calendar.fields", + "call one.calendar.fields", + // ToTemporalDate 1 → PrepareTemporalFields + "get one.day", + "get one.day.valueOf", + "call one.day.valueOf", + "get one.month", + "get one.month.valueOf", + "call one.month.valueOf", + "get one.monthCode", + "get one.monthCode.toString", + "call one.monthCode.toString", + "get one.year", + "get one.year.valueOf", + "call one.year.valueOf", + // ToTemporalDate 1 → CalendarDateFromFields + "get one.calendar.dateFromFields", + "call one.calendar.dateFromFields", + // ToTemporalDate 2 → GetTemporalCalendarWithISODefault + "get two.calendar", + "has two.calendar.calendar", + // ToTemporalDate 2 → CalendarFields + "get two.calendar.fields", + "call two.calendar.fields", + // ToTemporalDate 2 → PrepareTemporalFields + "get two.day", + "get two.day.valueOf", + "call two.day.valueOf", + "get two.month", + "get two.month.valueOf", + "call two.month.valueOf", + "get two.monthCode", + "get two.monthCode.toString", + "call two.monthCode.toString", + "get two.year", + "get two.year.valueOf", + "call two.year.valueOf", + // ToTemporalDate 2 → CalendarDateFromFields + "get two.calendar.dateFromFields", + "call two.calendar.dateFromFields", + // GetTemporalUnit + "get options.largestUnit", + "get options.largestUnit.toString", + "call options.largestUnit.toString", +]; +const actual = []; + +const instance = new Temporal.Calendar("iso8601"); + +const one = TemporalHelpers.propertyBagObserver(actual, { + year: 2000, + month: 5, + monthCode: "M05", + day: 2, + calendar: TemporalHelpers.calendarObserver(actual, "one.calendar"), +}, "one"); + +const two = TemporalHelpers.propertyBagObserver(actual, { + year: 2001, + month: 10, + monthCode: "M10", + day: 4, + calendar: TemporalHelpers.calendarObserver(actual, "two.calendar"), +}, "two"); + +const options = TemporalHelpers.propertyBagObserver(actual, { largestUnit: "day" }, "options"); + +instance.dateUntil(one, two, options); +assert.compareArray(actual, expected, "order of operations"); diff --git a/test/built-ins/Temporal/Duration/prototype/toString/order-of-operations.js b/test/built-ins/Temporal/Duration/prototype/toString/order-of-operations.js new file mode 100644 index 0000000000..d4a6613a19 --- /dev/null +++ b/test/built-ins/Temporal/Duration/prototype/toString/order-of-operations.js @@ -0,0 +1,50 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.tostring +description: Properties on objects passed to toString() are accessed in the correct order +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + "get options.smallestUnit", + "get options.smallestUnit.toString", + "call options.smallestUnit.toString", + "get options.roundingMode", + "get options.roundingMode.toString", + "call options.roundingMode.toString", +]; +const actual = []; + +const instance = new Temporal.Duration(1, 1, 1, 1, 1, 1, 1, 1, 1, 1); + +instance.toString( + TemporalHelpers.propertyBagObserver(actual, { + fractionalSecondDigits: 3, + roundingMode: "halfExpand", + smallestUnit: "millisecond", + }, "options"), +); +assert.compareArray(actual, expected, "order of operations"); +actual.splice(0); // clear + +const expectedForFractionalSecondDigits = [ + "get options.smallestUnit", + "get options.fractionalSecondDigits", + "get options.fractionalSecondDigits.toString", + "call options.fractionalSecondDigits.toString", + "get options.roundingMode", + "get options.roundingMode.toString", + "call options.roundingMode.toString", +]; + +instance.toString( + TemporalHelpers.propertyBagObserver(actual, { + fractionalSecondDigits: "auto", + roundingMode: "halfExpand", + smallestUnit: undefined, + }, "options"), +); +assert.compareArray(actual, expectedForFractionalSecondDigits, "order of operations with smallestUnit undefined"); diff --git a/test/built-ins/Temporal/Instant/prototype/since/order-of-operations.js b/test/built-ins/Temporal/Instant/prototype/since/order-of-operations.js new file mode 100644 index 0000000000..f23d54ebcc --- /dev/null +++ b/test/built-ins/Temporal/Instant/prototype/since/order-of-operations.js @@ -0,0 +1,39 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.since +description: Properties on objects passed to since() are accessed in the correct order +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + "get other.toString", + "call other.toString", + "get options.smallestUnit", + "get options.smallestUnit.toString", + "call options.smallestUnit.toString", + "get options.largestUnit", + "get options.largestUnit.toString", + "call options.largestUnit.toString", + "get options.roundingMode", + "get options.roundingMode.toString", + "call options.roundingMode.toString", + "get options.roundingIncrement", + "get options.roundingIncrement.valueOf", + "call options.roundingIncrement.valueOf", +]; +const actual = []; + +const instance = new Temporal.Instant(1_000_000_000_000_000_000n); +instance.since( + TemporalHelpers.toPrimitiveObserver(actual, "1970-01-01T00:00Z", "other"), + TemporalHelpers.propertyBagObserver(actual, { + largestUnit: "hours", + roundingIncrement: 1, + roundingMode: "halfExpand", + smallestUnit: "minutes", + }, "options"), +); +assert.compareArray(actual, expected, "order of operations"); diff --git a/test/built-ins/Temporal/Instant/prototype/toString/order-of-operations.js b/test/built-ins/Temporal/Instant/prototype/toString/order-of-operations.js new file mode 100644 index 0000000000..3058d55baf --- /dev/null +++ b/test/built-ins/Temporal/Instant/prototype/toString/order-of-operations.js @@ -0,0 +1,59 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.tostring +description: Properties on objects passed to toString() are accessed in the correct order +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + "get options.timeZone", + "has options.timeZone.timeZone", + "get options.smallestUnit", + "get options.smallestUnit.toString", + "call options.smallestUnit.toString", + "get options.roundingMode", + "get options.roundingMode.toString", + "call options.roundingMode.toString", + "get options.timeZone.getOffsetNanosecondsFor", + "call options.timeZone.getOffsetNanosecondsFor", + "get options.timeZone.getOffsetNanosecondsFor", + "call options.timeZone.getOffsetNanosecondsFor", +]; +const actual = []; + +const instance = new Temporal.Instant(0n); + +instance.toString( + TemporalHelpers.propertyBagObserver(actual, { + fractionalSecondDigits: 3, + roundingMode: "halfExpand", + smallestUnit: "millisecond", + timeZone: TemporalHelpers.timeZoneObserver(actual, "options.timeZone"), + }, "options"), +); +assert.compareArray(actual, expected, "order of operations"); +actual.splice(0); // clear + +const expectedForFractionalSecondDigits = [ + "get options.timeZone", + "get options.smallestUnit", + "get options.fractionalSecondDigits", + "get options.fractionalSecondDigits.toString", + "call options.fractionalSecondDigits.toString", + "get options.roundingMode", + "get options.roundingMode.toString", + "call options.roundingMode.toString", +]; + +instance.toString( + TemporalHelpers.propertyBagObserver(actual, { + fractionalSecondDigits: "auto", + roundingMode: "halfExpand", + smallestUnit: undefined, + timeZone: undefined, + }, "options"), +); +assert.compareArray(actual, expectedForFractionalSecondDigits, "order of operations with smallestUnit undefined"); diff --git a/test/built-ins/Temporal/Instant/prototype/until/order-of-operations.js b/test/built-ins/Temporal/Instant/prototype/until/order-of-operations.js new file mode 100644 index 0000000000..1529933a8b --- /dev/null +++ b/test/built-ins/Temporal/Instant/prototype/until/order-of-operations.js @@ -0,0 +1,39 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.until +description: Properties on objects passed to until() are accessed in the correct order +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + "get other.toString", + "call other.toString", + "get options.smallestUnit", + "get options.smallestUnit.toString", + "call options.smallestUnit.toString", + "get options.largestUnit", + "get options.largestUnit.toString", + "call options.largestUnit.toString", + "get options.roundingMode", + "get options.roundingMode.toString", + "call options.roundingMode.toString", + "get options.roundingIncrement", + "get options.roundingIncrement.valueOf", + "call options.roundingIncrement.valueOf", +]; +const actual = []; + +const instance = new Temporal.Instant(0n); +instance.until( + TemporalHelpers.toPrimitiveObserver(actual, "2001-09-09T01:46:40Z", "other"), + TemporalHelpers.propertyBagObserver(actual, { + largestUnit: "hours", + roundingIncrement: 1, + roundingMode: "halfExpand", + smallestUnit: "minutes", + }, "options"), +); +assert.compareArray(actual, expected, "order of operations"); diff --git a/test/built-ins/Temporal/PlainDate/prototype/toString/order-of-operations.js b/test/built-ins/Temporal/PlainDate/prototype/toString/order-of-operations.js new file mode 100644 index 0000000000..fa627943c1 --- /dev/null +++ b/test/built-ins/Temporal/PlainDate/prototype/toString/order-of-operations.js @@ -0,0 +1,31 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.tostring +description: Properties on an object passed to toString() are accessed in the correct order +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + "get options.calendarName", + "get options.calendarName.toString", + "call options.calendarName.toString", + "get this.calendar[Symbol.toPrimitive]", + "get this.calendar.toString", + "call this.calendar.toString", +]; +const actual = []; + +const calendar = TemporalHelpers.calendarObserver(actual, "this.calendar"); +const instance = new Temporal.PlainDate(2000, 5, 2, calendar); +// clear observable operations that occurred during the constructor call +actual.splice(0); + +const options = TemporalHelpers.propertyBagObserver(actual, { + calendarName: "auto", +}, "options"); + +instance.toString(options); +assert.compareArray(actual, expected, "order of operations"); diff --git a/test/built-ins/Temporal/PlainDateTime/prototype/toString/order-of-operations.js b/test/built-ins/Temporal/PlainDateTime/prototype/toString/order-of-operations.js new file mode 100644 index 0000000000..68fd6a5684 --- /dev/null +++ b/test/built-ins/Temporal/PlainDateTime/prototype/toString/order-of-operations.js @@ -0,0 +1,61 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.tostring +description: Properties on objects passed to toString() are accessed in the correct order +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + "get options.roundingMode", + "get options.roundingMode.toString", + "call options.roundingMode.toString", + "get options.calendarName", + "get options.calendarName.toString", + "call options.calendarName.toString", + "get this.calendar[Symbol.toPrimitive]", + "get this.calendar.toString", + "call this.calendar.toString", +]; +const actual = []; + +const calendar = TemporalHelpers.calendarObserver(actual, "this.calendar"); +const instance = new Temporal.PlainDateTime(1990, 11, 3, 15, 54, 37, 123, 456, 789, calendar); +// clear observable operations that occurred during the constructor call +actual.splice(0); + +const expectedForSmallestUnit = [ + "get options.smallestUnit", + "get options.smallestUnit.toString", + "call options.smallestUnit.toString", +].concat(expected); + +instance.toString( + TemporalHelpers.propertyBagObserver(actual, { + fractionalSecondDigits: 3, + roundingMode: "halfExpand", + smallestUnit: "millisecond", + calendarName: "auto", + }, "options"), +); +assert.compareArray(actual, expectedForSmallestUnit, "order of operations"); +actual.splice(0); // clear + +const expectedForFractionalSecondDigits = [ + "get options.smallestUnit", + "get options.fractionalSecondDigits", + "get options.fractionalSecondDigits.toString", + "call options.fractionalSecondDigits.toString", +].concat(expected); + +instance.toString( + TemporalHelpers.propertyBagObserver(actual, { + fractionalSecondDigits: "auto", + roundingMode: "halfExpand", + smallestUnit: undefined, + calendarName: "auto", + }, "options"), +); +assert.compareArray(actual, expectedForFractionalSecondDigits, "order of operations with smallestUnit undefined"); diff --git a/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/order-of-operations.js b/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/order-of-operations.js new file mode 100644 index 0000000000..166c4e377d --- /dev/null +++ b/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/order-of-operations.js @@ -0,0 +1,34 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.tozoneddatetime +description: Properties on an object passed to toZonedDateTime() are accessed in the correct order +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + // ToTemporalTimeZone + "has timeZone.timeZone", + // ToTemporalDisambiguation + "get options.disambiguation", + "get options.disambiguation.toString", + "call options.disambiguation.toString", + // BuiltinTimeZoneGetInstantFor + "get timeZone.getPossibleInstantsFor", + "call timeZone.getPossibleInstantsFor", +]; +const actual = []; + +const calendar = TemporalHelpers.calendarObserver(actual, "this.calendar"); +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, calendar); +// clear observable operations that occurred during the constructor call +actual.splice(0); + +const timeZone = TemporalHelpers.timeZoneObserver(actual, "timeZone"); + +const options = TemporalHelpers.propertyBagObserver(actual, { disambiguation: "compatible" }, "options"); + +instance.toZonedDateTime(timeZone, options); +assert.compareArray(actual, expected, "order of operations"); diff --git a/test/built-ins/Temporal/PlainMonthDay/prototype/toString/order-of-operations.js b/test/built-ins/Temporal/PlainMonthDay/prototype/toString/order-of-operations.js new file mode 100644 index 0000000000..be16b543ed --- /dev/null +++ b/test/built-ins/Temporal/PlainMonthDay/prototype/toString/order-of-operations.js @@ -0,0 +1,31 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday.prototype.tostring +description: Properties on an object passed to toString() are accessed in the correct order +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + "get options.calendarName", + "get options.calendarName.toString", + "call options.calendarName.toString", + "get this.calendar[Symbol.toPrimitive]", + "get this.calendar.toString", + "call this.calendar.toString", +]; +const actual = []; + +const calendar = TemporalHelpers.calendarObserver(actual, "this.calendar"); +const instance = new Temporal.PlainMonthDay(5, 2, calendar); +// clear observable operations that occurred during the constructor call +actual.splice(0); + +const options = TemporalHelpers.propertyBagObserver(actual, { + calendarName: "auto", +}, "options"); + +instance.toString(options); +assert.compareArray(actual, expected, "order of operations"); diff --git a/test/built-ins/Temporal/PlainTime/prototype/since/order-of-operations.js b/test/built-ins/Temporal/PlainTime/prototype/since/order-of-operations.js new file mode 100644 index 0000000000..66b0ac28f0 --- /dev/null +++ b/test/built-ins/Temporal/PlainTime/prototype/since/order-of-operations.js @@ -0,0 +1,70 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.since +description: Properties on an object passed to since() are accessed in the correct order +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + // ToTemporalTime + "get other.calendar", + "get other.calendar.toString", + "call other.calendar.toString", + "get other.hour", + "get other.hour.valueOf", + "call other.hour.valueOf", + "get other.microsecond", + "get other.microsecond.valueOf", + "call other.microsecond.valueOf", + "get other.millisecond", + "get other.millisecond.valueOf", + "call other.millisecond.valueOf", + "get other.minute", + "get other.minute.valueOf", + "call other.minute.valueOf", + "get other.nanosecond", + "get other.nanosecond.valueOf", + "call other.nanosecond.valueOf", + "get other.second", + "get other.second.valueOf", + "call other.second.valueOf", + // GetDifferenceSettings + "get options.smallestUnit", + "get options.smallestUnit.toString", + "call options.smallestUnit.toString", + "get options.largestUnit", + "get options.largestUnit.toString", + "call options.largestUnit.toString", + "get options.roundingMode", + "get options.roundingMode.toString", + "call options.roundingMode.toString", + "get options.roundingIncrement", + "get options.roundingIncrement.valueOf", + "call options.roundingIncrement.valueOf", +]; +const actual = []; + +const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); + +const other = TemporalHelpers.propertyBagObserver(actual, { + hour: 1.7, + minute: 1.7, + second: 1.7, + millisecond: 1.7, + microsecond: 1.7, + nanosecond: 1.7, + calendar: "iso8601", +}, "other"); + +const options = TemporalHelpers.propertyBagObserver(actual, { + smallestUnit: "nanoseconds", + largestUnit: "hours", + roundingMode: "trunc", + roundingIncrement: 1, +}, "options"); + +const result = instance.since(other, options); +assert.compareArray(actual, expected, "order of operations"); diff --git a/test/built-ins/Temporal/PlainTime/prototype/toString/order-of-operations.js b/test/built-ins/Temporal/PlainTime/prototype/toString/order-of-operations.js new file mode 100644 index 0000000000..d3f599fcff --- /dev/null +++ b/test/built-ins/Temporal/PlainTime/prototype/toString/order-of-operations.js @@ -0,0 +1,50 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.tostring +description: Properties on objects passed to toString() are accessed in the correct order +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + "get options.smallestUnit", + "get options.smallestUnit.toString", + "call options.smallestUnit.toString", + "get options.roundingMode", + "get options.roundingMode.toString", + "call options.roundingMode.toString", +]; +const actual = []; + +const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); + +instance.toString( + TemporalHelpers.propertyBagObserver(actual, { + fractionalSecondDigits: 3, + roundingMode: "halfExpand", + smallestUnit: "millisecond", + }, "options"), +); +assert.compareArray(actual, expected, "order of operations"); +actual.splice(0); // clear + +const expectedForFractionalSecondDigits = [ + "get options.smallestUnit", + "get options.fractionalSecondDigits", + "get options.fractionalSecondDigits.toString", + "call options.fractionalSecondDigits.toString", + "get options.roundingMode", + "get options.roundingMode.toString", + "call options.roundingMode.toString", +]; + +instance.toString( + TemporalHelpers.propertyBagObserver(actual, { + fractionalSecondDigits: "auto", + roundingMode: "halfExpand", + smallestUnit: undefined, + }, "options"), +); +assert.compareArray(actual, expectedForFractionalSecondDigits, "order of operations with smallestUnit undefined"); diff --git a/test/built-ins/Temporal/PlainTime/prototype/until/order-of-operations.js b/test/built-ins/Temporal/PlainTime/prototype/until/order-of-operations.js new file mode 100644 index 0000000000..37ff6793b3 --- /dev/null +++ b/test/built-ins/Temporal/PlainTime/prototype/until/order-of-operations.js @@ -0,0 +1,70 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.until +description: Properties on an object passed to until() are accessed in the correct order +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + // ToTemporalTime + "get other.calendar", + "get other.calendar.toString", + "call other.calendar.toString", + "get other.hour", + "get other.hour.valueOf", + "call other.hour.valueOf", + "get other.microsecond", + "get other.microsecond.valueOf", + "call other.microsecond.valueOf", + "get other.millisecond", + "get other.millisecond.valueOf", + "call other.millisecond.valueOf", + "get other.minute", + "get other.minute.valueOf", + "call other.minute.valueOf", + "get other.nanosecond", + "get other.nanosecond.valueOf", + "call other.nanosecond.valueOf", + "get other.second", + "get other.second.valueOf", + "call other.second.valueOf", + // GetDifferenceSettings + "get options.smallestUnit", + "get options.smallestUnit.toString", + "call options.smallestUnit.toString", + "get options.largestUnit", + "get options.largestUnit.toString", + "call options.largestUnit.toString", + "get options.roundingMode", + "get options.roundingMode.toString", + "call options.roundingMode.toString", + "get options.roundingIncrement", + "get options.roundingIncrement.valueOf", + "call options.roundingIncrement.valueOf", +]; +const actual = []; + +const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); + +const other = TemporalHelpers.propertyBagObserver(actual, { + hour: 1.7, + minute: 1.7, + second: 1.7, + millisecond: 1.7, + microsecond: 1.7, + nanosecond: 1.7, + calendar: "iso8601", +}, "other"); + +const options = TemporalHelpers.propertyBagObserver(actual, { + smallestUnit: "nanoseconds", + largestUnit: "hours", + roundingMode: "trunc", + roundingIncrement: 1, +}, "options"); + +const result = instance.until(other, options); +assert.compareArray(actual, expected, "order of operations"); diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/toString/order-of-operations.js b/test/built-ins/Temporal/PlainYearMonth/prototype/toString/order-of-operations.js new file mode 100644 index 0000000000..902d57fd5b --- /dev/null +++ b/test/built-ins/Temporal/PlainYearMonth/prototype/toString/order-of-operations.js @@ -0,0 +1,31 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.tostring +description: Properties on an object passed to toString() are accessed in the correct order +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + "get options.calendarName", + "get options.calendarName.toString", + "call options.calendarName.toString", + "get this.calendar[Symbol.toPrimitive]", + "get this.calendar.toString", + "call this.calendar.toString", +]; +const actual = []; + +const calendar = TemporalHelpers.calendarObserver(actual, "this.calendar"); +const instance = new Temporal.PlainYearMonth(2000, 5, calendar); +// clear observable operations that occurred during the constructor call +actual.splice(0); + +const options = TemporalHelpers.propertyBagObserver(actual, { + calendarName: "auto", +}, "options"); + +instance.toString(options); +assert.compareArray(actual, expected, "order of operations"); diff --git a/test/built-ins/Temporal/TimeZone/prototype/getInstantFor/order-of-operations.js b/test/built-ins/Temporal/TimeZone/prototype/getInstantFor/order-of-operations.js new file mode 100644 index 0000000000..a4318a880f --- /dev/null +++ b/test/built-ins/Temporal/TimeZone/prototype/getInstantFor/order-of-operations.js @@ -0,0 +1,85 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: Properties on an object passed to getInstantFor() are accessed in the correct order +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + // GetTemporalCalendarWithISODefault + "get fields.calendar", + "has fields.calendar.calendar", + // CalendarFields + "get fields.calendar.fields", + "call fields.calendar.fields", + // PrepareTemporalFields + "get fields.day", + "get fields.day.valueOf", + "call fields.day.valueOf", + "get fields.hour", + "get fields.hour.valueOf", + "call fields.hour.valueOf", + "get fields.microsecond", + "get fields.microsecond.valueOf", + "call fields.microsecond.valueOf", + "get fields.millisecond", + "get fields.millisecond.valueOf", + "call fields.millisecond.valueOf", + "get fields.minute", + "get fields.minute.valueOf", + "call fields.minute.valueOf", + "get fields.month", + "get fields.month.valueOf", + "call fields.month.valueOf", + "get fields.monthCode", + "get fields.monthCode.toString", + "call fields.monthCode.toString", + "get fields.nanosecond", + "get fields.nanosecond.valueOf", + "call fields.nanosecond.valueOf", + "get fields.second", + "get fields.second.valueOf", + "call fields.second.valueOf", + "get fields.year", + "get fields.year.valueOf", + "call fields.year.valueOf", + // InterpretTemporalDateTimeFields + "get fields.calendar.dateFromFields", + "call fields.calendar.dateFromFields", + // ToTemporalDisambiguation + "get options.disambiguation", + "get options.disambiguation.toString", + "call options.disambiguation.toString", + // BuiltinTimeZoneGetInstantFor + "get this.getPossibleInstantsFor", + "call this.getPossibleInstantsFor", +]; +const actual = []; + +const instance = new Temporal.TimeZone("UTC"); +TemporalHelpers.observeProperty(actual, instance, "getPossibleInstantsFor", function getPossibleInstantsFor(...args) { + actual.push("call this.getPossibleInstantsFor"); + return Temporal.TimeZone.prototype.getPossibleInstantsFor.apply(instance, args); +}, "this"); + +const fields = TemporalHelpers.propertyBagObserver(actual, { + year: 2000, + month: 5, + monthCode: "M05", + day: 2, + hour: 12, + minute: 34, + second: 56, + millisecond: 987, + microsecond: 654, + nanosecond: 321, + calendar: TemporalHelpers.calendarObserver(actual, "fields.calendar"), +}, "fields"); + +const options = TemporalHelpers.propertyBagObserver(actual, { disambiguation: "compatible" }, "options"); + +instance.getInstantFor(fields, options); +assert.compareArray(actual, expected, "order of operations"); diff --git a/test/built-ins/Temporal/ZonedDateTime/compare/order-of-operations.js b/test/built-ins/Temporal/ZonedDateTime/compare/order-of-operations.js new file mode 100644 index 0000000000..aa02e88168 --- /dev/null +++ b/test/built-ins/Temporal/ZonedDateTime/compare/order-of-operations.js @@ -0,0 +1,145 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.compare +description: Properties on objects passed to compare() are accessed in the correct order +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + "get one.calendar", + "has one.calendar.calendar", + "get one.calendar.fields", + "call one.calendar.fields", + // PrepareTemporalFields + "get one.day", + "get one.day.valueOf", + "call one.day.valueOf", + "get one.hour", + "get one.hour.valueOf", + "call one.hour.valueOf", + "get one.microsecond", + "get one.microsecond.valueOf", + "call one.microsecond.valueOf", + "get one.millisecond", + "get one.millisecond.valueOf", + "call one.millisecond.valueOf", + "get one.minute", + "get one.minute.valueOf", + "call one.minute.valueOf", + "get one.month", + "get one.month.valueOf", + "call one.month.valueOf", + "get one.monthCode", + "get one.monthCode.toString", + "call one.monthCode.toString", + "get one.nanosecond", + "get one.nanosecond.valueOf", + "call one.nanosecond.valueOf", + "get one.second", + "get one.second.valueOf", + "call one.second.valueOf", + "get one.year", + "get one.year.valueOf", + "call one.year.valueOf", + "get one.timeZone", + "get one.offset", + "get one.offset.toString", + "call one.offset.toString", + "has one.timeZone.timeZone", + // InterpretTemporalDateTimeFields + "get one.calendar.dateFromFields", + "call one.calendar.dateFromFields", + // InterpretISODateTimeOffset + "get one.timeZone.getPossibleInstantsFor", + "call one.timeZone.getPossibleInstantsFor", + "get one.timeZone.getOffsetNanosecondsFor", + "call one.timeZone.getOffsetNanosecondsFor", + // Same set of operations, for the other argument: + "get two.calendar", + "has two.calendar.calendar", + "get two.calendar.fields", + "call two.calendar.fields", + // PrepareTemporalFields + "get two.day", + "get two.day.valueOf", + "call two.day.valueOf", + "get two.hour", + "get two.hour.valueOf", + "call two.hour.valueOf", + "get two.microsecond", + "get two.microsecond.valueOf", + "call two.microsecond.valueOf", + "get two.millisecond", + "get two.millisecond.valueOf", + "call two.millisecond.valueOf", + "get two.minute", + "get two.minute.valueOf", + "call two.minute.valueOf", + "get two.month", + "get two.month.valueOf", + "call two.month.valueOf", + "get two.monthCode", + "get two.monthCode.toString", + "call two.monthCode.toString", + "get two.nanosecond", + "get two.nanosecond.valueOf", + "call two.nanosecond.valueOf", + "get two.second", + "get two.second.valueOf", + "call two.second.valueOf", + "get two.year", + "get two.year.valueOf", + "call two.year.valueOf", + "get two.timeZone", + "get two.offset", + "get two.offset.toString", + "call two.offset.toString", + "has two.timeZone.timeZone", + // InterpretTemporalDateTimeFields + "get two.calendar.dateFromFields", + "call two.calendar.dateFromFields", + // InterpretISODateTimeOffset + "get two.timeZone.getPossibleInstantsFor", + "call two.timeZone.getPossibleInstantsFor", + "get two.timeZone.getOffsetNanosecondsFor", + "call two.timeZone.getOffsetNanosecondsFor", +]; +const actual = []; + +const one = TemporalHelpers.propertyBagObserver(actual, { + year: 2001, + month: 5, + monthCode: "M05", + day: 2, + hour: 6, + minute: 54, + second: 32, + millisecond: 987, + microsecond: 654, + nanosecond: 321, + offset: "+00:00", + calendar: TemporalHelpers.calendarObserver(actual, "one.calendar"), + timeZone: TemporalHelpers.timeZoneObserver(actual, "one.timeZone"), +}, "one"); + +const two = TemporalHelpers.propertyBagObserver(actual, { + year: 2014, + month: 7, + monthCode: "M07", + day: 19, + hour: 12, + minute: 34, + second: 56, + millisecond: 123, + microsecond: 456, + nanosecond: 789, + offset: "+00:00", + calendar: TemporalHelpers.calendarObserver(actual, "two.calendar"), + timeZone: TemporalHelpers.timeZoneObserver(actual, "two.timeZone"), +}, "two"); + +Temporal.ZonedDateTime.compare(one, two); +assert.compareArray(actual, expected, "order of operations"); diff --git a/test/built-ins/Temporal/ZonedDateTime/from/order-of-operations.js b/test/built-ins/Temporal/ZonedDateTime/from/order-of-operations.js new file mode 100644 index 0000000000..c32f5be23a --- /dev/null +++ b/test/built-ins/Temporal/ZonedDateTime/from/order-of-operations.js @@ -0,0 +1,103 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.from +description: Properties on objects passed to from() are accessed in the correct order +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + "get item.calendar", + "has item.calendar.calendar", + "get item.calendar.fields", + "call item.calendar.fields", + // PrepareTemporalFields + "get item.day", + "get item.day.valueOf", + "call item.day.valueOf", + "get item.hour", + "get item.hour.valueOf", + "call item.hour.valueOf", + "get item.microsecond", + "get item.microsecond.valueOf", + "call item.microsecond.valueOf", + "get item.millisecond", + "get item.millisecond.valueOf", + "call item.millisecond.valueOf", + "get item.minute", + "get item.minute.valueOf", + "call item.minute.valueOf", + "get item.month", + "get item.month.valueOf", + "call item.month.valueOf", + "get item.monthCode", + "get item.monthCode.toString", + "call item.monthCode.toString", + "get item.nanosecond", + "get item.nanosecond.valueOf", + "call item.nanosecond.valueOf", + "get item.second", + "get item.second.valueOf", + "call item.second.valueOf", + "get item.year", + "get item.year.valueOf", + "call item.year.valueOf", + "get item.timeZone", + "get item.offset", + "get item.offset.toString", + "call item.offset.toString", + "has item.timeZone.timeZone", + // InterpretTemporalDateTimeFields + "get options.overflow", + "get options.overflow.toString", + "call options.overflow.toString", + "get item.calendar.dateFromFields", + "call item.calendar.dateFromFields", + // inside calendar.dateFromFields + "get options.overflow", + "get options.overflow.toString", + "call options.overflow.toString", + // ToTemporalDisambiguation + "get options.disambiguation", + "get options.disambiguation.toString", + "call options.disambiguation.toString", + // ToTemporalOffset + "get options.offset", + "get options.offset.toString", + "call options.offset.toString", + // InterpretISODateTimeOffset + "get item.timeZone.getPossibleInstantsFor", + "call item.timeZone.getPossibleInstantsFor", + "get item.timeZone.getOffsetNanosecondsFor", + "call item.timeZone.getOffsetNanosecondsFor", +]; +const actual = []; + +const from = TemporalHelpers.propertyBagObserver(actual, { + year: 2001, + month: 5, + monthCode: "M05", + day: 2, + hour: 6, + minute: 54, + second: 32, + millisecond: 987, + microsecond: 654, + nanosecond: 321, + offset: "+00:00", + calendar: TemporalHelpers.calendarObserver(actual, "item.calendar"), + timeZone: TemporalHelpers.timeZoneObserver(actual, "item.timeZone"), +}, "item"); + +function createOptionsObserver({ overflow = "constrain", disambiguation = "compatible", offset = "reject" } = {}) { + return TemporalHelpers.propertyBagObserver(actual, { + overflow, + disambiguation, + offset, + }, "options"); +} + +Temporal.ZonedDateTime.from(from, createOptionsObserver()); +assert.compareArray(actual, expected, "order of operations"); diff --git a/test/built-ins/Temporal/ZonedDateTime/prototype/add/order-of-operations.js b/test/built-ins/Temporal/ZonedDateTime/prototype/add/order-of-operations.js new file mode 100644 index 0000000000..edafee0ec3 --- /dev/null +++ b/test/built-ins/Temporal/ZonedDateTime/prototype/add/order-of-operations.js @@ -0,0 +1,80 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.add +description: Properties on objects passed to add() are accessed in the correct order +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + // ToTemporalDurationRecord + "get duration.days", + "get duration.days.valueOf", + "call duration.days.valueOf", + "get duration.hours", + "get duration.hours.valueOf", + "call duration.hours.valueOf", + "get duration.microseconds", + "get duration.microseconds.valueOf", + "call duration.microseconds.valueOf", + "get duration.milliseconds", + "get duration.milliseconds.valueOf", + "call duration.milliseconds.valueOf", + "get duration.minutes", + "get duration.minutes.valueOf", + "call duration.minutes.valueOf", + "get duration.months", + "get duration.months.valueOf", + "call duration.months.valueOf", + "get duration.nanoseconds", + "get duration.nanoseconds.valueOf", + "call duration.nanoseconds.valueOf", + "get duration.seconds", + "get duration.seconds.valueOf", + "call duration.seconds.valueOf", + "get duration.weeks", + "get duration.weeks.valueOf", + "call duration.weeks.valueOf", + "get duration.years", + "get duration.years.valueOf", + "call duration.years.valueOf", + // AddZonedDateTime + "get this.timeZone.getOffsetNanosecondsFor", + "call this.timeZone.getOffsetNanosecondsFor", + "get this.calendar.dateAdd", + "call this.calendar.dateAdd", + // ... inside Calendar.p.dateAdd + "get options.overflow", + "get options.overflow.toString", + "call options.overflow.toString", + // AddZonedDateTime again + "get this.timeZone.getPossibleInstantsFor", + "call this.timeZone.getPossibleInstantsFor", +]; +const actual = []; + +const timeZone = TemporalHelpers.timeZoneObserver(actual, "this.timeZone"); +const calendar = TemporalHelpers.calendarObserver(actual, "this.calendar"); +const instance = new Temporal.ZonedDateTime(0n, timeZone, calendar); +// clear observable operations that occurred during the constructor call +actual.splice(0); + +const duration = TemporalHelpers.propertyBagObserver(actual, { + years: 1, + months: 1, + weeks: 1, + days: 1, + hours: 1, + minutes: 1, + seconds: 1, + milliseconds: 1, + microseconds: 1, + nanoseconds: 1, +}, "duration"); + +const options = TemporalHelpers.propertyBagObserver(actual, { overflow: "constrain" }, "options"); + +instance.add(duration, options); +assert.compareArray(actual, expected, "order of operations"); diff --git a/test/built-ins/Temporal/ZonedDateTime/prototype/equals/order-of-operations.js b/test/built-ins/Temporal/ZonedDateTime/prototype/equals/order-of-operations.js new file mode 100644 index 0000000000..cd9251da32 --- /dev/null +++ b/test/built-ins/Temporal/ZonedDateTime/prototype/equals/order-of-operations.js @@ -0,0 +1,103 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.equals +description: Properties on objects passed to equals() are accessed in the correct order +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + "get other.calendar", + "has other.calendar.calendar", + "get other.calendar.fields", + "call other.calendar.fields", + // PrepareTemporalFields + "get other.day", + "get other.day.valueOf", + "call other.day.valueOf", + "get other.hour", + "get other.hour.valueOf", + "call other.hour.valueOf", + "get other.microsecond", + "get other.microsecond.valueOf", + "call other.microsecond.valueOf", + "get other.millisecond", + "get other.millisecond.valueOf", + "call other.millisecond.valueOf", + "get other.minute", + "get other.minute.valueOf", + "call other.minute.valueOf", + "get other.month", + "get other.month.valueOf", + "call other.month.valueOf", + "get other.monthCode", + "get other.monthCode.toString", + "call other.monthCode.toString", + "get other.nanosecond", + "get other.nanosecond.valueOf", + "call other.nanosecond.valueOf", + "get other.second", + "get other.second.valueOf", + "call other.second.valueOf", + "get other.year", + "get other.year.valueOf", + "call other.year.valueOf", + "get other.timeZone", + "get other.offset", + "get other.offset.toString", + "call other.offset.toString", + "has other.timeZone.timeZone", + // InterpretTemporalDateTimeFields + "get other.calendar.dateFromFields", + "call other.calendar.dateFromFields", + // InterpretISODateTimeOffset + "get other.timeZone.getPossibleInstantsFor", + "call other.timeZone.getPossibleInstantsFor", + "get other.timeZone.getOffsetNanosecondsFor", + "call other.timeZone.getOffsetNanosecondsFor", + // TimeZoneEquals + "get this.timeZone[Symbol.toPrimitive]", + "get this.timeZone.toString", + "call this.timeZone.toString", + "get other.timeZone[Symbol.toPrimitive]", + "get other.timeZone.toString", + "call other.timeZone.toString", + // CalendarEquals + "get this.calendar[Symbol.toPrimitive]", + "get this.calendar.toString", + "call this.calendar.toString", + "get other.calendar[Symbol.toPrimitive]", + "get other.calendar.toString", + "call other.calendar.toString", +]; +const actual = []; + +const other = TemporalHelpers.propertyBagObserver(actual, { + year: 2001, + month: 5, + monthCode: "M05", + day: 2, + hour: 6, + minute: 54, + second: 32, + millisecond: 987, + microsecond: 654, + nanosecond: 321, + offset: "+00:00", + calendar: TemporalHelpers.calendarObserver(actual, "other.calendar"), + timeZone: TemporalHelpers.timeZoneObserver(actual, "other.timeZone"), +}, "other"); + +const instance = new Temporal.ZonedDateTime( + 988786472_987_654_321n, /* 2001-05-02T06:54:32.987654321Z */ + TemporalHelpers.timeZoneObserver(actual, "this.timeZone"), + TemporalHelpers.calendarObserver(actual, "this.calendar"), +); +// clear any observable operations that happen due to time zone or calendar +// calls on the constructor +actual.splice(0); + +instance.equals(other); +assert.compareArray(actual, expected, "order of operations"); diff --git a/test/built-ins/Temporal/ZonedDateTime/prototype/subtract/order-of-operations.js b/test/built-ins/Temporal/ZonedDateTime/prototype/subtract/order-of-operations.js new file mode 100644 index 0000000000..66e4487e53 --- /dev/null +++ b/test/built-ins/Temporal/ZonedDateTime/prototype/subtract/order-of-operations.js @@ -0,0 +1,80 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.subtract +description: Properties on objects passed to subtract() are accessed in the correct order +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + // ToTemporalDurationRecord + "get duration.days", + "get duration.days.valueOf", + "call duration.days.valueOf", + "get duration.hours", + "get duration.hours.valueOf", + "call duration.hours.valueOf", + "get duration.microseconds", + "get duration.microseconds.valueOf", + "call duration.microseconds.valueOf", + "get duration.milliseconds", + "get duration.milliseconds.valueOf", + "call duration.milliseconds.valueOf", + "get duration.minutes", + "get duration.minutes.valueOf", + "call duration.minutes.valueOf", + "get duration.months", + "get duration.months.valueOf", + "call duration.months.valueOf", + "get duration.nanoseconds", + "get duration.nanoseconds.valueOf", + "call duration.nanoseconds.valueOf", + "get duration.seconds", + "get duration.seconds.valueOf", + "call duration.seconds.valueOf", + "get duration.weeks", + "get duration.weeks.valueOf", + "call duration.weeks.valueOf", + "get duration.years", + "get duration.years.valueOf", + "call duration.years.valueOf", + // AddZonedDateTime + "get this.timeZone.getOffsetNanosecondsFor", + "call this.timeZone.getOffsetNanosecondsFor", + "get this.calendar.dateAdd", + "call this.calendar.dateAdd", + // ... inside Calendar.p.dateAdd + "get options.overflow", + "get options.overflow.toString", + "call options.overflow.toString", + // AddZonedDateTime again + "get this.timeZone.getPossibleInstantsFor", + "call this.timeZone.getPossibleInstantsFor", +]; +const actual = []; + +const timeZone = TemporalHelpers.timeZoneObserver(actual, "this.timeZone"); +const calendar = TemporalHelpers.calendarObserver(actual, "this.calendar"); +const instance = new Temporal.ZonedDateTime(0n, timeZone, calendar); +// clear observable operations that occurred during the constructor call +actual.splice(0); + +const duration = TemporalHelpers.propertyBagObserver(actual, { + years: 1, + months: 1, + weeks: 1, + days: 1, + hours: 1, + minutes: 1, + seconds: 1, + milliseconds: 1, + microseconds: 1, + nanoseconds: 1, +}, "duration"); + +const options = TemporalHelpers.propertyBagObserver(actual, { overflow: "constrain" }, "options"); + +instance.subtract(duration, options); +assert.compareArray(actual, expected, "order of operations"); diff --git a/test/built-ins/Temporal/ZonedDateTime/prototype/toString/order-of-operations.js b/test/built-ins/Temporal/ZonedDateTime/prototype/toString/order-of-operations.js new file mode 100644 index 0000000000..a8e3341ed9 --- /dev/null +++ b/test/built-ins/Temporal/ZonedDateTime/prototype/toString/order-of-operations.js @@ -0,0 +1,79 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.tostring +description: Properties on objects passed to toString() are accessed in the correct order +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + "get options.roundingMode", + "get options.roundingMode.toString", + "call options.roundingMode.toString", + "get options.calendarName", + "get options.calendarName.toString", + "call options.calendarName.toString", + "get options.timeZoneName", + "get options.timeZoneName.toString", + "call options.timeZoneName.toString", + "get options.offset", + "get options.offset.toString", + "call options.offset.toString", + "get this.timeZone.getOffsetNanosecondsFor", + "call this.timeZone.getOffsetNanosecondsFor", + "get this.timeZone.getOffsetNanosecondsFor", + "call this.timeZone.getOffsetNanosecondsFor", + "get this.timeZone[Symbol.toPrimitive]", + "get this.timeZone.toString", + "call this.timeZone.toString", + "get this.calendar[Symbol.toPrimitive]", + "get this.calendar.toString", + "call this.calendar.toString", +]; +const actual = []; + +const timeZone = TemporalHelpers.timeZoneObserver(actual, "this.timeZone"); +const calendar = TemporalHelpers.calendarObserver(actual, "this.calendar"); +const instance = new Temporal.ZonedDateTime(0n, timeZone, calendar); +// clear observable operations that occurred during the constructor call +actual.splice(0); + +const expectedForSmallestUnit = [ + "get options.smallestUnit", + "get options.smallestUnit.toString", + "call options.smallestUnit.toString", +].concat(expected); + +instance.toString( + TemporalHelpers.propertyBagObserver(actual, { + fractionalSecondDigits: 3, + roundingMode: "halfExpand", + smallestUnit: "millisecond", + offset: "auto", + timeZoneName: "auto", + calendarName: "auto", + }, "options"), +); +assert.compareArray(actual, expectedForSmallestUnit, "order of operations"); +actual.splice(0); // clear + +const expectedForFractionalSecondDigits = [ + "get options.smallestUnit", + "get options.fractionalSecondDigits", + "get options.fractionalSecondDigits.toString", + "call options.fractionalSecondDigits.toString", +].concat(expected); + +instance.toString( + TemporalHelpers.propertyBagObserver(actual, { + fractionalSecondDigits: "auto", + roundingMode: "halfExpand", + smallestUnit: undefined, + offset: "auto", + timeZoneName: "auto", + calendarName: "auto", + }, "options"), +); +assert.compareArray(actual, expectedForFractionalSecondDigits, "order of operations with smallestUnit undefined"); diff --git a/test/built-ins/Temporal/ZonedDateTime/prototype/with/order-of-operations.js b/test/built-ins/Temporal/ZonedDateTime/prototype/with/order-of-operations.js new file mode 100644 index 0000000000..b4b1340be8 --- /dev/null +++ b/test/built-ins/Temporal/ZonedDateTime/prototype/with/order-of-operations.js @@ -0,0 +1,137 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.with +description: Properties on objects passed to with() are accessed in the correct order +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + // RejectObjectWithCalendarOrTimeZone + "get fields.calendar", + "get fields.timeZone", + // CalendarFields / PrepareTemporalFields + "get this.calendar.fields", + "call this.calendar.fields", + "get fields.day", + "get fields.day.valueOf", + "call fields.day.valueOf", + "get fields.hour", + "get fields.hour.valueOf", + "call fields.hour.valueOf", + "get fields.microsecond", + "get fields.microsecond.valueOf", + "call fields.microsecond.valueOf", + "get fields.millisecond", + "get fields.millisecond.valueOf", + "call fields.millisecond.valueOf", + "get fields.minute", + "get fields.minute.valueOf", + "call fields.minute.valueOf", + "get fields.month", + "get fields.month.valueOf", + "call fields.month.valueOf", + "get fields.monthCode", + "get fields.monthCode.toString", + "call fields.monthCode.toString", + "get fields.nanosecond", + "get fields.nanosecond.valueOf", + "call fields.nanosecond.valueOf", + "get fields.second", + "get fields.second.valueOf", + "call fields.second.valueOf", + "get fields.year", + "get fields.year.valueOf", + "call fields.year.valueOf", + "get fields.offset", + "get fields.offset.toString", + "call fields.offset.toString", + // options + "get options.disambiguation", + "get options.disambiguation.toString", + "call options.disambiguation.toString", + "get options.offset", + "get options.offset.toString", + "call options.offset.toString", + // PrepareTemporalFields + "get this.timeZone.getOffsetNanosecondsFor", + "call this.timeZone.getOffsetNanosecondsFor", + "get this.calendar.day", + "call this.calendar.day", + "get this.timeZone.getOffsetNanosecondsFor", // ZonedDateTime.p.hour + "call this.timeZone.getOffsetNanosecondsFor", + "get this.timeZone.getOffsetNanosecondsFor", // ZonedDateTime.p.microsecond + "call this.timeZone.getOffsetNanosecondsFor", + "get this.timeZone.getOffsetNanosecondsFor", // ZonedDateTime.p.millisecond + "call this.timeZone.getOffsetNanosecondsFor", + "get this.timeZone.getOffsetNanosecondsFor", // ZonedDateTime.p.minute + "call this.timeZone.getOffsetNanosecondsFor", + "get this.timeZone.getOffsetNanosecondsFor", + "call this.timeZone.getOffsetNanosecondsFor", + "get this.calendar.month", + "call this.calendar.month", + "get this.timeZone.getOffsetNanosecondsFor", + "call this.timeZone.getOffsetNanosecondsFor", + "get this.calendar.monthCode", + "call this.calendar.monthCode", + "get this.timeZone.getOffsetNanosecondsFor", // ZonedDateTime.p.nanosecond + "call this.timeZone.getOffsetNanosecondsFor", + "get this.timeZone.getOffsetNanosecondsFor", // ZonedDateTime.p.second + "call this.timeZone.getOffsetNanosecondsFor", + "get this.timeZone.getOffsetNanosecondsFor", + "call this.timeZone.getOffsetNanosecondsFor", + "get this.calendar.year", + "call this.calendar.year", + "get this.timeZone.getOffsetNanosecondsFor", // ZonedDateTime.p.offset + "call this.timeZone.getOffsetNanosecondsFor", + // CalendarMergeFields + "get this.calendar.mergeFields", + "call this.calendar.mergeFields", + // InterpretTemporalDateTimeFields + "get options.overflow", + "get options.overflow.toString", + "call options.overflow.toString", + "get this.calendar.dateFromFields", + "call this.calendar.dateFromFields", + // Calendar.p.dateFromFields + "get options.overflow", + "get options.overflow.toString", + "call options.overflow.toString", + // InterpretISODateTimeOffset + "get this.timeZone.getPossibleInstantsFor", + "call this.timeZone.getPossibleInstantsFor", + "get this.timeZone.getOffsetNanosecondsFor", + "call this.timeZone.getOffsetNanosecondsFor", +]; +const actual = []; + +const timeZone = TemporalHelpers.timeZoneObserver(actual, "this.timeZone"); +const calendar = TemporalHelpers.calendarObserver(actual, "this.calendar"); +const instance = new Temporal.ZonedDateTime(0n, timeZone, calendar); +// clear observable operations that occurred during the constructor call +actual.splice(0); + +const fields = TemporalHelpers.propertyBagObserver(actual, { + year: 1.7, + month: 1.7, + monthCode: "M01", + day: 1.7, + hour: 1.7, + minute: 1.7, + second: 1.7, + millisecond: 1.7, + microsecond: 1.7, + nanosecond: 1.7, + offset: "+00:00", +}, "fields"); + +const options = TemporalHelpers.propertyBagObserver(actual, { + overflow: "constrain", + disambiguation: "compatible", + offset: "prefer", +}, "options"); + +instance.with(fields, options); +assert.compareArray(actual, expected, "order of operations");