diff --git a/JSTests/test262/config.yaml b/JSTests/test262/config.yaml index 6cafbb8dcc17..97394ab873b9 100644 --- a/JSTests/test262/config.yaml +++ b/JSTests/test262/config.yaml @@ -14,6 +14,7 @@ skip: - callable-boundary-realms - FinalizationRegistry.prototype.cleanupSome - decorators + - iterator-helpers - Intl.DurationFormat - Intl.Locale-info # Getters are replaced with methods. paths: diff --git a/JSTests/test262/expectations.yaml b/JSTests/test262/expectations.yaml index 3e4c32c8e0b3..200b318337c3 100644 --- a/JSTests/test262/expectations.yaml +++ b/JSTests/test262/expectations.yaml @@ -601,104 +601,6 @@ test/annexB/language/global-code/switch-dflt-global-skip-early-err-try.js: default: 'Test262Error: An initialized binding is not created prior to evaluation Expected a ReferenceError to be thrown but no exception was thrown at all' test/annexB/language/global-code/switch-dflt-global-skip-early-err.js: default: "SyntaxError: Cannot declare a function that shadows a let/const/class/function variable 'f' in strict mode." -test/built-ins/Array/prototype/Symbol.unscopables/array-grouping.js: - default: 'Test262Error: `group` property value Expected SameValue(«undefined», «true») to be true' - strict mode: 'Test262Error: `group` property value Expected SameValue(«undefined», «true») to be true' -test/built-ins/Array/prototype/group/array-like.js: - default: "TypeError: undefined is not an object (evaluating 'Array.prototype.group.call')" - strict mode: "TypeError: undefined is not an object (evaluating 'Array.prototype.group.call')" -test/built-ins/Array/prototype/group/callback-arg.js: - default: "TypeError: undefined is not a function (near '...arr.group...')" - strict mode: "TypeError: undefined is not a function (near '...arr.group...')" -test/built-ins/Array/prototype/group/callback-throws.js: - default: 'Test262Error: Expected a Test262Error but got a TypeError' - strict mode: 'Test262Error: Expected a Test262Error but got a TypeError' -test/built-ins/Array/prototype/group/emptyList.js: - default: "TypeError: original.group is not a function. (In 'original.group(function () {" - strict mode: "TypeError: original.group is not a function. (In 'original.group(function () {" -test/built-ins/Array/prototype/group/evenOdd.js: - default: "TypeError: array.group is not a function. (In 'array.group(function (i) {" - strict mode: "TypeError: array.group is not a function. (In 'array.group(function (i) {" -test/built-ins/Array/prototype/group/get-throws.js: - default: 'Test262Error: Expected a Test262Error but got a TypeError' - strict mode: 'Test262Error: Expected a Test262Error but got a TypeError' -test/built-ins/Array/prototype/group/groupLength.js: - default: "TypeError: arr.group is not a function. (In 'arr.group(function (i) { return i.length; })', 'arr.group' is undefined)" - strict mode: "TypeError: arr.group is not a function. (In 'arr.group(function (i) { return i.length; })', 'arr.group' is undefined)" -test/built-ins/Array/prototype/group/invalid-property-key.js: - default: 'Test262Error: Expected a Test262Error but got a TypeError' - strict mode: 'Test262Error: Expected a Test262Error but got a TypeError' -test/built-ins/Array/prototype/group/length-throw.js: - default: 'Test262Error: Expected a Test262Error but got a TypeError' - strict mode: 'Test262Error: Expected a Test262Error but got a TypeError' -test/built-ins/Array/prototype/group/length.js: - default: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(obj, name)')" - strict mode: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(obj, name)')" -test/built-ins/Array/prototype/group/name.js: - default: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(obj, name)')" - strict mode: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(obj, name)')" -test/built-ins/Array/prototype/group/null-prototype.js: - default: "TypeError: array.group is not a function. (In 'array.group(function (i) {" - strict mode: "TypeError: array.group is not a function. (In 'array.group(function (i) {" -test/built-ins/Array/prototype/group/sparse-array.js: - default: "TypeError: array.group is not a function. (In 'array.group(function () {" - strict mode: "TypeError: array.group is not a function. (In 'array.group(function () {" -test/built-ins/Array/prototype/group/this-arg-strict.js: - strict mode: "TypeError: [1].group is not a function. (In '[1].group(function() {" -test/built-ins/Array/prototype/group/this-arg.js: - default: "TypeError: [1].group is not a function. (In '[1].group(function() {" -test/built-ins/Array/prototype/group/toPropertyKey.js: - default: "TypeError: array.group is not a function. (In 'array.group(function (v) { return v; })', 'array.group' is undefined)" - strict mode: "TypeError: array.group is not a function. (In 'array.group(function (v) { return v; })', 'array.group' is undefined)" -test/built-ins/Array/prototype/groupToMap/array-like.js: - default: "TypeError: undefined is not an object (evaluating 'Array.prototype.groupToMap.call')" - strict mode: "TypeError: undefined is not an object (evaluating 'Array.prototype.groupToMap.call')" -test/built-ins/Array/prototype/groupToMap/callback-arg.js: - default: "TypeError: undefined is not a function (near '...arr.groupToMap...')" - strict mode: "TypeError: undefined is not a function (near '...arr.groupToMap...')" -test/built-ins/Array/prototype/groupToMap/callback-throws.js: - default: 'Test262Error: Expected a Test262Error but got a TypeError' - strict mode: 'Test262Error: Expected a Test262Error but got a TypeError' -test/built-ins/Array/prototype/groupToMap/emptyList.js: - default: "TypeError: original.groupToMap is not a function. (In 'original.groupToMap(function () {" - strict mode: "TypeError: original.groupToMap is not a function. (In 'original.groupToMap(function () {" -test/built-ins/Array/prototype/groupToMap/evenOdd.js: - default: "TypeError: array.groupToMap is not a function. (In 'array.groupToMap(function (i) {" - strict mode: "TypeError: array.groupToMap is not a function. (In 'array.groupToMap(function (i) {" -test/built-ins/Array/prototype/groupToMap/get-throws.js: - default: 'Test262Error: Expected a Test262Error but got a TypeError' - strict mode: 'Test262Error: Expected a Test262Error but got a TypeError' -test/built-ins/Array/prototype/groupToMap/groupLength.js: - default: "TypeError: arr.groupToMap is not a function. (In 'arr.groupToMap(function (i) { return i.length; })', 'arr.groupToMap' is undefined)" - strict mode: "TypeError: arr.groupToMap is not a function. (In 'arr.groupToMap(function (i) { return i.length; })', 'arr.groupToMap' is undefined)" -test/built-ins/Array/prototype/groupToMap/invalid-property-key.js: - default: "TypeError: [1].groupToMap is not a function. (In '[1].groupToMap(function() {" - strict mode: "TypeError: [1].groupToMap is not a function. (In '[1].groupToMap(function() {" -test/built-ins/Array/prototype/groupToMap/length-throw.js: - default: 'Test262Error: Expected a Test262Error but got a TypeError' - strict mode: 'Test262Error: Expected a Test262Error but got a TypeError' -test/built-ins/Array/prototype/groupToMap/length.js: - default: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(obj, name)')" - strict mode: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(obj, name)')" -test/built-ins/Array/prototype/groupToMap/map-instance.js: - default: "TypeError: array.groupToMap is not a function. (In 'array.groupToMap(function (i) {" - strict mode: "TypeError: array.groupToMap is not a function. (In 'array.groupToMap(function (i) {" -test/built-ins/Array/prototype/groupToMap/name.js: - default: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(obj, name)')" - strict mode: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(obj, name)')" -test/built-ins/Array/prototype/groupToMap/negativeZero.js: - default: "TypeError: arr.groupToMap is not a function. (In 'arr.groupToMap(function (i) { return i; })', 'arr.groupToMap' is undefined)" - strict mode: "TypeError: arr.groupToMap is not a function. (In 'arr.groupToMap(function (i) { return i; })', 'arr.groupToMap' is undefined)" -test/built-ins/Array/prototype/groupToMap/sparse-array.js: - default: "TypeError: array.groupToMap is not a function. (In 'array.groupToMap(function () {" - strict mode: "TypeError: array.groupToMap is not a function. (In 'array.groupToMap(function () {" -test/built-ins/Array/prototype/groupToMap/this-arg-strict.js: - strict mode: "TypeError: [1].groupToMap is not a function. (In '[1].groupToMap(function() {" -test/built-ins/Array/prototype/groupToMap/this-arg.js: - default: "TypeError: [1].groupToMap is not a function. (In '[1].groupToMap(function() {" -test/built-ins/Array/prototype/groupToMap/toPropertyKey.js: - default: "TypeError: array.groupToMap is not a function. (In 'array.groupToMap(v => v)', 'array.groupToMap' is undefined)" - strict mode: "TypeError: array.groupToMap is not a function. (In 'array.groupToMap(v => v)', 'array.groupToMap' is undefined)" test/built-ins/ArrayBuffer/prototype/detached/detached-buffer-resizable.js: default: 'Test262Error: Resizable ArrayBuffer with maxByteLength of 0 is not detached Expected SameValue(«undefined», «false») to be true' strict mode: 'Test262Error: Resizable ArrayBuffer with maxByteLength of 0 is not detached Expected SameValue(«undefined», «false») to be true' @@ -732,6 +634,24 @@ test/built-ins/ArrayBuffer/prototype/detached/this-is-sharedarraybuffer-resizabl test/built-ins/ArrayBuffer/prototype/detached/this-is-sharedarraybuffer.js: default: "TypeError: undefined is not an object (evaluating 'detached.get')" strict mode: "TypeError: undefined is not an object (evaluating 'detached.get')" +test/built-ins/ArrayBuffer/prototype/transfer/descriptor.js: + default: 'Test262Error: obj should have an own property transfer' + strict mode: 'Test262Error: obj should have an own property transfer' +test/built-ins/ArrayBuffer/prototype/transfer/extensible.js: + default: 'Test262Error: Expected true but got false' + strict mode: 'Test262Error: Expected true but got false' +test/built-ins/ArrayBuffer/prototype/transfer/from-fixed-to-larger-no-resizable.js: + default: "TypeError: source.transfer is not a function. (In 'source.transfer(5)', 'source.transfer' is undefined)" + strict mode: "TypeError: source.transfer is not a function. (In 'source.transfer(5)', 'source.transfer' is undefined)" +test/built-ins/ArrayBuffer/prototype/transfer/from-fixed-to-same-no-resizable.js: + default: "TypeError: source.transfer is not a function. (In 'source.transfer()', 'source.transfer' is undefined)" + strict mode: "TypeError: source.transfer is not a function. (In 'source.transfer()', 'source.transfer' is undefined)" +test/built-ins/ArrayBuffer/prototype/transfer/from-fixed-to-smaller-no-resizable.js: + default: "TypeError: source.transfer is not a function. (In 'source.transfer(3)', 'source.transfer' is undefined)" + strict mode: "TypeError: source.transfer is not a function. (In 'source.transfer(3)', 'source.transfer' is undefined)" +test/built-ins/ArrayBuffer/prototype/transfer/from-fixed-to-zero-no-resizable.js: + default: "TypeError: source.transfer is not a function. (In 'source.transfer(0)', 'source.transfer' is undefined)" + strict mode: "TypeError: source.transfer is not a function. (In 'source.transfer(0)', 'source.transfer' is undefined)" test/built-ins/ArrayBuffer/prototype/transfer/from-resizable-to-larger.js: default: 'Test262Error: dest.resizable Expected SameValue(«false», «true») to be true' strict mode: 'Test262Error: dest.resizable Expected SameValue(«false», «true») to be true' @@ -744,6 +664,96 @@ test/built-ins/ArrayBuffer/prototype/transfer/from-resizable-to-smaller.js: test/built-ins/ArrayBuffer/prototype/transfer/from-resizable-to-zero.js: default: 'Test262Error: dest.resizable Expected SameValue(«false», «true») to be true' strict mode: 'Test262Error: dest.resizable Expected SameValue(«false», «true») to be true' +test/built-ins/ArrayBuffer/prototype/transfer/length.js: + default: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(obj, name)')" + strict mode: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(obj, name)')" +test/built-ins/ArrayBuffer/prototype/transfer/name.js: + default: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(obj, name)')" + strict mode: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(obj, name)')" +test/built-ins/ArrayBuffer/prototype/transfer/new-length-excessive.js: + default: 'Test262Error: Expected a RangeError but got a TypeError' + strict mode: 'Test262Error: Expected a RangeError but got a TypeError' +test/built-ins/ArrayBuffer/prototype/transfer/new-length-non-number.js: + default: 'Test262Error: Expected SameValue(«0», «2») to be true' + strict mode: 'Test262Error: Expected SameValue(«0», «2») to be true' +test/built-ins/ArrayBuffer/prototype/transfer/nonconstructor.js: + default: "TypeError: undefined is not an object (evaluating 'Object.prototype.hasOwnProperty.call(ArrayBuffer.prototype.transfer, 'prototype')')" + strict mode: "TypeError: undefined is not an object (evaluating 'Object.prototype.hasOwnProperty.call(ArrayBuffer.prototype.transfer, 'prototype')')" +test/built-ins/ArrayBuffer/prototype/transfer/this-is-detached.js: + default: 'Test262Error: Expected SameValue(«undefined», «function») to be true' + strict mode: 'Test262Error: Expected SameValue(«undefined», «function») to be true' +test/built-ins/ArrayBuffer/prototype/transfer/this-is-not-arraybuffer-object.js: + default: 'Test262Error: Expected SameValue(«undefined», «function») to be true' + strict mode: 'Test262Error: Expected SameValue(«undefined», «function») to be true' +test/built-ins/ArrayBuffer/prototype/transfer/this-is-not-object.js: + default: 'Test262Error: Expected SameValue(«undefined», «function») to be true' + strict mode: 'Test262Error: Expected SameValue(«undefined», «function») to be true' +test/built-ins/ArrayBuffer/prototype/transferToFixedLength/descriptor.js: + default: 'Test262Error: obj should have an own property transferToFixedLength' + strict mode: 'Test262Error: obj should have an own property transferToFixedLength' +test/built-ins/ArrayBuffer/prototype/transferToFixedLength/extensible.js: + default: 'Test262Error: Expected true but got false' + strict mode: 'Test262Error: Expected true but got false' +test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-larger-no-resizable.js: + default: "TypeError: source.transferToFixedLength is not a function. (In 'source.transferToFixedLength(5)', 'source.transferToFixedLength' is undefined)" + strict mode: "TypeError: source.transferToFixedLength is not a function. (In 'source.transferToFixedLength(5)', 'source.transferToFixedLength' is undefined)" +test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-larger.js: + default: "TypeError: source.transferToFixedLength is not a function. (In 'source.transferToFixedLength(5)', 'source.transferToFixedLength' is undefined)" + strict mode: "TypeError: source.transferToFixedLength is not a function. (In 'source.transferToFixedLength(5)', 'source.transferToFixedLength' is undefined)" +test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-same-no-resizable.js: + default: "TypeError: source.transferToFixedLength is not a function. (In 'source.transferToFixedLength()', 'source.transferToFixedLength' is undefined)" + strict mode: "TypeError: source.transferToFixedLength is not a function. (In 'source.transferToFixedLength()', 'source.transferToFixedLength' is undefined)" +test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-same.js: + default: "TypeError: source.transferToFixedLength is not a function. (In 'source.transferToFixedLength()', 'source.transferToFixedLength' is undefined)" + strict mode: "TypeError: source.transferToFixedLength is not a function. (In 'source.transferToFixedLength()', 'source.transferToFixedLength' is undefined)" +test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-smaller-no-resizable.js: + default: "TypeError: source.transferToFixedLength is not a function. (In 'source.transferToFixedLength(3)', 'source.transferToFixedLength' is undefined)" + strict mode: "TypeError: source.transferToFixedLength is not a function. (In 'source.transferToFixedLength(3)', 'source.transferToFixedLength' is undefined)" +test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-smaller.js: + default: "TypeError: source.transferToFixedLength is not a function. (In 'source.transferToFixedLength(3)', 'source.transferToFixedLength' is undefined)" + strict mode: "TypeError: source.transferToFixedLength is not a function. (In 'source.transferToFixedLength(3)', 'source.transferToFixedLength' is undefined)" +test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-zero-no-resizable.js: + default: "TypeError: source.transferToFixedLength is not a function. (In 'source.transferToFixedLength(0)', 'source.transferToFixedLength' is undefined)" + strict mode: "TypeError: source.transferToFixedLength is not a function. (In 'source.transferToFixedLength(0)', 'source.transferToFixedLength' is undefined)" +test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-zero.js: + default: "TypeError: source.transferToFixedLength is not a function. (In 'source.transferToFixedLength(0)', 'source.transferToFixedLength' is undefined)" + strict mode: "TypeError: source.transferToFixedLength is not a function. (In 'source.transferToFixedLength(0)', 'source.transferToFixedLength' is undefined)" +test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-resizable-to-larger.js: + default: "TypeError: source.transferToFixedLength is not a function. (In 'source.transferToFixedLength(5)', 'source.transferToFixedLength' is undefined)" + strict mode: "TypeError: source.transferToFixedLength is not a function. (In 'source.transferToFixedLength(5)', 'source.transferToFixedLength' is undefined)" +test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-resizable-to-same.js: + default: "TypeError: source.transferToFixedLength is not a function. (In 'source.transferToFixedLength()', 'source.transferToFixedLength' is undefined)" + strict mode: "TypeError: source.transferToFixedLength is not a function. (In 'source.transferToFixedLength()', 'source.transferToFixedLength' is undefined)" +test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-resizable-to-smaller.js: + default: "TypeError: source.transferToFixedLength is not a function. (In 'source.transferToFixedLength(3)', 'source.transferToFixedLength' is undefined)" + strict mode: "TypeError: source.transferToFixedLength is not a function. (In 'source.transferToFixedLength(3)', 'source.transferToFixedLength' is undefined)" +test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-resizable-to-zero.js: + default: "TypeError: source.transferToFixedLength is not a function. (In 'source.transferToFixedLength(0)', 'source.transferToFixedLength' is undefined)" + strict mode: "TypeError: source.transferToFixedLength is not a function. (In 'source.transferToFixedLength(0)', 'source.transferToFixedLength' is undefined)" +test/built-ins/ArrayBuffer/prototype/transferToFixedLength/length.js: + default: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(obj, name)')" + strict mode: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(obj, name)')" +test/built-ins/ArrayBuffer/prototype/transferToFixedLength/name.js: + default: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(obj, name)')" + strict mode: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(obj, name)')" +test/built-ins/ArrayBuffer/prototype/transferToFixedLength/new-length-excessive.js: + default: 'Test262Error: Expected a RangeError but got a TypeError' + strict mode: 'Test262Error: Expected a RangeError but got a TypeError' +test/built-ins/ArrayBuffer/prototype/transferToFixedLength/new-length-non-number.js: + default: 'Test262Error: Expected SameValue(«0», «2») to be true' + strict mode: 'Test262Error: Expected SameValue(«0», «2») to be true' +test/built-ins/ArrayBuffer/prototype/transferToFixedLength/nonconstructor.js: + default: "TypeError: undefined is not an object (evaluating 'Object.prototype.hasOwnProperty.call(ArrayBuffer.prototype.transferToFixedLength, 'prototype')')" + strict mode: "TypeError: undefined is not an object (evaluating 'Object.prototype.hasOwnProperty.call(ArrayBuffer.prototype.transferToFixedLength, 'prototype')')" +test/built-ins/ArrayBuffer/prototype/transferToFixedLength/this-is-detached.js: + default: 'Test262Error: Expected SameValue(«undefined», «function») to be true' + strict mode: 'Test262Error: Expected SameValue(«undefined», «function») to be true' +test/built-ins/ArrayBuffer/prototype/transferToFixedLength/this-is-not-arraybuffer-object.js: + default: 'Test262Error: Expected SameValue(«undefined», «function») to be true' + strict mode: 'Test262Error: Expected SameValue(«undefined», «function») to be true' +test/built-ins/ArrayBuffer/prototype/transferToFixedLength/this-is-not-object.js: + default: 'Test262Error: Expected SameValue(«undefined», «function») to be true' + strict mode: 'Test262Error: Expected SameValue(«undefined», «function») to be true' test/built-ins/AsyncGeneratorPrototype/return/return-suspendedStart-broken-promise.js: default: 'Error: broken promise' strict mode: 'Error: broken promise' @@ -771,9 +781,15 @@ test/built-ins/Function/prototype/toString/GeneratorFunction.js: test/built-ins/Function/prototype/toString/built-in-function-object.js: default: 'Test262Error: Conforms to NativeFunction Syntax: "function $*() {\n [native code]\n}" (%RegExp%.$*)' strict mode: 'Test262Error: Conforms to NativeFunction Syntax: "function $*() {\n [native code]\n}" (%RegExp%.$*)' +test/built-ins/Map/groupBy/callback-arg.js: + default: 'Test262Error: only two arguments are passed Expected SameValue(«3», «2») to be true' + strict mode: 'Test262Error: only two arguments are passed Expected SameValue(«3», «2») to be true' test/built-ins/Object/entries/order-after-define-property-with-function.js: default: 'Test262Error: Expected [a, name] and [name, a] to have the same contents. ' strict mode: 'Test262Error: Expected [a, name] and [name, a] to have the same contents. ' +test/built-ins/Object/groupBy/callback-arg.js: + default: 'Test262Error: only two arguments are passed Expected SameValue(«3», «2») to be true' + strict mode: 'Test262Error: only two arguments are passed Expected SameValue(«3», «2») to be true' test/built-ins/Object/keys/order-after-define-property-with-function.js: default: 'Test262Error: Expected [a, length] and [length, a] to have the same contents. ' strict mode: 'Test262Error: Expected [a, length] and [length, a] to have the same contents. ' @@ -846,21 +862,42 @@ test/built-ins/RegExp/prototype/exec/u-lastindex-adv.js: test/built-ins/RegExp/quantifier-integer-limit.js: default: 'SyntaxError: Invalid regular expression: number too large in {} quantifier' strict mode: 'SyntaxError: Invalid regular expression: number too large in {} quantifier' +test/built-ins/Temporal/Duration/compare/relativeto-propertybag-timezone-string.js: + default: 'TypeError: Property description must be an object.' + strict mode: 'TypeError: Property description must be an object.' test/built-ins/Temporal/Duration/prototype/add/precision-exact-mathematical-values.js: default: 'Test262Error: duration1.add(duration2) nanoseconds result Expected SameValue(«24», «0») to be true' strict mode: 'Test262Error: duration1.add(duration2) nanoseconds result Expected SameValue(«24», «0») to be true' +test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-calendar-string.js: + default: 'RangeError: Cannot add a duration of years, months, or weeks without a relativeTo option' + strict mode: 'RangeError: Cannot add a duration of years, months, or weeks without a relativeTo option' +test/built-ins/Temporal/Duration/prototype/round/largestunit-correct-rebalancing.js: + default: 'RangeError: Cannot round a duration of years, months, or weeks without a relativeTo option' + strict mode: "ReferenceError: Can't find variable: unit" test/built-ins/Temporal/Duration/prototype/round/precision-exact-in-round-duration.js: default: 'Test262Error: hours result Expected SameValue(«100000», «100001») to be true' strict mode: 'Test262Error: hours result Expected SameValue(«100000», «100001») to be true' +test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-calendar-string.js: + default: 'Error: FIXME: years, months, or weeks rounding with relativeTo not implemented yet' + strict mode: 'Error: FIXME: years, months, or weeks rounding with relativeTo not implemented yet' test/built-ins/Temporal/Duration/prototype/round/roundingincrement-non-integer.js: default: 'Error: FIXME: years, months, or weeks rounding with relativeTo not implemented yet' strict mode: 'Error: FIXME: years, months, or weeks rounding with relativeTo not implemented yet' test/built-ins/Temporal/Duration/prototype/round/roundingincrement-out-of-range.js: default: 'Test262Error: Expected a RangeError but got a Error' strict mode: 'Test262Error: Expected a RangeError but got a Error' +test/built-ins/Temporal/Duration/prototype/round/zero-day-length-1.js: + default: "TypeError: undefined is not a constructor (evaluating 'new Temporal.ZonedDateTime(0n, tz, \"iso8601\")')" + strict mode: "TypeError: undefined is not a constructor (evaluating 'new Temporal.ZonedDateTime(0n, tz, \"iso8601\")')" +test/built-ins/Temporal/Duration/prototype/round/zero-day-length-2.js: + default: "TypeError: undefined is not a constructor (evaluating 'new Temporal.ZonedDateTime(0n, tz, cal)')" + strict mode: "TypeError: undefined is not a constructor (evaluating 'new Temporal.ZonedDateTime(0n, tz, cal)')" test/built-ins/Temporal/Duration/prototype/subtract/precision-exact-mathematical-values.js: default: 'Test262Error: duration1.subtract(duration2) nanoseconds result Expected SameValue(«24», «0») to be true' strict mode: 'Test262Error: duration1.subtract(duration2) nanoseconds result Expected SameValue(«24», «0») to be true' +test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-calendar-string.js: + default: 'RangeError: Cannot subtract a duration of years, months, or weeks without a relativeTo option' + strict mode: 'RangeError: Cannot subtract a duration of years, months, or weeks without a relativeTo option' test/built-ins/Temporal/Duration/prototype/toString/fractionalseconddigits-non-integer.js: default: 'Test262Error: fractionalSecondDigits -0.6 floors to -1 and is out of range Expected a RangeError to be thrown but no exception was thrown at all' strict mode: 'Test262Error: fractionalSecondDigits -0.6 floors to -1 and is out of range Expected a RangeError to be thrown but no exception was thrown at all' @@ -876,12 +913,30 @@ test/built-ins/Temporal/Duration/prototype/total/precision-exact-mathematical-va test/built-ins/Temporal/Duration/prototype/total/precision-exact-mathematical-values-2.js: default: 'Test262Error: Expected SameValue(«4001», «4000.9999999999995») to be true' strict mode: 'Test262Error: Expected SameValue(«4001», «4000.9999999999995») to be true' +test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-calendar-string.js: + default: 'RangeError: Cannot total a duration of years, months, or weeks without a relativeTo option' + strict mode: 'RangeError: Cannot total a duration of years, months, or weeks without a relativeTo option' +test/built-ins/Temporal/Duration/prototype/total/zero-day-length-1.js: + default: "TypeError: undefined is not a constructor (evaluating 'new Temporal.ZonedDateTime(0n, tz, \"iso8601\")')" + strict mode: "TypeError: undefined is not a constructor (evaluating 'new Temporal.ZonedDateTime(0n, tz, \"iso8601\")')" +test/built-ins/Temporal/Duration/prototype/total/zero-day-length-2.js: + default: "TypeError: undefined is not a constructor (evaluating 'new Temporal.ZonedDateTime(0n, tz, cal)')" + strict mode: "TypeError: undefined is not a constructor (evaluating 'new Temporal.ZonedDateTime(0n, tz, cal)')" test/built-ins/Temporal/Instant/compare/argument-string-date-with-utc-offset.js: default: "RangeError: '1970-01-01T00Z[!UTC]' is not a valid Temporal.Instant string" strict mode: "RangeError: '1970-01-01T00Z[!UTC]' is not a valid Temporal.Instant string" test/built-ins/Temporal/Instant/from/argument-string-date-with-utc-offset.js: default: "RangeError: '1970-01-01T00Z[!UTC]' is not a valid Temporal.Instant string" strict mode: "RangeError: '1970-01-01T00Z[!UTC]' is not a valid Temporal.Instant string" +test/built-ins/Temporal/Instant/prototype/epochMicroseconds/basic.js: + default: 'Test262Error: epochMicroseconds pre epoch Expected SameValue(«-217175010876543», «-217175010876544») to be true' + strict mode: 'Test262Error: epochMicroseconds pre epoch Expected SameValue(«-217175010876543», «-217175010876544») to be true' +test/built-ins/Temporal/Instant/prototype/epochMilliseconds/basic.js: + default: 'Test262Error: epochMilliseconds pre epoch Expected SameValue(«-217175010876», «-217175010877») to be true' + strict mode: 'Test262Error: epochMilliseconds pre epoch Expected SameValue(«-217175010876», «-217175010877») to be true' +test/built-ins/Temporal/Instant/prototype/epochSeconds/basic.js: + default: 'Test262Error: epochSeconds pre epoch Expected SameValue(«-217175010», «-217175011») to be true' + strict mode: 'Test262Error: epochSeconds pre epoch Expected SameValue(«-217175010», «-217175011») to be true' test/built-ins/Temporal/Instant/prototype/equals/argument-string-date-with-utc-offset.js: default: "RangeError: '1970-01-01T00Z[!UTC]' is not a valid Temporal.Instant string" strict mode: "RangeError: '1970-01-01T00Z[!UTC]' is not a valid Temporal.Instant string" @@ -928,8 +983,8 @@ test/built-ins/Temporal/Instant/prototype/toString/order-of-operations.js: default: 'Error: FIXME: Temporal.Instant.toString({timeZone}) not implemented yet' strict mode: 'Error: FIXME: Temporal.Instant.toString({timeZone}) not implemented yet' test/built-ins/Temporal/Instant/prototype/toString/timezone-wrong-type.js: - default: 'Test262Error: calendar instance does not convert to a valid ISO string Expected a RangeError to be thrown but no exception was thrown at all' - strict mode: 'Test262Error: calendar instance does not convert to a valid ISO string Expected a RangeError to be thrown but no exception was thrown at all' + default: 'Test262Error: object not implementing time zone protocol is not a valid object and does not convert to a string Expected a TypeError to be thrown but no exception was thrown at all' + strict mode: 'Test262Error: object not implementing time zone protocol is not a valid object and does not convert to a string Expected a TypeError to be thrown but no exception was thrown at all' test/built-ins/Temporal/Instant/prototype/until/argument-string-date-with-utc-offset.js: default: "RangeError: '1970-01-01T00Z[!UTC]' is not a valid Temporal.Instant string" strict mode: "RangeError: '1970-01-01T00Z[!UTC]' is not a valid Temporal.Instant string" @@ -963,15 +1018,45 @@ test/built-ins/Temporal/Instant/prototype/until/roundingmode-halfTrunc.js: test/built-ins/Temporal/Instant/prototype/until/roundingmode-trunc.js: default: 'Test262Error: rounds to hours (rounding mode = trunc, negative case) hours result Expected SameValue(«-376436», «-376435») to be true' strict mode: 'Test262Error: rounds to hours (rounding mode = trunc, negative case) hours result Expected SameValue(«-376436», «-376435») to be true' +test/built-ins/Temporal/Now/timeZoneId/extensible.js: + default: 'Test262Error: Object.isExtensible(Temporal.Now.timeZoneId) must return true' + strict mode: 'Test262Error: Object.isExtensible(Temporal.Now.timeZoneId) must return true' +test/built-ins/Temporal/Now/timeZoneId/length.js: + default: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(obj, name)')" + strict mode: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(obj, name)')" +test/built-ins/Temporal/Now/timeZoneId/name.js: + default: "TypeError: undefined is not an object (evaluating 'Temporal.Now.timeZoneId.name')" + strict mode: "TypeError: undefined is not an object (evaluating 'Temporal.Now.timeZoneId.name')" +test/built-ins/Temporal/Now/timeZoneId/not-a-constructor.js: + default: 'Test262Error: isConstructor invoked with a non-function value' + strict mode: 'Test262Error: isConstructor invoked with a non-function value' +test/built-ins/Temporal/Now/timeZoneId/prop-desc.js: + default: 'Test262Error: typeof is function Expected SameValue(«undefined», «function») to be true' + strict mode: 'Test262Error: typeof is function Expected SameValue(«undefined», «function») to be true' +test/built-ins/Temporal/Now/timeZoneId/return-value.js: + default: "TypeError: Temporal.Now.timeZoneId is not a function. (In 'Temporal.Now.timeZoneId()', 'Temporal.Now.timeZoneId' is undefined)" + strict mode: "TypeError: Temporal.Now.timeZoneId is not a function. (In 'Temporal.Now.timeZoneId()', 'Temporal.Now.timeZoneId' is undefined)" test/built-ins/Temporal/PlainDate/argument-convert.js: default: 'Test262Error: year undefined Expected a RangeError to be thrown but no exception was thrown at all' strict mode: 'Test262Error: year undefined Expected a RangeError to be thrown but no exception was thrown at all' +test/built-ins/Temporal/PlainDate/calendar-case-insensitive.js: + default: 'Test262Error: Calendar is case-insensitive Expected SameValue(«undefined», «iso8601») to be true' + strict mode: 'Test262Error: Calendar is case-insensitive Expected SameValue(«undefined», «iso8601») to be true' +test/built-ins/Temporal/PlainDate/calendar-string.js: + default: 'Test262Error: Calendar created from string "iso8601" Expected SameValue(«iso8601», «iso8601») to be true' + strict mode: 'Test262Error: Calendar created from string "iso8601" Expected SameValue(«iso8601», «iso8601») to be true' +test/built-ins/Temporal/PlainDate/calendar-undefined.js: + default: 'Test262Error: calendar slot should store string Expected SameValue(«iso8601», «iso8601») to be true' + strict mode: 'Test262Error: calendar slot should store string Expected SameValue(«iso8601», «iso8601») to be true' test/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-case-insensitive.js: default: 'RangeError: invalid calendar ID' strict mode: 'RangeError: invalid calendar ID' test/built-ins/Temporal/PlainDate/compare/argument-string-date-with-utc-offset.js: default: 'RangeError: invalid date string' strict mode: 'RangeError: invalid date string' +test/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-string.js: + default: 'Test262Error: calendar slot stores a string Expected SameValue(«iso8601», «iso8601») to be true' + strict mode: 'Test262Error: calendar slot stores a string Expected SameValue(«iso8601», «iso8601») to be true' test/built-ins/Temporal/PlainDate/from/argument-string-date-with-utc-offset.js: default: 'RangeError: invalid date string' strict mode: 'RangeError: invalid date string' @@ -981,9 +1066,66 @@ test/built-ins/Temporal/PlainDate/from/order-of-operations.js: test/built-ins/Temporal/PlainDate/prototype/add/order-of-operations.js: default: 'Test262Error: Expected [get fields.days, get fields.days.valueOf, call fields.days.valueOf, get fields.hours, get fields.hours.valueOf, call fields.hours.valueOf, get fields.microseconds, get fields.microseconds.valueOf, call fields.microseconds.valueOf, get fields.milliseconds, get fields.milliseconds.valueOf, call fields.milliseconds.valueOf, get fields.minutes, get fields.minutes.valueOf, call fields.minutes.valueOf, get fields.months, get fields.months.valueOf, call fields.months.valueOf, get fields.nanoseconds, get fields.nanoseconds.valueOf, call fields.nanoseconds.valueOf, get fields.seconds, get fields.seconds.valueOf, call fields.seconds.valueOf, get fields.weeks, get fields.weeks.valueOf, call fields.weeks.valueOf, get fields.years, get fields.years.valueOf, call fields.years.valueOf, get options.overflow, get options.overflow.toString, call options.overflow.toString] and [get fields.days, get fields.days.valueOf, call fields.days.valueOf, get fields.hours, get fields.hours.valueOf, call fields.hours.valueOf, get fields.microseconds, get fields.microseconds.valueOf, call fields.microseconds.valueOf, get fields.milliseconds, get fields.milliseconds.valueOf, call fields.milliseconds.valueOf, get fields.minutes, get fields.minutes.valueOf, call fields.minutes.valueOf, get fields.months, get fields.months.valueOf, call fields.months.valueOf, get fields.nanoseconds, get fields.nanoseconds.valueOf, call fields.nanoseconds.valueOf, get fields.seconds, get fields.seconds.valueOf, call fields.seconds.valueOf, get fields.weeks, get fields.weeks.valueOf, call fields.weeks.valueOf, get fields.years, get fields.years.valueOf, call fields.years.valueOf, get this.calendar.dateAdd, call this.calendar.dateAdd, get options.overflow, get options.overflow.toString, call options.overflow.toString] to have the same contents. order of operations' strict mode: 'Test262Error: Expected [get fields.days, get fields.days.valueOf, call fields.days.valueOf, get fields.hours, get fields.hours.valueOf, call fields.hours.valueOf, get fields.microseconds, get fields.microseconds.valueOf, call fields.microseconds.valueOf, get fields.milliseconds, get fields.milliseconds.valueOf, call fields.milliseconds.valueOf, get fields.minutes, get fields.minutes.valueOf, call fields.minutes.valueOf, get fields.months, get fields.months.valueOf, call fields.months.valueOf, get fields.nanoseconds, get fields.nanoseconds.valueOf, call fields.nanoseconds.valueOf, get fields.seconds, get fields.seconds.valueOf, call fields.seconds.valueOf, get fields.weeks, get fields.weeks.valueOf, call fields.weeks.valueOf, get fields.years, get fields.years.valueOf, call fields.years.valueOf, get options.overflow, get options.overflow.toString, call options.overflow.toString] and [get fields.days, get fields.days.valueOf, call fields.days.valueOf, get fields.hours, get fields.hours.valueOf, call fields.hours.valueOf, get fields.microseconds, get fields.microseconds.valueOf, call fields.microseconds.valueOf, get fields.milliseconds, get fields.milliseconds.valueOf, call fields.milliseconds.valueOf, get fields.minutes, get fields.minutes.valueOf, call fields.minutes.valueOf, get fields.months, get fields.months.valueOf, call fields.months.valueOf, get fields.nanoseconds, get fields.nanoseconds.valueOf, call fields.nanoseconds.valueOf, get fields.seconds, get fields.seconds.valueOf, call fields.seconds.valueOf, get fields.weeks, get fields.weeks.valueOf, call fields.weeks.valueOf, get fields.years, get fields.years.valueOf, call fields.years.valueOf, get this.calendar.dateAdd, call this.calendar.dateAdd, get options.overflow, get options.overflow.toString, call options.overflow.toString] to have the same contents. order of operations' +test/built-ins/Temporal/PlainDate/prototype/calendarId/branding.js: + default: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(Temporal.PlainDate.prototype, \"calendarId\").get')" + strict mode: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(Temporal.PlainDate.prototype, \"calendarId\").get')" +test/built-ins/Temporal/PlainDate/prototype/calendarId/prop-desc.js: + default: "TypeError: undefined is not an object (evaluating 'descriptor.get')" + strict mode: "TypeError: undefined is not an object (evaluating 'descriptor.get')" +test/built-ins/Temporal/PlainDate/prototype/day/builtin-calendar-no-observable-calls.js: + default: 'TypeError: Property description must be an object.' + strict mode: 'TypeError: Property description must be an object.' +test/built-ins/Temporal/PlainDate/prototype/dayOfWeek/builtin-calendar-no-observable-calls.js: + default: 'TypeError: Property description must be an object.' + strict mode: 'TypeError: Property description must be an object.' +test/built-ins/Temporal/PlainDate/prototype/dayOfYear/builtin-calendar-no-observable-calls.js: + default: 'TypeError: Property description must be an object.' + strict mode: 'TypeError: Property description must be an object.' +test/built-ins/Temporal/PlainDate/prototype/daysInMonth/builtin-calendar-no-observable-calls.js: + default: 'TypeError: Property description must be an object.' + strict mode: 'TypeError: Property description must be an object.' +test/built-ins/Temporal/PlainDate/prototype/daysInWeek/builtin-calendar-no-observable-calls.js: + default: 'TypeError: Property description must be an object.' + strict mode: 'TypeError: Property description must be an object.' +test/built-ins/Temporal/PlainDate/prototype/daysInYear/builtin-calendar-no-observable-calls.js: + default: 'TypeError: Property description must be an object.' + strict mode: 'TypeError: Property description must be an object.' test/built-ins/Temporal/PlainDate/prototype/equals/argument-string-date-with-utc-offset.js: default: 'RangeError: invalid date string' strict mode: 'RangeError: invalid date string' +test/built-ins/Temporal/PlainDate/prototype/getCalendar/branding.js: + default: 'Test262Error: Expected SameValue(«undefined», «function») to be true' + strict mode: 'Test262Error: Expected SameValue(«undefined», «function») to be true' +test/built-ins/Temporal/PlainDate/prototype/getCalendar/builtin.js: + default: 'Test262Error: Built-in objects must be extensible. Expected SameValue(«false», «true») to be true' + strict mode: 'Test262Error: Built-in objects must be extensible. Expected SameValue(«false», «true») to be true' +test/built-ins/Temporal/PlainDate/prototype/getCalendar/length.js: + default: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(obj, name)')" + strict mode: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(obj, name)')" +test/built-ins/Temporal/PlainDate/prototype/getCalendar/name.js: + default: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(obj, name)')" + strict mode: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(obj, name)')" +test/built-ins/Temporal/PlainDate/prototype/getCalendar/not-a-constructor.js: + default: 'Test262Error: isConstructor invoked with a non-function value' + strict mode: 'Test262Error: isConstructor invoked with a non-function value' +test/built-ins/Temporal/PlainDate/prototype/getCalendar/prop-desc.js: + default: 'Test262Error: `typeof PlainDate.prototype.getCalendar` is `function` Expected SameValue(«undefined», «function») to be true' + strict mode: 'Test262Error: `typeof PlainDate.prototype.getCalendar` is `function` Expected SameValue(«undefined», «function») to be true' +test/built-ins/Temporal/PlainDate/prototype/getISOFields/field-names.js: + default: 'Test262Error: calendar result Expected SameValue(«iso8601», «iso8601») to be true' + strict mode: 'Test262Error: calendar result Expected SameValue(«iso8601», «iso8601») to be true' +test/built-ins/Temporal/PlainDate/prototype/inLeapYear/builtin-calendar-no-observable-calls.js: + default: 'TypeError: Property description must be an object.' + strict mode: 'TypeError: Property description must be an object.' +test/built-ins/Temporal/PlainDate/prototype/month/builtin-calendar-no-observable-calls.js: + default: 'TypeError: Property description must be an object.' + strict mode: 'TypeError: Property description must be an object.' +test/built-ins/Temporal/PlainDate/prototype/monthCode/builtin-calendar-no-observable-calls.js: + default: 'TypeError: Property description must be an object.' + strict mode: 'TypeError: Property description must be an object.' +test/built-ins/Temporal/PlainDate/prototype/monthsInYear/builtin-calendar-no-observable-calls.js: + default: 'TypeError: Property description must be an object.' + strict mode: 'TypeError: Property description must be an object.' test/built-ins/Temporal/PlainDate/prototype/since/argument-string-date-with-utc-offset.js: default: 'RangeError: invalid date string' strict mode: 'RangeError: invalid date string' @@ -997,23 +1139,32 @@ test/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/argument-string-date default: 'RangeError: invalid time string' strict mode: 'RangeError: invalid time string' test/built-ins/Temporal/PlainDate/prototype/toString/order-of-operations.js: - default: 'Test262Error: Expected [] and [get options.calendarName, get options.calendarName.toString, call options.calendarName.toString, get this.calendar[Symbol.toPrimitive], get this.calendar.toString, call this.calendar.toString] to have the same contents. order of operations' - strict mode: 'Test262Error: Expected [] and [get options.calendarName, get options.calendarName.toString, call options.calendarName.toString, get this.calendar[Symbol.toPrimitive], get this.calendar.toString, call this.calendar.toString] to have the same contents. order of operations' + default: 'Test262Error: Expected [] and [get options.calendarName, get options.calendarName.toString, call options.calendarName.toString, get this.calendar.id] to have the same contents. order of operations' + strict mode: 'Test262Error: Expected [] and [get options.calendarName, get options.calendarName.toString, call options.calendarName.toString, get this.calendar.id] to have the same contents. order of operations' test/built-ins/Temporal/PlainDate/prototype/until/argument-string-date-with-utc-offset.js: default: 'RangeError: invalid date string' strict mode: 'RangeError: invalid date string' test/built-ins/Temporal/PlainDate/prototype/until/roundingincrement-out-of-range.js: default: 'Test262Error: Expected a RangeError to be thrown but no exception was thrown at all' strict mode: 'Test262Error: Expected a RangeError to be thrown but no exception was thrown at all' +test/built-ins/Temporal/PlainDate/prototype/weekOfYear/builtin-calendar-no-observable-calls.js: + default: 'TypeError: Property description must be an object.' + strict mode: 'TypeError: Property description must be an object.' test/built-ins/Temporal/PlainDate/prototype/with/order-of-operations.js: default: 'Test262Error: Expected [get fields.calendar, get fields.timeZone, get fields.day, get fields.day.valueOf, call fields.day.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.year, get fields.year.valueOf, call fields.year.valueOf, get options.overflow, get options.overflow.toString, call options.overflow.toString] and [get fields.calendar, get fields.timeZone, get this.calendar.fields, call this.calendar.fields, get this.calendar.day, call this.calendar.day, get this.calendar.month, call this.calendar.month, get this.calendar.monthCode, call this.calendar.monthCode, get this.calendar.year, call this.calendar.year, get fields.day, get fields.day.valueOf, call fields.day.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.year, get fields.year.valueOf, call fields.year.valueOf, get this.calendar.mergeFields, call this.calendar.mergeFields, get this.calendar.dateFromFields, call this.calendar.dateFromFields, get options.overflow, get options.overflow.toString, call options.overflow.toString] to have the same contents. order of operations' strict mode: 'Test262Error: Expected [get fields.calendar, get fields.timeZone, get fields.day, get fields.day.valueOf, call fields.day.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.year, get fields.year.valueOf, call fields.year.valueOf, get options.overflow, get options.overflow.toString, call options.overflow.toString] and [get fields.calendar, get fields.timeZone, get this.calendar.fields, call this.calendar.fields, get this.calendar.day, call this.calendar.day, get this.calendar.month, call this.calendar.month, get this.calendar.monthCode, call this.calendar.monthCode, get this.calendar.year, call this.calendar.year, get fields.day, get fields.day.valueOf, call fields.day.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.year, get fields.year.valueOf, call fields.year.valueOf, get this.calendar.mergeFields, call this.calendar.mergeFields, get this.calendar.dateFromFields, call this.calendar.dateFromFields, get options.overflow, get options.overflow.toString, call options.overflow.toString] to have the same contents. order of operations' +test/built-ins/Temporal/PlainDate/prototype/year/builtin-calendar-no-observable-calls.js: + default: 'TypeError: Property description must be an object.' + strict mode: 'TypeError: Property description must be an object.' test/built-ins/Temporal/PlainDate/prototype/yearOfWeek/basic.js: default: 'Test262Error: 1975-12-29 should be in yearOfWeek 1976 Expected SameValue(«undefined», «1976») to be true' strict mode: 'Test262Error: 1975-12-29 should be in yearOfWeek 1976 Expected SameValue(«undefined», «1976») to be true' test/built-ins/Temporal/PlainDate/prototype/yearOfWeek/branding.js: default: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(Temporal.PlainDate.prototype, \"yearOfWeek\").get')" strict mode: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(Temporal.PlainDate.prototype, \"yearOfWeek\").get')" +test/built-ins/Temporal/PlainDate/prototype/yearOfWeek/builtin-calendar-no-observable-calls.js: + default: 'TypeError: Property description must be an object.' + strict mode: 'TypeError: Property description must be an object.' test/built-ins/Temporal/PlainDate/prototype/yearOfWeek/custom.js: default: 'Test262Error: result Expected SameValue(«undefined», «7») to be true' strict mode: 'Test262Error: result Expected SameValue(«undefined», «7») to be true' @@ -1023,12 +1174,24 @@ test/built-ins/Temporal/PlainDate/prototype/yearOfWeek/prop-desc.js: test/built-ins/Temporal/PlainDate/prototype/yearOfWeek/validate-calendar-value.js: default: 'Test262Error: undefined undefined not converted to integer Expected a TypeError to be thrown but no exception was thrown at all' strict mode: 'Test262Error: undefined undefined not converted to integer Expected a TypeError to be thrown but no exception was thrown at all' +test/built-ins/Temporal/PlainDateTime/calendar-case-insensitive.js: + default: 'Test262Error: Calendar is case-insensitive Expected SameValue(«undefined», «iso8601») to be true' + strict mode: 'Test262Error: Calendar is case-insensitive Expected SameValue(«undefined», «iso8601») to be true' +test/built-ins/Temporal/PlainDateTime/calendar-string.js: + default: 'Test262Error: Calendar created from string "iso8601" Expected SameValue(«iso8601», «iso8601») to be true' + strict mode: 'Test262Error: Calendar created from string "iso8601" Expected SameValue(«iso8601», «iso8601») to be true' +test/built-ins/Temporal/PlainDateTime/calendar-undefined.js: + default: 'Test262Error: Expected SameValue(«undefined», «iso8601») to be true' + strict mode: 'Test262Error: Expected SameValue(«undefined», «iso8601») to be true' test/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-case-insensitive.js: default: 'RangeError: invalid calendar ID' strict mode: 'RangeError: invalid calendar ID' test/built-ins/Temporal/PlainDateTime/compare/argument-string-date-with-utc-offset.js: default: 'RangeError: invalid date string' strict mode: 'RangeError: invalid date string' +test/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-string.js: + default: 'Test262Error: calendar slot stores a string Expected SameValue(«iso8601», «iso8601») to be true' + strict mode: 'Test262Error: calendar slot stores a string Expected SameValue(«iso8601», «iso8601») to be true' test/built-ins/Temporal/PlainDateTime/from/argument-string-date-with-utc-offset.js: default: 'RangeError: invalid date string' strict mode: 'RangeError: invalid date string' @@ -1038,9 +1201,66 @@ test/built-ins/Temporal/PlainDateTime/from/order-of-operations.js: test/built-ins/Temporal/PlainDateTime/prototype/add/order-of-operations.js: default: 'Test262Error: Expected [get fields.days, get fields.days.valueOf, call fields.days.valueOf, get fields.hours, get fields.hours.valueOf, call fields.hours.valueOf, get fields.microseconds, get fields.microseconds.valueOf, call fields.microseconds.valueOf, get fields.milliseconds, get fields.milliseconds.valueOf, call fields.milliseconds.valueOf, get fields.minutes, get fields.minutes.valueOf, call fields.minutes.valueOf, get fields.months, get fields.months.valueOf, call fields.months.valueOf, get fields.nanoseconds, get fields.nanoseconds.valueOf, call fields.nanoseconds.valueOf, get fields.seconds, get fields.seconds.valueOf, call fields.seconds.valueOf, get fields.weeks, get fields.weeks.valueOf, call fields.weeks.valueOf, get fields.years, get fields.years.valueOf, call fields.years.valueOf, get options.overflow, get options.overflow.toString, call options.overflow.toString] and [get fields.days, get fields.days.valueOf, call fields.days.valueOf, get fields.hours, get fields.hours.valueOf, call fields.hours.valueOf, get fields.microseconds, get fields.microseconds.valueOf, call fields.microseconds.valueOf, get fields.milliseconds, get fields.milliseconds.valueOf, call fields.milliseconds.valueOf, get fields.minutes, get fields.minutes.valueOf, call fields.minutes.valueOf, get fields.months, get fields.months.valueOf, call fields.months.valueOf, get fields.nanoseconds, get fields.nanoseconds.valueOf, call fields.nanoseconds.valueOf, get fields.seconds, get fields.seconds.valueOf, call fields.seconds.valueOf, get fields.weeks, get fields.weeks.valueOf, call fields.weeks.valueOf, get fields.years, get fields.years.valueOf, call fields.years.valueOf, get this.calendar.dateAdd, call this.calendar.dateAdd, get options.overflow, get options.overflow.toString, call options.overflow.toString] to have the same contents. order of operations' strict mode: 'Test262Error: Expected [get fields.days, get fields.days.valueOf, call fields.days.valueOf, get fields.hours, get fields.hours.valueOf, call fields.hours.valueOf, get fields.microseconds, get fields.microseconds.valueOf, call fields.microseconds.valueOf, get fields.milliseconds, get fields.milliseconds.valueOf, call fields.milliseconds.valueOf, get fields.minutes, get fields.minutes.valueOf, call fields.minutes.valueOf, get fields.months, get fields.months.valueOf, call fields.months.valueOf, get fields.nanoseconds, get fields.nanoseconds.valueOf, call fields.nanoseconds.valueOf, get fields.seconds, get fields.seconds.valueOf, call fields.seconds.valueOf, get fields.weeks, get fields.weeks.valueOf, call fields.weeks.valueOf, get fields.years, get fields.years.valueOf, call fields.years.valueOf, get options.overflow, get options.overflow.toString, call options.overflow.toString] and [get fields.days, get fields.days.valueOf, call fields.days.valueOf, get fields.hours, get fields.hours.valueOf, call fields.hours.valueOf, get fields.microseconds, get fields.microseconds.valueOf, call fields.microseconds.valueOf, get fields.milliseconds, get fields.milliseconds.valueOf, call fields.milliseconds.valueOf, get fields.minutes, get fields.minutes.valueOf, call fields.minutes.valueOf, get fields.months, get fields.months.valueOf, call fields.months.valueOf, get fields.nanoseconds, get fields.nanoseconds.valueOf, call fields.nanoseconds.valueOf, get fields.seconds, get fields.seconds.valueOf, call fields.seconds.valueOf, get fields.weeks, get fields.weeks.valueOf, call fields.weeks.valueOf, get fields.years, get fields.years.valueOf, call fields.years.valueOf, get this.calendar.dateAdd, call this.calendar.dateAdd, get options.overflow, get options.overflow.toString, call options.overflow.toString] to have the same contents. order of operations' +test/built-ins/Temporal/PlainDateTime/prototype/calendarId/branding.js: + default: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(Temporal.PlainDateTime.prototype, \"calendarId\").get')" + strict mode: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(Temporal.PlainDateTime.prototype, \"calendarId\").get')" +test/built-ins/Temporal/PlainDateTime/prototype/calendarId/prop-desc.js: + default: "TypeError: undefined is not an object (evaluating 'descriptor.get')" + strict mode: "TypeError: undefined is not an object (evaluating 'descriptor.get')" +test/built-ins/Temporal/PlainDateTime/prototype/day/builtin-calendar-no-observable-calls.js: + default: 'TypeError: Property description must be an object.' + strict mode: 'TypeError: Property description must be an object.' +test/built-ins/Temporal/PlainDateTime/prototype/dayOfWeek/builtin-calendar-no-observable-calls.js: + default: 'TypeError: Property description must be an object.' + strict mode: 'TypeError: Property description must be an object.' +test/built-ins/Temporal/PlainDateTime/prototype/dayOfYear/builtin-calendar-no-observable-calls.js: + default: 'TypeError: Property description must be an object.' + strict mode: 'TypeError: Property description must be an object.' +test/built-ins/Temporal/PlainDateTime/prototype/daysInMonth/builtin-calendar-no-observable-calls.js: + default: 'TypeError: Property description must be an object.' + strict mode: 'TypeError: Property description must be an object.' +test/built-ins/Temporal/PlainDateTime/prototype/daysInWeek/builtin-calendar-no-observable-calls.js: + default: 'TypeError: Property description must be an object.' + strict mode: 'TypeError: Property description must be an object.' +test/built-ins/Temporal/PlainDateTime/prototype/daysInYear/builtin-calendar-no-observable-calls.js: + default: 'TypeError: Property description must be an object.' + strict mode: 'TypeError: Property description must be an object.' test/built-ins/Temporal/PlainDateTime/prototype/equals/argument-string-date-with-utc-offset.js: default: 'RangeError: invalid date string' strict mode: 'RangeError: invalid date string' +test/built-ins/Temporal/PlainDateTime/prototype/getCalendar/branding.js: + default: 'Test262Error: Expected SameValue(«undefined», «function») to be true' + strict mode: 'Test262Error: Expected SameValue(«undefined», «function») to be true' +test/built-ins/Temporal/PlainDateTime/prototype/getCalendar/builtin.js: + default: 'Test262Error: Built-in objects must be extensible. Expected SameValue(«false», «true») to be true' + strict mode: 'Test262Error: Built-in objects must be extensible. Expected SameValue(«false», «true») to be true' +test/built-ins/Temporal/PlainDateTime/prototype/getCalendar/length.js: + default: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(obj, name)')" + strict mode: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(obj, name)')" +test/built-ins/Temporal/PlainDateTime/prototype/getCalendar/name.js: + default: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(obj, name)')" + strict mode: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(obj, name)')" +test/built-ins/Temporal/PlainDateTime/prototype/getCalendar/not-a-constructor.js: + default: 'Test262Error: isConstructor invoked with a non-function value' + strict mode: 'Test262Error: isConstructor invoked with a non-function value' +test/built-ins/Temporal/PlainDateTime/prototype/getCalendar/prop-desc.js: + default: 'Test262Error: `typeof PlainDateTime.prototype.getCalendar` is `function` Expected SameValue(«undefined», «function») to be true' + strict mode: 'Test262Error: `typeof PlainDateTime.prototype.getCalendar` is `function` Expected SameValue(«undefined», «function») to be true' +test/built-ins/Temporal/PlainDateTime/prototype/getISOFields/field-names.js: + default: 'Test262Error: calendar result Expected SameValue(«iso8601», «iso8601») to be true' + strict mode: 'Test262Error: calendar result Expected SameValue(«iso8601», «iso8601») to be true' +test/built-ins/Temporal/PlainDateTime/prototype/inLeapYear/builtin-calendar-no-observable-calls.js: + default: 'TypeError: Property description must be an object.' + strict mode: 'TypeError: Property description must be an object.' +test/built-ins/Temporal/PlainDateTime/prototype/month/builtin-calendar-no-observable-calls.js: + default: 'TypeError: Property description must be an object.' + strict mode: 'TypeError: Property description must be an object.' +test/built-ins/Temporal/PlainDateTime/prototype/monthCode/builtin-calendar-no-observable-calls.js: + default: 'TypeError: Property description must be an object.' + strict mode: 'TypeError: Property description must be an object.' +test/built-ins/Temporal/PlainDateTime/prototype/monthsInYear/builtin-calendar-no-observable-calls.js: + default: 'TypeError: Property description must be an object.' + strict mode: 'TypeError: Property description must be an object.' test/built-ins/Temporal/PlainDateTime/prototype/subtract/order-of-operations.js: default: 'Test262Error: Expected [get fields.days, get fields.days.valueOf, call fields.days.valueOf, get fields.hours, get fields.hours.valueOf, call fields.hours.valueOf, get fields.microseconds, get fields.microseconds.valueOf, call fields.microseconds.valueOf, get fields.milliseconds, get fields.milliseconds.valueOf, call fields.milliseconds.valueOf, get fields.minutes, get fields.minutes.valueOf, call fields.minutes.valueOf, get fields.months, get fields.months.valueOf, call fields.months.valueOf, get fields.nanoseconds, get fields.nanoseconds.valueOf, call fields.nanoseconds.valueOf, get fields.seconds, get fields.seconds.valueOf, call fields.seconds.valueOf, get fields.weeks, get fields.weeks.valueOf, call fields.weeks.valueOf, get fields.years, get fields.years.valueOf, call fields.years.valueOf, get options.overflow, get options.overflow.toString, call options.overflow.toString] and [get fields.days, get fields.days.valueOf, call fields.days.valueOf, get fields.hours, get fields.hours.valueOf, call fields.hours.valueOf, get fields.microseconds, get fields.microseconds.valueOf, call fields.microseconds.valueOf, get fields.milliseconds, get fields.milliseconds.valueOf, call fields.milliseconds.valueOf, get fields.minutes, get fields.minutes.valueOf, call fields.minutes.valueOf, get fields.months, get fields.months.valueOf, call fields.months.valueOf, get fields.nanoseconds, get fields.nanoseconds.valueOf, call fields.nanoseconds.valueOf, get fields.seconds, get fields.seconds.valueOf, call fields.seconds.valueOf, get fields.weeks, get fields.weeks.valueOf, call fields.weeks.valueOf, get fields.years, get fields.years.valueOf, call fields.years.valueOf, get this.calendar.dateAdd, call this.calendar.dateAdd, get options.overflow, get options.overflow.toString, call options.overflow.toString] to have the same contents. order of operations' strict mode: 'Test262Error: Expected [get fields.days, get fields.days.valueOf, call fields.days.valueOf, get fields.hours, get fields.hours.valueOf, call fields.hours.valueOf, get fields.microseconds, get fields.microseconds.valueOf, call fields.microseconds.valueOf, get fields.milliseconds, get fields.milliseconds.valueOf, call fields.milliseconds.valueOf, get fields.minutes, get fields.minutes.valueOf, call fields.minutes.valueOf, get fields.months, get fields.months.valueOf, call fields.months.valueOf, get fields.nanoseconds, get fields.nanoseconds.valueOf, call fields.nanoseconds.valueOf, get fields.seconds, get fields.seconds.valueOf, call fields.seconds.valueOf, get fields.weeks, get fields.weeks.valueOf, call fields.weeks.valueOf, get fields.years, get fields.years.valueOf, call fields.years.valueOf, get options.overflow, get options.overflow.toString, call options.overflow.toString] and [get fields.days, get fields.days.valueOf, call fields.days.valueOf, get fields.hours, get fields.hours.valueOf, call fields.hours.valueOf, get fields.microseconds, get fields.microseconds.valueOf, call fields.microseconds.valueOf, get fields.milliseconds, get fields.milliseconds.valueOf, call fields.milliseconds.valueOf, get fields.minutes, get fields.minutes.valueOf, call fields.minutes.valueOf, get fields.months, get fields.months.valueOf, call fields.months.valueOf, get fields.nanoseconds, get fields.nanoseconds.valueOf, call fields.nanoseconds.valueOf, get fields.seconds, get fields.seconds.valueOf, call fields.seconds.valueOf, get fields.weeks, get fields.weeks.valueOf, call fields.weeks.valueOf, get fields.years, get fields.years.valueOf, call fields.years.valueOf, get this.calendar.dateAdd, call this.calendar.dateAdd, get options.overflow, get options.overflow.toString, call options.overflow.toString] to have the same contents. order of operations' @@ -1048,11 +1268,14 @@ test/built-ins/Temporal/PlainDateTime/prototype/toString/fractionalseconddigits- default: 'Test262Error: fractionalSecondDigits -0.6 floors to -1 and is out of range Expected a RangeError to be thrown but no exception was thrown at all' strict mode: 'Test262Error: fractionalSecondDigits -0.6 floors to -1 and is out of range Expected a RangeError to be thrown but no exception was thrown at all' test/built-ins/Temporal/PlainDateTime/prototype/toString/order-of-operations.js: - default: 'Test262Error: Expected [get options.smallestUnit, get options.smallestUnit.toString, call options.smallestUnit.toString, get options.roundingMode, get options.roundingMode.toString, call options.roundingMode.toString] and [get options.calendarName, get options.calendarName.toString, call options.calendarName.toString, get options.fractionalSecondDigits, get options.fractionalSecondDigits.toString, call options.fractionalSecondDigits.toString, get options.roundingMode, get options.roundingMode.toString, call options.roundingMode.toString, get options.smallestUnit, get options.smallestUnit.toString, call options.smallestUnit.toString, get this.calendar[Symbol.toPrimitive], get this.calendar.toString, call this.calendar.toString] to have the same contents. order of operations' - strict mode: 'Test262Error: Expected [get options.smallestUnit, get options.smallestUnit.toString, call options.smallestUnit.toString, get options.roundingMode, get options.roundingMode.toString, call options.roundingMode.toString] and [get options.calendarName, get options.calendarName.toString, call options.calendarName.toString, get options.fractionalSecondDigits, get options.fractionalSecondDigits.toString, call options.fractionalSecondDigits.toString, get options.roundingMode, get options.roundingMode.toString, call options.roundingMode.toString, get options.smallestUnit, get options.smallestUnit.toString, call options.smallestUnit.toString, get this.calendar[Symbol.toPrimitive], get this.calendar.toString, call this.calendar.toString] to have the same contents. order of operations' + default: 'Test262Error: Expected [get options.smallestUnit, get options.smallestUnit.toString, call options.smallestUnit.toString, get options.roundingMode, get options.roundingMode.toString, call options.roundingMode.toString] and [get options.calendarName, get options.calendarName.toString, call options.calendarName.toString, get options.fractionalSecondDigits, get options.fractionalSecondDigits.toString, call options.fractionalSecondDigits.toString, get options.roundingMode, get options.roundingMode.toString, call options.roundingMode.toString, get options.smallestUnit, get options.smallestUnit.toString, call options.smallestUnit.toString, get this.calendar.id] to have the same contents. order of operations' + strict mode: 'Test262Error: Expected [get options.smallestUnit, get options.smallestUnit.toString, call options.smallestUnit.toString, get options.roundingMode, get options.roundingMode.toString, call options.roundingMode.toString] and [get options.calendarName, get options.calendarName.toString, call options.calendarName.toString, get options.fractionalSecondDigits, get options.fractionalSecondDigits.toString, call options.fractionalSecondDigits.toString, get options.roundingMode, get options.roundingMode.toString, call options.roundingMode.toString, get options.smallestUnit, get options.smallestUnit.toString, call options.smallestUnit.toString, get this.calendar.id] to have the same contents. order of operations' +test/built-ins/Temporal/PlainDateTime/prototype/weekOfYear/builtin-calendar-no-observable-calls.js: + default: 'TypeError: Property description must be an object.' + strict mode: 'TypeError: Property description must be an object.' test/built-ins/Temporal/PlainDateTime/prototype/with/order-of-operations.js: - default: 'Test262Error: Expected [get fields.calendar, get fields.timeZone, get fields.day, get fields.day.valueOf, call fields.day.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.year, get fields.year.valueOf, call fields.year.valueOf, get options.overflow, get options.overflow.toString, call options.overflow.toString, 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.nanosecond, get fields.nanosecond.valueOf, call fields.nanosecond.valueOf, get fields.second, get fields.second.valueOf, call fields.second.valueOf] and [get fields.calendar, get fields.timeZone, get this.calendar.fields, call this.calendar.fields, get this.calendar.day, call this.calendar.day, get this.calendar.month, call this.calendar.month, get this.calendar.monthCode, call this.calendar.monthCode, get this.calendar.year, call this.calendar.year, 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 this.calendar.mergeFields, call this.calendar.mergeFields, get options.overflow, get options.overflow.toString, call options.overflow.toString, get this.calendar.dateFromFields, call this.calendar.dateFromFields, get options.overflow, get options.overflow.toString, call options.overflow.toString] to have the same contents. order of operations' - strict mode: 'Test262Error: Expected [get fields.calendar, get fields.timeZone, get fields.day, get fields.day.valueOf, call fields.day.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.year, get fields.year.valueOf, call fields.year.valueOf, get options.overflow, get options.overflow.toString, call options.overflow.toString, 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.nanosecond, get fields.nanosecond.valueOf, call fields.nanosecond.valueOf, get fields.second, get fields.second.valueOf, call fields.second.valueOf] and [get fields.calendar, get fields.timeZone, get this.calendar.fields, call this.calendar.fields, get this.calendar.day, call this.calendar.day, get this.calendar.month, call this.calendar.month, get this.calendar.monthCode, call this.calendar.monthCode, get this.calendar.year, call this.calendar.year, 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 this.calendar.mergeFields, call this.calendar.mergeFields, get options.overflow, get options.overflow.toString, call options.overflow.toString, get this.calendar.dateFromFields, call this.calendar.dateFromFields, get options.overflow, get options.overflow.toString, call options.overflow.toString] to have the same contents. order of operations' + default: 'Test262Error: Expected [get fields.calendar, get fields.timeZone, get fields.day, get fields.day.valueOf, call fields.day.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.year, get fields.year.valueOf, call fields.year.valueOf, get options.overflow, get options.overflow.toString, call options.overflow.toString, 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.nanosecond, get fields.nanosecond.valueOf, call fields.nanosecond.valueOf, get fields.second, get fields.second.valueOf, call fields.second.valueOf] and [get fields.calendar, get fields.timeZone, get this.calendar.fields, call this.calendar.fields, get this.calendar.day, call this.calendar.day, get this.hour, get this.microsecond, get this.millisecond, get this.minute, get this.calendar.month, call this.calendar.month, get this.calendar.monthCode, call this.calendar.monthCode, get this.nanosecond, get this.second, get this.calendar.year, call this.calendar.year, 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 this.calendar.mergeFields, call this.calendar.mergeFields, get options.overflow, get options.overflow.toString, call options.overflow.toString, get this.calendar.dateFromFields, call this.calendar.dateFromFields, get options.overflow, get options.overflow.toString, call options.overflow.toString] to have the same contents. order of operations' + strict mode: 'Test262Error: Expected [get fields.calendar, get fields.timeZone, get fields.day, get fields.day.valueOf, call fields.day.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.year, get fields.year.valueOf, call fields.year.valueOf, get options.overflow, get options.overflow.toString, call options.overflow.toString, 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.nanosecond, get fields.nanosecond.valueOf, call fields.nanosecond.valueOf, get fields.second, get fields.second.valueOf, call fields.second.valueOf] and [get fields.calendar, get fields.timeZone, get this.calendar.fields, call this.calendar.fields, get this.calendar.day, call this.calendar.day, get this.hour, get this.microsecond, get this.millisecond, get this.minute, get this.calendar.month, call this.calendar.month, get this.calendar.monthCode, call this.calendar.monthCode, get this.nanosecond, get this.second, get this.calendar.year, call this.calendar.year, 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 this.calendar.mergeFields, call this.calendar.mergeFields, get options.overflow, get options.overflow.toString, call options.overflow.toString, get this.calendar.dateFromFields, call this.calendar.dateFromFields, get options.overflow, get options.overflow.toString, call options.overflow.toString] to have the same contents. order of operations' test/built-ins/Temporal/PlainDateTime/prototype/with/overflow-wrong-type.js: default: 'Test262Error: Expected [get overflow.toString, call overflow.toString] and [get overflow.toString, call overflow.toString, get overflow.toString, call overflow.toString] to have the same contents. order of operations' strict mode: 'Test262Error: Expected [get overflow.toString, call overflow.toString] and [get overflow.toString, call overflow.toString, get overflow.toString, call overflow.toString] to have the same contents. order of operations' @@ -1062,12 +1285,18 @@ test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-string-da test/built-ins/Temporal/PlainDateTime/prototype/withPlainTime/argument-string-date-with-utc-offset.js: default: 'RangeError: invalid time string' strict mode: 'RangeError: invalid time string' +test/built-ins/Temporal/PlainDateTime/prototype/year/builtin-calendar-no-observable-calls.js: + default: 'TypeError: Property description must be an object.' + strict mode: 'TypeError: Property description must be an object.' test/built-ins/Temporal/PlainDateTime/prototype/yearOfWeek/basic.js: default: 'Test262Error: check yearOfWeek information Expected SameValue(«undefined», «1976») to be true' strict mode: 'Test262Error: check yearOfWeek information Expected SameValue(«undefined», «1976») to be true' test/built-ins/Temporal/PlainDateTime/prototype/yearOfWeek/branding.js: default: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(Temporal.PlainDateTime.prototype, \"yearOfWeek\").get')" strict mode: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(Temporal.PlainDateTime.prototype, \"yearOfWeek\").get')" +test/built-ins/Temporal/PlainDateTime/prototype/yearOfWeek/builtin-calendar-no-observable-calls.js: + default: 'TypeError: Property description must be an object.' + strict mode: 'TypeError: Property description must be an object.' test/built-ins/Temporal/PlainDateTime/prototype/yearOfWeek/custom.js: default: 'Test262Error: result Expected SameValue(«undefined», «7») to be true' strict mode: 'Test262Error: result Expected SameValue(«undefined», «7») to be true' @@ -1083,6 +1312,9 @@ test/built-ins/Temporal/PlainTime/compare/argument-string-date-with-utc-offset.j test/built-ins/Temporal/PlainTime/from/argument-string-date-with-utc-offset.js: default: 'RangeError: invalid time string' strict mode: 'RangeError: invalid time string' +test/built-ins/Temporal/PlainTime/from/order-of-operations.js: + default: 'Test262Error: Expected [get options.overflow, get options.overflow.toString, call options.overflow.toString, get fields.calendar, get fields.calendar.toString, call fields.calendar.toString, 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.nanosecond, get fields.nanosecond.valueOf, call fields.nanosecond.valueOf, get fields.second, get fields.second.valueOf, call fields.second.valueOf] and [get options.overflow, get options.overflow.toString, call options.overflow.toString, 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.nanosecond, get fields.nanosecond.valueOf, call fields.nanosecond.valueOf, get fields.second, get fields.second.valueOf, call fields.second.valueOf] to have the same contents. order of operations' + strict mode: 'Test262Error: Expected [get options.overflow, get options.overflow.toString, call options.overflow.toString, get fields.calendar, get fields.calendar.toString, call fields.calendar.toString, 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.nanosecond, get fields.nanosecond.valueOf, call fields.nanosecond.valueOf, get fields.second, get fields.second.valueOf, call fields.second.valueOf] and [get options.overflow, get options.overflow.toString, call options.overflow.toString, 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.nanosecond, get fields.nanosecond.valueOf, call fields.nanosecond.valueOf, get fields.second, get fields.second.valueOf, call fields.second.valueOf] to have the same contents. order of operations' test/built-ins/Temporal/PlainTime/prototype/add/precision-exact-mathematical-values-1.js: default: 'Test262Error: microsecond result Expected SameValue(«992», «993») to be true' strict mode: 'Test262Error: microsecond result Expected SameValue(«992», «993») to be true' @@ -1095,12 +1327,15 @@ test/built-ins/Temporal/PlainTime/prototype/add/precision-exact-mathematical-val test/built-ins/Temporal/PlainTime/prototype/equals/argument-string-date-with-utc-offset.js: default: 'RangeError: invalid time string' strict mode: 'RangeError: invalid time string' +test/built-ins/Temporal/PlainTime/prototype/getISOFields/field-traversal-order.js: + default: 'Test262Error: Expected [calendar, isoHour, isoMicrosecond, isoMillisecond, isoMinute, isoNanosecond, isoSecond] and [isoHour, isoMicrosecond, isoMillisecond, isoMinute, isoNanosecond, isoSecond] to have the same contents. ' + strict mode: 'Test262Error: Expected [calendar, isoHour, isoMicrosecond, isoMillisecond, isoMinute, isoNanosecond, isoSecond] and [isoHour, isoMicrosecond, isoMillisecond, isoMinute, isoNanosecond, isoSecond] to have the same contents. ' test/built-ins/Temporal/PlainTime/prototype/since/argument-string-date-with-utc-offset.js: default: 'RangeError: invalid time string' strict mode: 'RangeError: invalid time string' test/built-ins/Temporal/PlainTime/prototype/since/order-of-operations.js: - default: 'Test262Error: Expected [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, 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] and [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, ownKeys options, getOwnPropertyDescriptor options.roundingIncrement, get options.roundingIncrement, getOwnPropertyDescriptor options.roundingMode, get options.roundingMode, getOwnPropertyDescriptor options.largestUnit, get options.largestUnit, getOwnPropertyDescriptor options.smallestUnit, get options.smallestUnit, getOwnPropertyDescriptor options.additional, get options.additional, get options.largestUnit.toString, call options.largestUnit.toString, get options.roundingIncrement.valueOf, call options.roundingIncrement.valueOf, get options.roundingMode.toString, call options.roundingMode.toString, get options.smallestUnit.toString, call options.smallestUnit.toString] to have the same contents. order of operations' - strict mode: 'Test262Error: Expected [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, 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] and [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, ownKeys options, getOwnPropertyDescriptor options.roundingIncrement, get options.roundingIncrement, getOwnPropertyDescriptor options.roundingMode, get options.roundingMode, getOwnPropertyDescriptor options.largestUnit, get options.largestUnit, getOwnPropertyDescriptor options.smallestUnit, get options.smallestUnit, getOwnPropertyDescriptor options.additional, get options.additional, get options.largestUnit.toString, call options.largestUnit.toString, get options.roundingIncrement.valueOf, call options.roundingIncrement.valueOf, get options.roundingMode.toString, call options.roundingMode.toString, get options.smallestUnit.toString, call options.smallestUnit.toString] to have the same contents. order of operations' + default: 'Test262Error: Expected [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, 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] and [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, ownKeys options, getOwnPropertyDescriptor options.roundingIncrement, get options.roundingIncrement, getOwnPropertyDescriptor options.roundingMode, get options.roundingMode, getOwnPropertyDescriptor options.largestUnit, get options.largestUnit, getOwnPropertyDescriptor options.smallestUnit, get options.smallestUnit, getOwnPropertyDescriptor options.additional, get options.additional, get options.largestUnit.toString, call options.largestUnit.toString, get options.roundingIncrement.valueOf, call options.roundingIncrement.valueOf, get options.roundingMode.toString, call options.roundingMode.toString, get options.smallestUnit.toString, call options.smallestUnit.toString] to have the same contents. order of operations' + strict mode: 'Test262Error: Expected [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, 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] and [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, ownKeys options, getOwnPropertyDescriptor options.roundingIncrement, get options.roundingIncrement, getOwnPropertyDescriptor options.roundingMode, get options.roundingMode, getOwnPropertyDescriptor options.largestUnit, get options.largestUnit, getOwnPropertyDescriptor options.smallestUnit, get options.smallestUnit, getOwnPropertyDescriptor options.additional, get options.additional, get options.largestUnit.toString, call options.largestUnit.toString, get options.roundingIncrement.valueOf, call options.roundingIncrement.valueOf, get options.roundingMode.toString, call options.roundingMode.toString, get options.smallestUnit.toString, call options.smallestUnit.toString] to have the same contents. order of operations' test/built-ins/Temporal/PlainTime/prototype/subtract/precision-exact-mathematical-values-1.js: default: 'Test262Error: microsecond result Expected SameValue(«992», «993») to be true' strict mode: 'Test262Error: microsecond result Expected SameValue(«992», «993») to be true' @@ -1123,8 +1358,8 @@ test/built-ins/Temporal/PlainTime/prototype/until/argument-string-date-with-utc- default: 'RangeError: invalid time string' strict mode: 'RangeError: invalid time string' test/built-ins/Temporal/PlainTime/prototype/until/order-of-operations.js: - default: 'Test262Error: Expected [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, 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] and [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, ownKeys options, getOwnPropertyDescriptor options.roundingIncrement, get options.roundingIncrement, getOwnPropertyDescriptor options.roundingMode, get options.roundingMode, getOwnPropertyDescriptor options.largestUnit, get options.largestUnit, getOwnPropertyDescriptor options.smallestUnit, get options.smallestUnit, getOwnPropertyDescriptor options.additional, get options.additional, get options.largestUnit.toString, call options.largestUnit.toString, get options.roundingIncrement.valueOf, call options.roundingIncrement.valueOf, get options.roundingMode.toString, call options.roundingMode.toString, get options.smallestUnit.toString, call options.smallestUnit.toString] to have the same contents. order of operations' - strict mode: 'Test262Error: Expected [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, 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] and [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, ownKeys options, getOwnPropertyDescriptor options.roundingIncrement, get options.roundingIncrement, getOwnPropertyDescriptor options.roundingMode, get options.roundingMode, getOwnPropertyDescriptor options.largestUnit, get options.largestUnit, getOwnPropertyDescriptor options.smallestUnit, get options.smallestUnit, getOwnPropertyDescriptor options.additional, get options.additional, get options.largestUnit.toString, call options.largestUnit.toString, get options.roundingIncrement.valueOf, call options.roundingIncrement.valueOf, get options.roundingMode.toString, call options.roundingMode.toString, get options.smallestUnit.toString, call options.smallestUnit.toString] to have the same contents. order of operations' + default: 'Test262Error: Expected [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, 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] and [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, ownKeys options, getOwnPropertyDescriptor options.roundingIncrement, get options.roundingIncrement, getOwnPropertyDescriptor options.roundingMode, get options.roundingMode, getOwnPropertyDescriptor options.largestUnit, get options.largestUnit, getOwnPropertyDescriptor options.smallestUnit, get options.smallestUnit, getOwnPropertyDescriptor options.additional, get options.additional, get options.largestUnit.toString, call options.largestUnit.toString, get options.roundingIncrement.valueOf, call options.roundingIncrement.valueOf, get options.roundingMode.toString, call options.roundingMode.toString, get options.smallestUnit.toString, call options.smallestUnit.toString] to have the same contents. order of operations' + strict mode: 'Test262Error: Expected [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, 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] and [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, ownKeys options, getOwnPropertyDescriptor options.roundingIncrement, get options.roundingIncrement, getOwnPropertyDescriptor options.roundingMode, get options.roundingMode, getOwnPropertyDescriptor options.largestUnit, get options.largestUnit, getOwnPropertyDescriptor options.smallestUnit, get options.smallestUnit, getOwnPropertyDescriptor options.additional, get options.additional, get options.largestUnit.toString, call options.largestUnit.toString, get options.roundingIncrement.valueOf, call options.roundingIncrement.valueOf, get options.roundingMode.toString, call options.roundingMode.toString, get options.smallestUnit.toString, call options.smallestUnit.toString] to have the same contents. order of operations' test/built-ins/Temporal/PlainTime/prototype/with/order-of-operations.js: default: 'Test262Error: Expected [get fields.calendar, get fields.timeZone, 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.nanosecond, get fields.nanosecond.valueOf, call fields.nanosecond.valueOf, get fields.second, get fields.second.valueOf, call fields.second.valueOf, get options.overflow, get options.overflow.toString, call options.overflow.toString] and [get fields.calendar, get fields.timeZone, get options.overflow, get options.overflow.toString, call options.overflow.toString, 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.nanosecond, get fields.nanosecond.valueOf, call fields.nanosecond.valueOf, get fields.second, get fields.second.valueOf, call fields.second.valueOf] to have the same contents. order of operations' strict mode: 'Test262Error: Expected [get fields.calendar, get fields.timeZone, 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.nanosecond, get fields.nanosecond.valueOf, call fields.nanosecond.valueOf, get fields.second, get fields.second.valueOf, call fields.second.valueOf, get options.overflow, get options.overflow.toString, call options.overflow.toString] and [get fields.calendar, get fields.timeZone, get options.overflow, get options.overflow.toString, call options.overflow.toString, 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.nanosecond, get fields.nanosecond.valueOf, call fields.nanosecond.valueOf, get fields.second, get fields.second.valueOf, call fields.second.valueOf] to have the same contents. order of operations' diff --git a/JSTests/test262/harness/regExpUtils.js b/JSTests/test262/harness/regExpUtils.js index 1612f7f5e1df..677a8cf94208 100644 --- a/JSTests/test262/harness/regExpUtils.js +++ b/JSTests/test262/harness/regExpUtils.js @@ -51,10 +51,10 @@ function printStringCodePoints(string) { function testPropertyEscapes(regExp, string, expression) { if (!regExp.test(string)) { for (const symbol of string) { - const hex = printCodePoint(symbol.codePointAt(0)); + const formatted = printCodePoint(symbol.codePointAt(0)); assert( regExp.test(symbol), - `\`${ expression }\` should match U+${ hex } (\`${ symbol }\`)` + `\`${ expression }\` should match ${ formatted } (\`${ symbol }\`)` ); } } @@ -73,7 +73,7 @@ function testPropertyOfStrings(args) { for (const string of matchStrings) { assert( regExp.test(string), - `\`${ expression }\` should match ${ string } (U+${ printStringCodePoints(string) })` + `\`${ expression }\` should match ${ string } (${ printStringCodePoints(string) })` ); } } @@ -83,7 +83,7 @@ function testPropertyOfStrings(args) { for (const string of nonMatchStrings) { assert( !regExp.test(string), - `\`${ expression }\` should not match ${ string } (U+${ printStringCodePoints(string) })` + `\`${ expression }\` should not match ${ string } (${ printStringCodePoints(string) })` ); } } diff --git a/JSTests/test262/harness/sta.js b/JSTests/test262/harness/sta.js index b249ee454525..c95ed7a264c5 100644 --- a/JSTests/test262/harness/sta.js +++ b/JSTests/test262/harness/sta.js @@ -18,7 +18,7 @@ Test262Error.prototype.toString = function () { return "Test262Error: " + this.message; }; -Test262Error.thrower = (message) => { +Test262Error.thrower = function (message) { throw new Test262Error(message); }; diff --git a/JSTests/test262/harness/temporalHelpers.js b/JSTests/test262/harness/temporalHelpers.js index d79b080ea382..8234ad3de7cf 100644 --- a/JSTests/test262/harness/temporalHelpers.js +++ b/JSTests/test262/harness/temporalHelpers.js @@ -7,6 +7,8 @@ defines: [TemporalHelpers] features: [Symbol.species, Symbol.iterator, Temporal] ---*/ +const ASCII_IDENTIFIER = /^[$_a-zA-Z][$_a-zA-Z0-9]*$/u; + function formatPropertyName(propertyKey, objectName = "") { switch (typeof propertyKey) { case "symbol": @@ -17,12 +19,20 @@ function formatPropertyName(propertyKey, objectName = "") { } else { return `${objectName}[Symbol('${propertyKey.description}')]` } - case "number": - return `${objectName}[${propertyKey}]`; + case "string": + if (propertyKey !== String(Number(propertyKey))) { + if (ASCII_IDENTIFIER.test(propertyKey)) { + return objectName ? `${objectName}.${propertyKey}` : propertyKey; + } + return `${objectName}['${propertyKey.replace(/'/g, "\\'")}']` + } + // fall through default: - return objectName ? `${objectName}.${propertyKey}` : propertyKey; + // integer or string integer-index + return `${objectName}[${propertyKey}]`; } } + const SKIP_SYMBOL = Symbol("Skip"); var TemporalHelpers = { @@ -75,7 +85,7 @@ var TemporalHelpers = { * Shorthand for asserting that each field of a Temporal.PlainDate is equal to * an expected value. (Except the `calendar` property, since callers may want * to assert either object equality with an object they put in there, or the - * result of date.calendar.toString().) + * value of date.calendarId.) */ assertPlainDate(date, year, month, monthCode, day, description = "", era = undefined, eraYear = undefined) { assert(date instanceof Temporal.PlainDate, `${description} instanceof`); @@ -93,7 +103,7 @@ var TemporalHelpers = { * Shorthand for asserting that each field of a Temporal.PlainDateTime is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, - * or the result of datetime.calendar.toString().) + * or the value of datetime.calendarId.) */ assertPlainDateTime(datetime, year, month, monthCode, day, hour, minute, second, millisecond, microsecond, nanosecond, description = "", era = undefined, eraYear = undefined) { assert(datetime instanceof Temporal.PlainDateTime, `${description} instanceof`); @@ -116,13 +126,17 @@ var TemporalHelpers = { * * Shorthand for asserting that two Temporal.PlainDateTimes are of the correct * type, equal according to their equals() methods, and additionally that - * their calendars are the same value. + * their calendar internal slots are the same value. */ assertPlainDateTimesEqual(actual, expected, description = "") { assert(expected instanceof Temporal.PlainDateTime, `${description} expected value should be a Temporal.PlainDateTime`); assert(actual instanceof Temporal.PlainDateTime, `${description} instanceof`); assert(actual.equals(expected), `${description} equals method`); - assert.sameValue(actual.calendar, expected.calendar, `${description} calendar same value`); + assert.sameValue( + actual.getISOFields().calendar, + expected.getISOFields().calendar, + `${description} calendar same value` + ); }, /* @@ -131,7 +145,7 @@ var TemporalHelpers = { * Shorthand for asserting that each field of a Temporal.PlainMonthDay is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, - * or the result of monthDay.calendar.toString().) + * or the value of monthDay.calendarId().) */ assertPlainMonthDay(monthDay, monthCode, day, description = "", referenceISOYear = 1972) { assert(monthDay instanceof Temporal.PlainMonthDay, `${description} instanceof`); @@ -174,7 +188,7 @@ var TemporalHelpers = { * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, - * or the result of yearMonth.calendar.toString().) + * or the value of yearMonth.calendarId.) */ assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); @@ -191,14 +205,18 @@ var TemporalHelpers = { * * Shorthand for asserting that two Temporal.ZonedDateTimes are of the correct * type, equal according to their equals() methods, and additionally that - * their time zones and calendars are the same value. + * their time zones and calendar internal slots are the same value. */ assertZonedDateTimesEqual(actual, expected, description = "") { assert(expected instanceof Temporal.ZonedDateTime, `${description} expected value should be a Temporal.ZonedDateTime`); assert(actual instanceof Temporal.ZonedDateTime, `${description} instanceof`); assert(actual.equals(expected), `${description} equals method`); assert.sameValue(actual.timeZone, expected.timeZone, `${description} time zone same value`); - assert.sameValue(actual.calendar, expected.calendar, `${description} calendar same value`); + assert.sameValue( + actual.getISOFields().calendar, + expected.getISOFields().calendar, + `${description} calendar same value` + ); }, /* @@ -831,6 +849,20 @@ var TemporalHelpers = { super("iso8601"); } + dateFromFields(...args) { + return super.dateFromFields(...args).withCalendar(this); + } + + monthDayFromFields(...args) { + const { isoYear, isoMonth, isoDay } = super.monthDayFromFields(...args).getISOFields(); + return new Temporal.PlainMonthDay(isoMonth, isoDay, this, isoYear); + } + + yearMonthFromFields(...args) { + const { isoYear, isoMonth, isoDay } = super.yearMonthFromFields(...args).getISOFields(); + return new Temporal.PlainYearMonth(isoYear, isoMonth, this, isoDay); + } + toString() { return "fast-path-check"; } @@ -1051,13 +1083,17 @@ var TemporalHelpers = { return "dateadd-plain-date-instance"; } + dateFromFields(...args) { + return super.dateFromFields(...args).withCalendar(this); + } + dateAdd(date, duration, options) { this.dateAddCallCount++; assert(date instanceof Temporal.PlainDate, "dateAdd() should be called with a PlainDate instance"); if (this.dateAddCallCount === 1 && this.specificPlainDate) { assert.sameValue(date, this.specificPlainDate, `dateAdd() should be called first with the specific PlainDate instance ${this.specificPlainDate}`); } - return super.dateAdd(date, duration, options); + return super.dateAdd(date, duration, options).withCalendar(this); } } return new CalendarDateAddPlainDateInstance(); @@ -1437,6 +1473,34 @@ var TemporalHelpers = { * objectName is used in the log. */ calendarObserver(calls, objectName, methodOverrides = {}) { + function removeExtraHasPropertyChecks(objectName, calls) { + // Inserting the tracking calendar into the return values of methods + // that we chain up into the ISO calendar for, causes extra HasProperty + // checks, which we observe. This removes them so that we don't leak + // implementation details of the helper into the test code. + assert.sameValue(calls.pop(), `has ${objectName}.yearOfWeek`); + assert.sameValue(calls.pop(), `has ${objectName}.yearMonthFromFields`); + assert.sameValue(calls.pop(), `has ${objectName}.year`); + assert.sameValue(calls.pop(), `has ${objectName}.weekOfYear`); + assert.sameValue(calls.pop(), `has ${objectName}.monthsInYear`); + assert.sameValue(calls.pop(), `has ${objectName}.monthDayFromFields`); + assert.sameValue(calls.pop(), `has ${objectName}.monthCode`); + assert.sameValue(calls.pop(), `has ${objectName}.month`); + assert.sameValue(calls.pop(), `has ${objectName}.mergeFields`); + assert.sameValue(calls.pop(), `has ${objectName}.inLeapYear`); + assert.sameValue(calls.pop(), `has ${objectName}.id`); + assert.sameValue(calls.pop(), `has ${objectName}.fields`); + assert.sameValue(calls.pop(), `has ${objectName}.daysInYear`); + assert.sameValue(calls.pop(), `has ${objectName}.daysInWeek`); + assert.sameValue(calls.pop(), `has ${objectName}.daysInMonth`); + assert.sameValue(calls.pop(), `has ${objectName}.dayOfYear`); + assert.sameValue(calls.pop(), `has ${objectName}.dayOfWeek`); + assert.sameValue(calls.pop(), `has ${objectName}.day`); + assert.sameValue(calls.pop(), `has ${objectName}.dateUntil`); + assert.sameValue(calls.pop(), `has ${objectName}.dateFromFields`); + assert.sameValue(calls.pop(), `has ${objectName}.dateAdd`); + } + const iso8601 = new Temporal.Calendar("iso8601"); const trackingMethods = { dateFromFields(...args) { @@ -1449,8 +1513,7 @@ var TemporalHelpers = { // Replace the calendar in the result with the call-tracking calendar const {isoYear, isoMonth, isoDay} = originalResult.getISOFields(); const result = new Temporal.PlainDate(isoYear, isoMonth, isoDay, this); - // Remove the HasProperty check resulting from the above constructor call - assert.sameValue(calls.pop(), `has ${objectName}.calendar`); + removeExtraHasPropertyChecks(objectName, calls); return result; }, yearMonthFromFields(...args) { @@ -1463,8 +1526,7 @@ var TemporalHelpers = { // Replace the calendar in the result with the call-tracking calendar const {isoYear, isoMonth, isoDay} = originalResult.getISOFields(); const result = new Temporal.PlainYearMonth(isoYear, isoMonth, this, isoDay); - // Remove the HasProperty check resulting from the above constructor call - assert.sameValue(calls.pop(), `has ${objectName}.calendar`); + removeExtraHasPropertyChecks(objectName, calls); return result; }, monthDayFromFields(...args) { @@ -1477,8 +1539,7 @@ var TemporalHelpers = { // Replace the calendar in the result with the call-tracking calendar const {isoYear, isoMonth, isoDay} = originalResult.getISOFields(); const result = new Temporal.PlainMonthDay(isoMonth, isoDay, this, isoYear); - // Remove the HasProperty check resulting from the above constructor call - assert.sameValue(calls.pop(), `has ${objectName}.calendar`); + removeExtraHasPropertyChecks(objectName, calls); return result; }, dateAdd(...args) { @@ -1490,13 +1551,33 @@ var TemporalHelpers = { const originalResult = iso8601.dateAdd(...args); const {isoYear, isoMonth, isoDay} = originalResult.getISOFields(); const result = new Temporal.PlainDate(isoYear, isoMonth, isoDay, this); - // Remove the HasProperty check resulting from the above constructor call - assert.sameValue(calls.pop(), `has ${objectName}.calendar`); + removeExtraHasPropertyChecks(objectName, calls); return result; - } + }, + id: "iso8601", }; // Automatically generate the other methods that don't need any custom code - ["toString", "dateUntil", "era", "eraYear", "year", "month", "monthCode", "day", "daysInMonth", "fields", "mergeFields"].forEach((methodName) => { + [ + "dateUntil", + "day", + "dayOfWeek", + "dayOfYear", + "daysInMonth", + "daysInWeek", + "daysInYear", + "era", + "eraYear", + "fields", + "inLeapYear", + "mergeFields", + "month", + "monthCode", + "monthsInYear", + "toString", + "weekOfYear", + "year", + "yearOfWeek", + ].forEach((methodName) => { trackingMethods[methodName] = function (...args) { calls.push(`call ${formatPropertyName(methodName, objectName)}`); if (methodName in methodOverrides) { @@ -1669,7 +1750,7 @@ var TemporalHelpers = { if (result === undefined) { return undefined; } - if (typeof result === "object") { + if ((result !== null && typeof result === "object") || typeof result === "function") { return result; } return TemporalHelpers.toPrimitiveObserver(calls, result, `${formatPropertyName(key, objectName)}`); @@ -1770,6 +1851,10 @@ var TemporalHelpers = { return null; } + get id() { + return "Custom/Spring_Fall"; + } + toString() { return "Custom/Spring_Fall"; } @@ -1790,7 +1875,9 @@ var TemporalHelpers = { */ timeZoneObserver(calls, objectName, methodOverrides = {}) { const utc = new Temporal.TimeZone("UTC"); - const trackingMethods = {}; + const trackingMethods = { + id: "UTC", + }; // Automatically generate the methods ["getOffsetNanosecondsFor", "getPossibleInstantsFor", "toString"].forEach((methodName) => { trackingMethods[methodName] = function (...args) { diff --git a/JSTests/test262/latest-changes-summary.txt b/JSTests/test262/latest-changes-summary.txt index 6b42ccd6dc7d..932b8bbc4baf 100644 --- a/JSTests/test262/latest-changes-summary.txt +++ b/JSTests/test262/latest-changes-summary.txt @@ -1,35 +1,192 @@ -A harness/asyncHelpers.js -M harness/isConstructor.js +M harness/regExpUtils.js +M harness/sta.js M harness/temporalHelpers.js -A test/built-ins/Array/fromAsync/builtin.js -A test/built-ins/Array/fromAsync/length.js -A test/built-ins/Array/fromAsync/name.js -A test/built-ins/Array/fromAsync/not-a-constructor.js -A test/built-ins/Array/fromAsync/prop-desc.js -A test/built-ins/Array/prototype/findLast/maximum-index.js -A test/built-ins/Array/prototype/findLastIndex/maximum-index.js -A test/built-ins/Array/prototype/toLocaleString/invoke-element-tolocalestring.js -A test/built-ins/ArrayBuffer/prototype/detached/detached-buffer-resizable.js -A test/built-ins/ArrayBuffer/prototype/detached/detached-buffer.js -A test/built-ins/ArrayBuffer/prototype/detached/invoked-as-accessor.js -A test/built-ins/ArrayBuffer/prototype/detached/invoked-as-func.js -A test/built-ins/ArrayBuffer/prototype/detached/length.js -A test/built-ins/ArrayBuffer/prototype/detached/name.js -A test/built-ins/ArrayBuffer/prototype/detached/prop-desc.js -A test/built-ins/ArrayBuffer/prototype/detached/this-has-no-arraybufferdata-internal.js -A test/built-ins/ArrayBuffer/prototype/detached/this-is-not-object.js -A test/built-ins/ArrayBuffer/prototype/detached/this-is-sharedarraybuffer-resizable.js -A test/built-ins/ArrayBuffer/prototype/detached/this-is-sharedarraybuffer.js +A test/built-ins/Array/fromAsync/async-iterable-async-mapped-awaits-once.js +A test/built-ins/Array/fromAsync/async-iterable-input-does-not-await-input.js +A test/built-ins/Array/fromAsync/async-iterable-input-iteration-err.js +A test/built-ins/Array/fromAsync/async-iterable-input.js +A test/built-ins/Array/fromAsync/asyncitems-array-add-to-empty.js +A test/built-ins/Array/fromAsync/asyncitems-array-add-to-singleton.js +A test/built-ins/Array/fromAsync/asyncitems-array-add.js +A test/built-ins/Array/fromAsync/asyncitems-array-mutate.js +A test/built-ins/Array/fromAsync/asyncitems-array-remove.js +A test/built-ins/Array/fromAsync/asyncitems-arraybuffer.js +A test/built-ins/Array/fromAsync/asyncitems-arraylike-holes.js +A test/built-ins/Array/fromAsync/asyncitems-arraylike-length-accessor-throws.js +A test/built-ins/Array/fromAsync/asyncitems-arraylike-promise.js +A test/built-ins/Array/fromAsync/asyncitems-arraylike-too-long.js +A test/built-ins/Array/fromAsync/asyncitems-asynciterator-exists.js +A test/built-ins/Array/fromAsync/asyncitems-asynciterator-not-callable.js +A test/built-ins/Array/fromAsync/asyncitems-asynciterator-null.js +A test/built-ins/Array/fromAsync/asyncitems-asynciterator-sync.js +A test/built-ins/Array/fromAsync/asyncitems-asynciterator-throws.js +A test/built-ins/Array/fromAsync/asyncitems-bigint.js +A test/built-ins/Array/fromAsync/asyncitems-boolean.js +A test/built-ins/Array/fromAsync/asyncitems-function.js +A test/built-ins/Array/fromAsync/asyncitems-iterator-exists.js +A test/built-ins/Array/fromAsync/asyncitems-iterator-not-callable.js +A test/built-ins/Array/fromAsync/asyncitems-iterator-null.js +A test/built-ins/Array/fromAsync/asyncitems-iterator-promise.js +A test/built-ins/Array/fromAsync/asyncitems-iterator-throws.js +A test/built-ins/Array/fromAsync/asyncitems-null-undefined.js +A test/built-ins/Array/fromAsync/asyncitems-number.js +A test/built-ins/Array/fromAsync/asyncitems-object-not-arraylike.js +A test/built-ins/Array/fromAsync/asyncitems-operations.js +A test/built-ins/Array/fromAsync/asyncitems-string.js +A test/built-ins/Array/fromAsync/asyncitems-symbol.js +A test/built-ins/Array/fromAsync/asyncitems-uses-intrinsic-iterator-symbols.js +A test/built-ins/Array/fromAsync/mapfn-async-arraylike.js +A test/built-ins/Array/fromAsync/mapfn-async-iterable-async.js +A test/built-ins/Array/fromAsync/mapfn-async-iterable-sync.js +A test/built-ins/Array/fromAsync/mapfn-async-throws-close-async-iterator.js +A test/built-ins/Array/fromAsync/mapfn-async-throws-close-sync-iterator.js +A test/built-ins/Array/fromAsync/mapfn-async-throws.js +A test/built-ins/Array/fromAsync/mapfn-not-callable.js +A test/built-ins/Array/fromAsync/mapfn-result-awaited-once-per-iteration.js +A test/built-ins/Array/fromAsync/mapfn-sync-arraylike.js +A test/built-ins/Array/fromAsync/mapfn-sync-iterable-async.js +A test/built-ins/Array/fromAsync/mapfn-sync-iterable-sync.js +A test/built-ins/Array/fromAsync/mapfn-sync-throws-close-async-iterator.js +A test/built-ins/Array/fromAsync/mapfn-sync-throws-close-sync-iterator.js +A test/built-ins/Array/fromAsync/mapfn-sync-throws.js +A test/built-ins/Array/fromAsync/non-iterable-input-does-not-use-array-prototype.js +A test/built-ins/Array/fromAsync/non-iterable-input-element-access-err.js +A test/built-ins/Array/fromAsync/non-iterable-input-with-thenable-async-mapped-awaits-callback-result-once.js +A test/built-ins/Array/fromAsync/non-iterable-input-with-thenable-async-mapped-callback-err.js +A test/built-ins/Array/fromAsync/non-iterable-input-with-thenable-element-rejects.js +A test/built-ins/Array/fromAsync/non-iterable-input-with-thenable-sync-mapped-callback-err.js +A test/built-ins/Array/fromAsync/non-iterable-input-with-thenable.js +A test/built-ins/Array/fromAsync/non-iterable-input.js +A test/built-ins/Array/fromAsync/non-iterable-sync-mapped-callback-err.js +A test/built-ins/Array/fromAsync/non-iterable-with-non-promise-thenable.js +A test/built-ins/Array/fromAsync/non-iterable-with-thenable-async-mapped-awaits-once.js +A test/built-ins/Array/fromAsync/non-iterable-with-thenable-awaits-once.js +A test/built-ins/Array/fromAsync/non-iterable-with-thenable-sync-mapped-awaits-once.js +A test/built-ins/Array/fromAsync/non-iterable-with-thenable-then-method-err.js +A test/built-ins/Array/fromAsync/returned-promise-resolves-to-array.js +A test/built-ins/Array/fromAsync/returns-promise.js +A test/built-ins/Array/fromAsync/sync-iterable-input-with-non-promise-thenable.js +A test/built-ins/Array/fromAsync/sync-iterable-input-with-thenable.js +A test/built-ins/Array/fromAsync/sync-iterable-input.js +A test/built-ins/Array/fromAsync/sync-iterable-iteration-err.js +A test/built-ins/Array/fromAsync/sync-iterable-with-thenable-async-mapped-awaits-once.js +A test/built-ins/Array/fromAsync/sync-iterable-with-thenable-async-mapped-callback-err.js +A test/built-ins/Array/fromAsync/sync-iterable-with-thenable-awaits-once.js +A test/built-ins/Array/fromAsync/sync-iterable-with-thenable-element-rejects.js +A test/built-ins/Array/fromAsync/sync-iterable-with-thenable-sync-mapped-awaits-once.js +A test/built-ins/Array/fromAsync/sync-iterable-with-thenable-sync-mapped-callback-err.js +A test/built-ins/Array/fromAsync/sync-iterable-with-thenable-then-method-err.js +A test/built-ins/Array/fromAsync/this-constructor-operations.js +A test/built-ins/Array/fromAsync/this-constructor-with-bad-length-setter.js +A test/built-ins/Array/fromAsync/this-constructor-with-readonly-elements.js +A test/built-ins/Array/fromAsync/this-constructor-with-readonly-length.js +A test/built-ins/Array/fromAsync/this-constructor-with-unsettable-element-closes-async-iterator.js +A test/built-ins/Array/fromAsync/this-constructor-with-unsettable-element-closes-sync-iterator.js +A test/built-ins/Array/fromAsync/this-constructor-with-unsettable-element.js +A test/built-ins/Array/fromAsync/this-constructor.js +A test/built-ins/Array/fromAsync/this-non-constructor.js +A test/built-ins/Array/fromAsync/thisarg-object.js +A test/built-ins/Array/fromAsync/thisarg-omitted-sloppy.js +A test/built-ins/Array/fromAsync/thisarg-omitted-strict.js +A test/built-ins/Array/fromAsync/thisarg-primitive-sloppy.js +A test/built-ins/Array/fromAsync/thisarg-primitive-strict.js +D test/built-ins/Array/prototype/Symbol.unscopables/array-grouping.js +D test/built-ins/Array/prototype/group/array-like.js +D test/built-ins/Array/prototype/group/callback-arg.js +D test/built-ins/Array/prototype/group/callback-throws.js +D test/built-ins/Array/prototype/group/emptyList.js +D test/built-ins/Array/prototype/group/evenOdd.js +D test/built-ins/Array/prototype/group/get-throws.js +D test/built-ins/Array/prototype/group/invalid-callback.js +D test/built-ins/Array/prototype/group/invalid-object.js +D test/built-ins/Array/prototype/group/invalid-property-key.js +D test/built-ins/Array/prototype/group/length-throw.js +D test/built-ins/Array/prototype/group/length.js +D test/built-ins/Array/prototype/group/name.js +D test/built-ins/Array/prototype/group/null-prototype.js +D test/built-ins/Array/prototype/group/sparse-array.js +D test/built-ins/Array/prototype/group/this-arg-strict.js +D test/built-ins/Array/prototype/group/this-arg.js +D test/built-ins/Array/prototype/group/toPropertyKey.js +D test/built-ins/Array/prototype/groupToMap/array-like.js +D test/built-ins/Array/prototype/groupToMap/callback-arg.js +D test/built-ins/Array/prototype/groupToMap/callback-throws.js +D test/built-ins/Array/prototype/groupToMap/emptyList.js +D test/built-ins/Array/prototype/groupToMap/evenOdd.js +D test/built-ins/Array/prototype/groupToMap/get-throws.js +D test/built-ins/Array/prototype/groupToMap/groupLength.js +D test/built-ins/Array/prototype/groupToMap/invalid-callback.js +D test/built-ins/Array/prototype/groupToMap/invalid-object.js +D test/built-ins/Array/prototype/groupToMap/invalid-property-key.js +D test/built-ins/Array/prototype/groupToMap/length-throw.js +D test/built-ins/Array/prototype/groupToMap/length.js +D test/built-ins/Array/prototype/groupToMap/map-instance.js +D test/built-ins/Array/prototype/groupToMap/name.js +D test/built-ins/Array/prototype/groupToMap/negativeZero.js +D test/built-ins/Array/prototype/groupToMap/sparse-array.js +D test/built-ins/Array/prototype/groupToMap/this-arg-strict.js +D test/built-ins/Array/prototype/groupToMap/this-arg.js +D test/built-ins/Array/prototype/groupToMap/toPropertyKey.js +M test/built-ins/Array/prototype/includes/call-with-boolean.js +M test/built-ins/Array/prototype/includes/fromIndex-equal-or-greater-length-returns-false.js +M test/built-ins/Array/prototype/includes/fromIndex-infinity.js +M test/built-ins/Array/prototype/includes/fromIndex-minus-zero.js +M test/built-ins/Array/prototype/includes/get-prop.js +M test/built-ins/Array/prototype/includes/length-boundaries.js +M test/built-ins/Array/prototype/includes/length-zero-returns-false.js +M test/built-ins/Array/prototype/includes/length.js +M test/built-ins/Array/prototype/includes/name.js +M test/built-ins/Array/prototype/includes/no-arg.js +M test/built-ins/Array/prototype/includes/not-a-constructor.js +M test/built-ins/Array/prototype/includes/prop-desc.js +M test/built-ins/Array/prototype/includes/return-abrupt-get-length.js +M test/built-ins/Array/prototype/includes/return-abrupt-get-prop.js +M test/built-ins/Array/prototype/includes/return-abrupt-tointeger-fromindex-symbol.js +M test/built-ins/Array/prototype/includes/return-abrupt-tointeger-fromindex.js +M test/built-ins/Array/prototype/includes/return-abrupt-tonumber-length-symbol.js +M test/built-ins/Array/prototype/includes/return-abrupt-tonumber-length.js +M test/built-ins/Array/prototype/includes/samevaluezero.js +M test/built-ins/Array/prototype/includes/search-found-returns-true.js +M test/built-ins/Array/prototype/includes/search-not-found-returns-false.js +M test/built-ins/Array/prototype/includes/sparse.js +M test/built-ins/Array/prototype/includes/this-is-not-object.js +M test/built-ins/Array/prototype/includes/tointeger-fromindex.js +M test/built-ins/Array/prototype/includes/tolength-length.js +M test/built-ins/Array/prototype/includes/using-fromindex.js +M test/built-ins/Array/prototype/includes/values-are-not-cached.js +M test/built-ins/Array/prototype/methods-called-as-functions.js +M test/built-ins/Array/prototype/pop/clamps-to-integer-limit.js +M test/built-ins/Array/prototype/pop/length-near-integer-limit.js +M test/built-ins/Array/prototype/push/clamps-to-integer-limit.js +M test/built-ins/Array/prototype/push/length-near-integer-limit.js +M test/built-ins/Array/prototype/push/throws-if-integer-limit-exceeded.js +M test/built-ins/Array/prototype/reverse/length-exceeding-integer-limit-with-object.js +M test/built-ins/Array/prototype/reverse/length-exceeding-integer-limit-with-proxy.js +M test/built-ins/Array/prototype/slice/length-exceeding-integer-limit-proxied-array.js +M test/built-ins/Array/prototype/slice/length-exceeding-integer-limit.js +M test/built-ins/Array/prototype/splice/clamps-length-to-integer-limit.js +M test/built-ins/Array/prototype/splice/create-species-length-exceeding-integer-limit.js +M test/built-ins/Array/prototype/splice/length-and-deleteCount-exceeding-integer-limit.js +M test/built-ins/Array/prototype/splice/length-exceeding-integer-limit-shrink-array.js +M test/built-ins/Array/prototype/splice/length-near-integer-limit-grow-array.js +M test/built-ins/Array/prototype/splice/throws-if-integer-limit-exceeded.js +M test/built-ins/Array/prototype/toReversed/length-exceeding-array-length-limit.js +M test/built-ins/Array/prototype/toSorted/length-exceeding-array-length-limit.js +M test/built-ins/Array/prototype/toSpliced/length-clamped-to-2pow53minus1.js +M test/built-ins/Array/prototype/toSpliced/length-exceeding-array-length-limit.js +M test/built-ins/Array/prototype/unshift/clamps-to-integer-limit.js +M test/built-ins/Array/prototype/unshift/length-near-integer-limit.js +M test/built-ins/Array/prototype/unshift/throws-if-integer-limit-exceeded.js +M test/built-ins/Array/prototype/with/index-bigger-or-eq-than-length.js +M test/built-ins/Array/prototype/with/index-smaller-than-minus-length.js +M test/built-ins/Array/prototype/with/length-exceeding-array-length-limit.js +M test/built-ins/ArrayBuffer/prototype/detached/this-is-sharedarraybuffer-resizable.js M test/built-ins/ArrayBuffer/prototype/transfer/descriptor.js M test/built-ins/ArrayBuffer/prototype/transfer/extensible.js -M test/built-ins/ArrayBuffer/prototype/transfer/from-fixed-to-larger.js -M test/built-ins/ArrayBuffer/prototype/transfer/from-fixed-to-same.js -M test/built-ins/ArrayBuffer/prototype/transfer/from-fixed-to-smaller.js -M test/built-ins/ArrayBuffer/prototype/transfer/from-fixed-to-zero.js -M test/built-ins/ArrayBuffer/prototype/transfer/from-resizable-to-larger.js -M test/built-ins/ArrayBuffer/prototype/transfer/from-resizable-to-same.js -M test/built-ins/ArrayBuffer/prototype/transfer/from-resizable-to-smaller.js -M test/built-ins/ArrayBuffer/prototype/transfer/from-resizable-to-zero.js +A test/built-ins/ArrayBuffer/prototype/transfer/from-fixed-to-larger-no-resizable.js +A test/built-ins/ArrayBuffer/prototype/transfer/from-fixed-to-same-no-resizable.js +A test/built-ins/ArrayBuffer/prototype/transfer/from-fixed-to-smaller-no-resizable.js +A test/built-ins/ArrayBuffer/prototype/transfer/from-fixed-to-zero-no-resizable.js M test/built-ins/ArrayBuffer/prototype/transfer/length.js M test/built-ins/ArrayBuffer/prototype/transfer/name.js M test/built-ins/ArrayBuffer/prototype/transfer/new-length-excessive.js @@ -37,402 +194,1872 @@ M test/built-ins/ArrayBuffer/prototype/transfer/new-length-non-number.js M test/built-ins/ArrayBuffer/prototype/transfer/nonconstructor.js M test/built-ins/ArrayBuffer/prototype/transfer/this-is-detached.js M test/built-ins/ArrayBuffer/prototype/transfer/this-is-not-arraybuffer-object.js -M test/built-ins/AsyncFromSyncIteratorPrototype/next/absent-value-not-passed.js -M test/built-ins/AsyncFromSyncIteratorPrototype/return/absent-value-not-passed.js -M test/built-ins/AsyncFromSyncIteratorPrototype/return/return-null.js -M test/built-ins/AsyncGeneratorPrototype/next/request-queue-await-order.js -M test/built-ins/Atomics/waitAsync/bigint/good-views.js -M test/built-ins/Atomics/waitAsync/good-views.js -M test/built-ins/FinalizationRegistry/prototype/cleanupSome/not-a-constructor.js -M test/built-ins/Promise/prototype/finally/rejected-observable-then-calls-argument.js -M test/built-ins/String/prototype/isWellFormed/prop-desc.js -A test/built-ins/String/prototype/isWellFormed/to-string-primitive.js -M test/built-ins/String/prototype/toWellFormed/prop-desc.js -A test/built-ins/String/prototype/toWellFormed/to-string-primitive.js +M test/built-ins/ArrayBuffer/prototype/transfer/this-is-not-object.js +M test/built-ins/ArrayBuffer/prototype/transfer/this-is-sharedarraybuffer.js +A test/built-ins/ArrayBuffer/prototype/transferToFixedLength/descriptor.js +A test/built-ins/ArrayBuffer/prototype/transferToFixedLength/extensible.js +A test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-larger-no-resizable.js +A test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-larger.js +A test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-same-no-resizable.js +A test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-same.js +A test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-smaller-no-resizable.js +A test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-smaller.js +A test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-zero-no-resizable.js +A test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-zero.js +A test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-resizable-to-larger.js +A test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-resizable-to-same.js +A test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-resizable-to-smaller.js +A test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-resizable-to-zero.js +A test/built-ins/ArrayBuffer/prototype/transferToFixedLength/length.js +A test/built-ins/ArrayBuffer/prototype/transferToFixedLength/name.js +A test/built-ins/ArrayBuffer/prototype/transferToFixedLength/new-length-excessive.js +A test/built-ins/ArrayBuffer/prototype/transferToFixedLength/new-length-non-number.js +A test/built-ins/ArrayBuffer/prototype/transferToFixedLength/nonconstructor.js +A test/built-ins/ArrayBuffer/prototype/transferToFixedLength/this-is-detached.js +A test/built-ins/ArrayBuffer/prototype/transferToFixedLength/this-is-not-arraybuffer-object.js +A test/built-ins/ArrayBuffer/prototype/transferToFixedLength/this-is-not-object.js +A test/built-ins/ArrayBuffer/prototype/transferToFixedLength/this-is-sharedarraybuffer.js +M test/built-ins/Atomics/isLockFree/expected-return-value.js +M test/built-ins/Function/prototype/toString/built-in-function-object.js +A test/built-ins/Iterator/constructor.js +A test/built-ins/Iterator/from/callable.js +A test/built-ins/Iterator/from/get-next-method-only-once.js +A test/built-ins/Iterator/from/get-next-method-throws.js +A test/built-ins/Iterator/from/is-function.js +A test/built-ins/Iterator/from/iterable-primitives.js +A test/built-ins/Iterator/from/iterable-to-iterator-fallback.js +A test/built-ins/Iterator/from/length.js +A test/built-ins/Iterator/from/name.js +A test/built-ins/Iterator/from/non-constructible.js +A test/built-ins/Iterator/from/primitives.js +A test/built-ins/Iterator/from/prop-desc.js +A test/built-ins/Iterator/from/proto.js +A test/built-ins/Iterator/from/result-proto.js +A test/built-ins/Iterator/from/supports-iterable.js +A test/built-ins/Iterator/from/supports-iterator.js +A test/built-ins/Iterator/length.js +A test/built-ins/Iterator/name.js +A test/built-ins/Iterator/newtarget-or-active-function-object.js +A test/built-ins/Iterator/prop-desc.js +A test/built-ins/Iterator/proto-from-ctor-realm.js +A test/built-ins/Iterator/proto.js +A test/built-ins/Iterator/prototype/Symbol.iterator/is-function.js +R068 test/built-ins/IteratorPrototype/Symbol.iterator/length.js test/built-ins/Iterator/prototype/Symbol.iterator/length.js +R074 test/built-ins/IteratorPrototype/Symbol.iterator/name.js test/built-ins/Iterator/prototype/Symbol.iterator/name.js +R065 test/built-ins/IteratorPrototype/Symbol.iterator/prop-desc.js test/built-ins/Iterator/prototype/Symbol.iterator/prop-desc.js +R067 test/built-ins/IteratorPrototype/Symbol.iterator/return-val.js test/built-ins/Iterator/prototype/Symbol.iterator/return-val.js +A test/built-ins/Iterator/prototype/Symbol.toStringTag/prop-desc.js +A test/built-ins/Iterator/prototype/drop/argument-effect-order.js +A test/built-ins/Iterator/prototype/drop/callable.js +A test/built-ins/Iterator/prototype/drop/exhaustion-does-not-call-return.js +A test/built-ins/Iterator/prototype/drop/get-next-method-only-once.js +A test/built-ins/Iterator/prototype/drop/get-next-method-throws.js +A test/built-ins/Iterator/prototype/drop/get-return-method-throws.js +A test/built-ins/Iterator/prototype/drop/is-function.js +A test/built-ins/Iterator/prototype/drop/length.js +A test/built-ins/Iterator/prototype/drop/limit-equals-total.js +A test/built-ins/Iterator/prototype/drop/limit-greater-than-total.js +A test/built-ins/Iterator/prototype/drop/limit-less-than-total.js +A test/built-ins/Iterator/prototype/drop/limit-rangeerror.js +A test/built-ins/Iterator/prototype/drop/limit-tonumber-throws.js +A test/built-ins/Iterator/prototype/drop/limit-tonumber.js +A test/built-ins/Iterator/prototype/drop/name.js +A test/built-ins/Iterator/prototype/drop/next-method-returns-non-object.js +A test/built-ins/Iterator/prototype/drop/next-method-returns-throwing-done.js +A test/built-ins/Iterator/prototype/drop/next-method-returns-throwing-value-done.js +A test/built-ins/Iterator/prototype/drop/next-method-returns-throwing-value.js +A test/built-ins/Iterator/prototype/drop/next-method-throws.js +A test/built-ins/Iterator/prototype/drop/non-constructible.js +A test/built-ins/Iterator/prototype/drop/prop-desc.js +A test/built-ins/Iterator/prototype/drop/proto.js +A test/built-ins/Iterator/prototype/drop/result-is-iterator.js +A test/built-ins/Iterator/prototype/drop/return-is-forwarded.js +A test/built-ins/Iterator/prototype/drop/return-is-not-forwarded-after-exhaustion.js +A test/built-ins/Iterator/prototype/drop/this-non-callable-next.js +A test/built-ins/Iterator/prototype/drop/this-non-object.js +A test/built-ins/Iterator/prototype/drop/this-plain-iterator.js +A test/built-ins/Iterator/prototype/drop/underlying-iterator-advanced-in-parallel.js +A test/built-ins/Iterator/prototype/drop/underlying-iterator-closed-in-parallel.js +A test/built-ins/Iterator/prototype/drop/underlying-iterator-closed.js +A test/built-ins/Iterator/prototype/every/argument-effect-order.js +A test/built-ins/Iterator/prototype/every/callable.js +A test/built-ins/Iterator/prototype/every/get-next-method-only-once.js +A test/built-ins/Iterator/prototype/every/get-next-method-throws.js +A test/built-ins/Iterator/prototype/every/get-return-method-throws.js +A test/built-ins/Iterator/prototype/every/is-function.js +A test/built-ins/Iterator/prototype/every/iterator-already-exhausted.js +A test/built-ins/Iterator/prototype/every/iterator-has-no-return.js +A test/built-ins/Iterator/prototype/every/iterator-return-method-throws.js +A test/built-ins/Iterator/prototype/every/length.js +A test/built-ins/Iterator/prototype/every/name.js +A test/built-ins/Iterator/prototype/every/next-method-returns-non-object.js +A test/built-ins/Iterator/prototype/every/next-method-returns-throwing-done.js +A test/built-ins/Iterator/prototype/every/next-method-returns-throwing-value-done.js +A test/built-ins/Iterator/prototype/every/next-method-returns-throwing-value.js +A test/built-ins/Iterator/prototype/every/next-method-throws.js +A test/built-ins/Iterator/prototype/every/non-callable-predicate.js +A test/built-ins/Iterator/prototype/every/non-constructible.js +A test/built-ins/Iterator/prototype/every/predicate-args.js +A test/built-ins/Iterator/prototype/every/predicate-returns-falsey.js +A test/built-ins/Iterator/prototype/every/predicate-returns-non-boolean.js +A test/built-ins/Iterator/prototype/every/predicate-returns-truthy-then-falsey.js +A test/built-ins/Iterator/prototype/every/predicate-returns-truthy.js +A test/built-ins/Iterator/prototype/every/predicate-this.js +A test/built-ins/Iterator/prototype/every/predicate-throws-then-closing-iterator-also-throws.js +A test/built-ins/Iterator/prototype/every/predicate-throws.js +A test/built-ins/Iterator/prototype/every/prop-desc.js +A test/built-ins/Iterator/prototype/every/proto.js +A test/built-ins/Iterator/prototype/every/result-is-boolean.js +A test/built-ins/Iterator/prototype/every/this-non-callable-next.js +A test/built-ins/Iterator/prototype/every/this-non-object.js +A test/built-ins/Iterator/prototype/every/this-plain-iterator.js +A test/built-ins/Iterator/prototype/filter/argument-effect-order.js +A test/built-ins/Iterator/prototype/filter/callable.js +A test/built-ins/Iterator/prototype/filter/exhaustion-does-not-call-return.js +A test/built-ins/Iterator/prototype/filter/get-next-method-only-once.js +A test/built-ins/Iterator/prototype/filter/get-next-method-throws.js +A test/built-ins/Iterator/prototype/filter/get-return-method-throws.js +A test/built-ins/Iterator/prototype/filter/is-function.js +A test/built-ins/Iterator/prototype/filter/iterator-already-exhausted.js +A test/built-ins/Iterator/prototype/filter/iterator-return-method-throws.js +A test/built-ins/Iterator/prototype/filter/length.js +A test/built-ins/Iterator/prototype/filter/name.js +A test/built-ins/Iterator/prototype/filter/next-method-returns-non-object.js +A test/built-ins/Iterator/prototype/filter/next-method-returns-throwing-done.js +A test/built-ins/Iterator/prototype/filter/next-method-returns-throwing-value-done.js +A test/built-ins/Iterator/prototype/filter/next-method-returns-throwing-value.js +A test/built-ins/Iterator/prototype/filter/next-method-throws.js +A test/built-ins/Iterator/prototype/filter/non-callable-predicate.js +A test/built-ins/Iterator/prototype/filter/non-constructible.js +A test/built-ins/Iterator/prototype/filter/predicate-args.js +A test/built-ins/Iterator/prototype/filter/predicate-filters.js +A test/built-ins/Iterator/prototype/filter/predicate-returns-non-boolean.js +A test/built-ins/Iterator/prototype/filter/predicate-this.js +A test/built-ins/Iterator/prototype/filter/predicate-throws-then-closing-iterator-also-throws.js +A test/built-ins/Iterator/prototype/filter/predicate-throws.js +A test/built-ins/Iterator/prototype/filter/prop-desc.js +A test/built-ins/Iterator/prototype/filter/proto.js +A test/built-ins/Iterator/prototype/filter/result-is-iterator.js +A test/built-ins/Iterator/prototype/filter/return-is-forwarded.js +A test/built-ins/Iterator/prototype/filter/return-is-not-forwarded-after-exhaustion.js +A test/built-ins/Iterator/prototype/filter/this-non-callable-next.js +A test/built-ins/Iterator/prototype/filter/this-non-object.js +A test/built-ins/Iterator/prototype/filter/this-plain-iterator.js +A test/built-ins/Iterator/prototype/filter/underlying-iterator-advanced-in-parallel.js +A test/built-ins/Iterator/prototype/filter/underlying-iterator-closed-in-parallel.js +A test/built-ins/Iterator/prototype/filter/underlying-iterator-closed.js +A test/built-ins/Iterator/prototype/find/argument-effect-order.js +A test/built-ins/Iterator/prototype/find/callable.js +A test/built-ins/Iterator/prototype/find/get-next-method-only-once.js +A test/built-ins/Iterator/prototype/find/get-next-method-throws.js +A test/built-ins/Iterator/prototype/find/get-return-method-throws.js +A test/built-ins/Iterator/prototype/find/is-function.js +A test/built-ins/Iterator/prototype/find/iterator-already-exhausted.js +A test/built-ins/Iterator/prototype/find/iterator-has-no-return.js +A test/built-ins/Iterator/prototype/find/iterator-return-method-throws.js +A test/built-ins/Iterator/prototype/find/length.js +A test/built-ins/Iterator/prototype/find/name.js +A test/built-ins/Iterator/prototype/find/next-method-returns-non-object.js +A test/built-ins/Iterator/prototype/find/next-method-returns-throwing-done.js +A test/built-ins/Iterator/prototype/find/next-method-returns-throwing-value-done.js +A test/built-ins/Iterator/prototype/find/next-method-returns-throwing-value.js +A test/built-ins/Iterator/prototype/find/next-method-throws.js +A test/built-ins/Iterator/prototype/find/non-callable-predicate.js +A test/built-ins/Iterator/prototype/find/non-constructible.js +A test/built-ins/Iterator/prototype/find/predicate-args.js +A test/built-ins/Iterator/prototype/find/predicate-returns-falsey-then-truthy.js +A test/built-ins/Iterator/prototype/find/predicate-returns-falsey.js +A test/built-ins/Iterator/prototype/find/predicate-returns-non-boolean.js +A test/built-ins/Iterator/prototype/find/predicate-returns-truthy.js +A test/built-ins/Iterator/prototype/find/predicate-this.js +A test/built-ins/Iterator/prototype/find/predicate-throws-then-closing-iterator-also-throws.js +A test/built-ins/Iterator/prototype/find/predicate-throws.js +A test/built-ins/Iterator/prototype/find/prop-desc.js +A test/built-ins/Iterator/prototype/find/proto.js +A test/built-ins/Iterator/prototype/find/this-non-callable-next.js +A test/built-ins/Iterator/prototype/find/this-non-object.js +A test/built-ins/Iterator/prototype/find/this-plain-iterator.js +A test/built-ins/Iterator/prototype/flatMap/argument-effect-order.js +A test/built-ins/Iterator/prototype/flatMap/callable.js +A test/built-ins/Iterator/prototype/flatMap/exhaustion-does-not-call-return.js +A test/built-ins/Iterator/prototype/flatMap/flattens-iterable.js +A test/built-ins/Iterator/prototype/flatMap/flattens-iterator.js +A test/built-ins/Iterator/prototype/flatMap/flattens-only-depth-1.js +A test/built-ins/Iterator/prototype/flatMap/get-next-method-only-once.js +A test/built-ins/Iterator/prototype/flatMap/get-next-method-throws.js +A test/built-ins/Iterator/prototype/flatMap/get-return-method-throws.js +A test/built-ins/Iterator/prototype/flatMap/is-function.js +A test/built-ins/Iterator/prototype/flatMap/iterable-primitives-are-not-flattened.js +A test/built-ins/Iterator/prototype/flatMap/iterable-to-iterator-fallback.js +A test/built-ins/Iterator/prototype/flatMap/iterator-already-exhausted.js +A test/built-ins/Iterator/prototype/flatMap/iterator-return-method-throws.js +A test/built-ins/Iterator/prototype/flatMap/length.js +A test/built-ins/Iterator/prototype/flatMap/mapper-args.js +A test/built-ins/Iterator/prototype/flatMap/mapper-returns-closed-iterator.js +A test/built-ins/Iterator/prototype/flatMap/mapper-returns-non-object.js +A test/built-ins/Iterator/prototype/flatMap/mapper-this.js +A test/built-ins/Iterator/prototype/flatMap/mapper-throws-then-closing-iterator-also-throws.js +A test/built-ins/Iterator/prototype/flatMap/mapper-throws.js +A test/built-ins/Iterator/prototype/flatMap/name.js +A test/built-ins/Iterator/prototype/flatMap/next-method-returns-non-object.js +A test/built-ins/Iterator/prototype/flatMap/next-method-returns-throwing-done.js +A test/built-ins/Iterator/prototype/flatMap/next-method-returns-throwing-value-done.js +A test/built-ins/Iterator/prototype/flatMap/next-method-returns-throwing-value.js +A test/built-ins/Iterator/prototype/flatMap/next-method-throws.js +A test/built-ins/Iterator/prototype/flatMap/non-callable-mapper.js +A test/built-ins/Iterator/prototype/flatMap/non-constructible.js +A test/built-ins/Iterator/prototype/flatMap/prop-desc.js +A test/built-ins/Iterator/prototype/flatMap/proto.js +A test/built-ins/Iterator/prototype/flatMap/result-is-iterator.js +A test/built-ins/Iterator/prototype/flatMap/return-is-forwarded-to-mapper-result.js +A test/built-ins/Iterator/prototype/flatMap/return-is-forwarded-to-underlying-iterator.js +A test/built-ins/Iterator/prototype/flatMap/return-is-not-forwarded-after-exhaustion.js +A test/built-ins/Iterator/prototype/flatMap/strings-are-not-flattened.js +A test/built-ins/Iterator/prototype/flatMap/this-non-callable-next.js +A test/built-ins/Iterator/prototype/flatMap/this-non-object.js +A test/built-ins/Iterator/prototype/flatMap/this-plain-iterator.js +A test/built-ins/Iterator/prototype/flatMap/underlying-iterator-advanced-in-parallel.js +A test/built-ins/Iterator/prototype/flatMap/underlying-iterator-closed-in-parallel.js +A test/built-ins/Iterator/prototype/flatMap/underlying-iterator-closed.js +A test/built-ins/Iterator/prototype/forEach/argument-effect-order.js +A test/built-ins/Iterator/prototype/forEach/callable.js +A test/built-ins/Iterator/prototype/forEach/fn-args.js +A test/built-ins/Iterator/prototype/forEach/fn-called-for-each-yielded-value.js +A test/built-ins/Iterator/prototype/forEach/fn-this.js +A test/built-ins/Iterator/prototype/forEach/fn-throws-then-closing-iterator-also-throws.js +A test/built-ins/Iterator/prototype/forEach/fn-throws.js +A test/built-ins/Iterator/prototype/forEach/get-next-method-only-once.js +A test/built-ins/Iterator/prototype/forEach/get-next-method-throws.js +A test/built-ins/Iterator/prototype/forEach/is-function.js +A test/built-ins/Iterator/prototype/forEach/iterator-already-exhausted.js +A test/built-ins/Iterator/prototype/forEach/length.js +A test/built-ins/Iterator/prototype/forEach/name.js +A test/built-ins/Iterator/prototype/forEach/next-method-returns-non-object.js +A test/built-ins/Iterator/prototype/forEach/next-method-returns-throwing-done.js +A test/built-ins/Iterator/prototype/forEach/next-method-returns-throwing-value-done.js +A test/built-ins/Iterator/prototype/forEach/next-method-returns-throwing-value.js +A test/built-ins/Iterator/prototype/forEach/next-method-throws.js +A test/built-ins/Iterator/prototype/forEach/non-callable-predicate.js +A test/built-ins/Iterator/prototype/forEach/non-constructible.js +A test/built-ins/Iterator/prototype/forEach/prop-desc.js +A test/built-ins/Iterator/prototype/forEach/proto.js +A test/built-ins/Iterator/prototype/forEach/result-is-undefined.js +A test/built-ins/Iterator/prototype/forEach/this-non-callable-next.js +A test/built-ins/Iterator/prototype/forEach/this-non-object.js +A test/built-ins/Iterator/prototype/forEach/this-plain-iterator.js +A test/built-ins/Iterator/prototype/initial-value.js +A test/built-ins/Iterator/prototype/map/argument-effect-order.js +A test/built-ins/Iterator/prototype/map/callable.js +A test/built-ins/Iterator/prototype/map/exhaustion-does-not-call-return.js +A test/built-ins/Iterator/prototype/map/get-next-method-only-once.js +A test/built-ins/Iterator/prototype/map/get-next-method-throws.js +A test/built-ins/Iterator/prototype/map/get-return-method-throws.js +A test/built-ins/Iterator/prototype/map/is-function.js +A test/built-ins/Iterator/prototype/map/iterator-already-exhausted.js +A test/built-ins/Iterator/prototype/map/iterator-return-method-throws.js +A test/built-ins/Iterator/prototype/map/length.js +A test/built-ins/Iterator/prototype/map/mapper-args.js +A test/built-ins/Iterator/prototype/map/mapper-this.js +A test/built-ins/Iterator/prototype/map/mapper-throws-then-closing-iterator-also-throws.js +A test/built-ins/Iterator/prototype/map/mapper-throws.js +A test/built-ins/Iterator/prototype/map/name.js +A test/built-ins/Iterator/prototype/map/next-method-returns-non-object.js +A test/built-ins/Iterator/prototype/map/next-method-returns-throwing-done.js +A test/built-ins/Iterator/prototype/map/next-method-returns-throwing-value-done.js +A test/built-ins/Iterator/prototype/map/next-method-returns-throwing-value.js +A test/built-ins/Iterator/prototype/map/next-method-throws.js +A test/built-ins/Iterator/prototype/map/non-callable-mapper.js +A test/built-ins/Iterator/prototype/map/non-constructible.js +A test/built-ins/Iterator/prototype/map/prop-desc.js +A test/built-ins/Iterator/prototype/map/proto.js +A test/built-ins/Iterator/prototype/map/result-is-iterator.js +A test/built-ins/Iterator/prototype/map/return-is-forwarded-to-underlying-iterator.js +A test/built-ins/Iterator/prototype/map/return-is-not-forwarded-after-exhaustion.js +A test/built-ins/Iterator/prototype/map/returned-iterator-yields-mapper-return-values.js +A test/built-ins/Iterator/prototype/map/this-non-callable-next.js +A test/built-ins/Iterator/prototype/map/this-non-object.js +A test/built-ins/Iterator/prototype/map/this-plain-iterator.js +A test/built-ins/Iterator/prototype/map/underlying-iterator-advanced-in-parallel.js +A test/built-ins/Iterator/prototype/map/underlying-iterator-closed-in-parallel.js +A test/built-ins/Iterator/prototype/map/underlying-iterator-closed.js +A test/built-ins/Iterator/prototype/reduce/argument-effect-order.js +A test/built-ins/Iterator/prototype/reduce/callable.js +A test/built-ins/Iterator/prototype/reduce/get-next-method-only-once.js +A test/built-ins/Iterator/prototype/reduce/get-next-method-throws.js +A test/built-ins/Iterator/prototype/reduce/is-function.js +A test/built-ins/Iterator/prototype/reduce/iterator-already-exhausted-initial-value.js +A test/built-ins/Iterator/prototype/reduce/iterator-already-exhausted-no-initial-value.js +A test/built-ins/Iterator/prototype/reduce/iterator-yields-once-initial-value.js +A test/built-ins/Iterator/prototype/reduce/iterator-yields-once-no-initial-value.js +A test/built-ins/Iterator/prototype/reduce/length.js +A test/built-ins/Iterator/prototype/reduce/name.js +A test/built-ins/Iterator/prototype/reduce/next-method-returns-non-object.js +A test/built-ins/Iterator/prototype/reduce/next-method-returns-throwing-done.js +A test/built-ins/Iterator/prototype/reduce/next-method-returns-throwing-value-done.js +A test/built-ins/Iterator/prototype/reduce/next-method-returns-throwing-value.js +A test/built-ins/Iterator/prototype/reduce/next-method-throws.js +A test/built-ins/Iterator/prototype/reduce/non-callable-reducer.js +A test/built-ins/Iterator/prototype/reduce/non-constructible.js +A test/built-ins/Iterator/prototype/reduce/prop-desc.js +A test/built-ins/Iterator/prototype/reduce/proto.js +A test/built-ins/Iterator/prototype/reduce/reducer-args-initial-value.js +A test/built-ins/Iterator/prototype/reduce/reducer-args-no-initial-value.js +A test/built-ins/Iterator/prototype/reduce/reducer-memo-can-be-any-type.js +A test/built-ins/Iterator/prototype/reduce/reducer-this.js +A test/built-ins/Iterator/prototype/reduce/reducer-throws-then-closing-iterator-also-throws.js +A test/built-ins/Iterator/prototype/reduce/reducer-throws.js +A test/built-ins/Iterator/prototype/reduce/this-non-callable-next.js +A test/built-ins/Iterator/prototype/reduce/this-non-object.js +A test/built-ins/Iterator/prototype/reduce/this-plain-iterator.js +A test/built-ins/Iterator/prototype/some/argument-effect-order.js +A test/built-ins/Iterator/prototype/some/callable.js +A test/built-ins/Iterator/prototype/some/get-next-method-only-once.js +A test/built-ins/Iterator/prototype/some/get-next-method-throws.js +A test/built-ins/Iterator/prototype/some/get-return-method-throws.js +A test/built-ins/Iterator/prototype/some/is-function.js +A test/built-ins/Iterator/prototype/some/iterator-already-exhausted.js +A test/built-ins/Iterator/prototype/some/iterator-has-no-return.js +A test/built-ins/Iterator/prototype/some/iterator-return-method-throws.js +A test/built-ins/Iterator/prototype/some/length.js +A test/built-ins/Iterator/prototype/some/name.js +A test/built-ins/Iterator/prototype/some/next-method-returns-non-object.js +A test/built-ins/Iterator/prototype/some/next-method-returns-throwing-done.js +A test/built-ins/Iterator/prototype/some/next-method-returns-throwing-value-done.js +A test/built-ins/Iterator/prototype/some/next-method-returns-throwing-value.js +A test/built-ins/Iterator/prototype/some/next-method-throws.js +A test/built-ins/Iterator/prototype/some/non-callable-predicate.js +A test/built-ins/Iterator/prototype/some/non-constructible.js +A test/built-ins/Iterator/prototype/some/predicate-args.js +A test/built-ins/Iterator/prototype/some/predicate-returns-falsey-then-truthy.js +A test/built-ins/Iterator/prototype/some/predicate-returns-falsey.js +A test/built-ins/Iterator/prototype/some/predicate-returns-non-boolean.js +A test/built-ins/Iterator/prototype/some/predicate-returns-truthy.js +A test/built-ins/Iterator/prototype/some/predicate-this.js +A test/built-ins/Iterator/prototype/some/predicate-throws-then-closing-iterator-also-throws.js +A test/built-ins/Iterator/prototype/some/predicate-throws.js +A test/built-ins/Iterator/prototype/some/prop-desc.js +A test/built-ins/Iterator/prototype/some/proto.js +A test/built-ins/Iterator/prototype/some/result-is-boolean.js +A test/built-ins/Iterator/prototype/some/this-non-callable-next.js +A test/built-ins/Iterator/prototype/some/this-non-object.js +A test/built-ins/Iterator/prototype/some/this-plain-iterator.js +A test/built-ins/Iterator/prototype/take/argument-effect-order.js +A test/built-ins/Iterator/prototype/take/callable.js +A test/built-ins/Iterator/prototype/take/exhaustion-calls-return.js +A test/built-ins/Iterator/prototype/take/get-next-method-only-once.js +A test/built-ins/Iterator/prototype/take/get-next-method-throws.js +A test/built-ins/Iterator/prototype/take/get-return-method-throws.js +A test/built-ins/Iterator/prototype/take/is-function.js +A test/built-ins/Iterator/prototype/take/length.js +A test/built-ins/Iterator/prototype/take/limit-greater-than-or-equal-to-total.js +A test/built-ins/Iterator/prototype/take/limit-less-than-total.js +A test/built-ins/Iterator/prototype/take/limit-rangeerror.js +A test/built-ins/Iterator/prototype/take/limit-tonumber-throws.js +A test/built-ins/Iterator/prototype/take/limit-tonumber.js +A test/built-ins/Iterator/prototype/take/name.js +A test/built-ins/Iterator/prototype/take/next-method-returns-non-object.js +A test/built-ins/Iterator/prototype/take/next-method-returns-throwing-done.js +A test/built-ins/Iterator/prototype/take/next-method-returns-throwing-value-done.js +A test/built-ins/Iterator/prototype/take/next-method-returns-throwing-value.js +A test/built-ins/Iterator/prototype/take/next-method-throws.js +A test/built-ins/Iterator/prototype/take/non-constructible.js +A test/built-ins/Iterator/prototype/take/prop-desc.js +A test/built-ins/Iterator/prototype/take/proto.js +A test/built-ins/Iterator/prototype/take/result-is-iterator.js +A test/built-ins/Iterator/prototype/take/return-is-forwarded.js +A test/built-ins/Iterator/prototype/take/return-is-not-forwarded-after-exhaustion.js +A test/built-ins/Iterator/prototype/take/this-non-callable-next.js +A test/built-ins/Iterator/prototype/take/this-non-object.js +A test/built-ins/Iterator/prototype/take/this-plain-iterator.js +A test/built-ins/Iterator/prototype/take/underlying-iterator-advanced-in-parallel.js +A test/built-ins/Iterator/prototype/take/underlying-iterator-closed-in-parallel.js +A test/built-ins/Iterator/prototype/take/underlying-iterator-closed.js +A test/built-ins/Iterator/prototype/toArray/callable.js +A test/built-ins/Iterator/prototype/toArray/get-next-method-only-once.js +A test/built-ins/Iterator/prototype/toArray/get-next-method-throws.js +A test/built-ins/Iterator/prototype/toArray/is-function.js +A test/built-ins/Iterator/prototype/toArray/iterator-already-exhausted.js +A test/built-ins/Iterator/prototype/toArray/length.js +A test/built-ins/Iterator/prototype/toArray/name.js +A test/built-ins/Iterator/prototype/toArray/next-method-returns-non-object.js +A test/built-ins/Iterator/prototype/toArray/next-method-returns-throwing-done.js +A test/built-ins/Iterator/prototype/toArray/next-method-returns-throwing-value-done.js +A test/built-ins/Iterator/prototype/toArray/next-method-returns-throwing-value.js +A test/built-ins/Iterator/prototype/toArray/next-method-throws.js +A test/built-ins/Iterator/prototype/toArray/non-constructible.js +A test/built-ins/Iterator/prototype/toArray/prop-desc.js +A test/built-ins/Iterator/prototype/toArray/proto.js +A test/built-ins/Iterator/prototype/toArray/this-non-callable-next.js +A test/built-ins/Iterator/prototype/toArray/this-non-object.js +A test/built-ins/Iterator/prototype/toArray/this-plain-iterator.js +A test/built-ins/Iterator/subclassable.js +A test/built-ins/Map/groupBy/callback-arg.js +A test/built-ins/Map/groupBy/callback-throws.js +A test/built-ins/Map/groupBy/emptyList.js +A test/built-ins/Map/groupBy/evenOdd.js +A test/built-ins/Map/groupBy/groupLength.js +A test/built-ins/Map/groupBy/invalid-callback.js +A test/built-ins/Map/groupBy/invalid-iterable.js +A test/built-ins/Map/groupBy/iterator-next-throws.js +A test/built-ins/Map/groupBy/length.js +A test/built-ins/Map/groupBy/map-instance.js +A test/built-ins/Map/groupBy/name.js +A test/built-ins/Map/groupBy/negativeZero.js +A test/built-ins/Map/groupBy/toPropertyKey.js +M test/built-ins/Map/valid-keys.js +M test/built-ins/Number/bigint-conversion.js +A test/built-ins/Object/groupBy/callback-arg.js +A test/built-ins/Object/groupBy/callback-throws.js +A test/built-ins/Object/groupBy/emptyList.js +A test/built-ins/Object/groupBy/evenOdd.js +R050 test/built-ins/Array/prototype/group/groupLength.js test/built-ins/Object/groupBy/groupLength.js +A test/built-ins/Object/groupBy/invalid-callback.js +A test/built-ins/Object/groupBy/invalid-iterable.js +A test/built-ins/Object/groupBy/invalid-property-key.js +A test/built-ins/Object/groupBy/iterator-next-throws.js +A test/built-ins/Object/groupBy/length.js +A test/built-ins/Object/groupBy/name.js +A test/built-ins/Object/groupBy/null-prototype.js +A test/built-ins/Object/groupBy/toPropertyKey.js +M test/built-ins/Object/prototype/toString/symbol-tag-non-str-builtin.js +M test/built-ins/Proxy/has/trap-is-null-target-is-proxy.js +M test/built-ins/RegExp/prototype/exec/failure-lastindex-set.js +A test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-01.js +A test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-02.js +A test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-03.js +A test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-04.js +A test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-05.js +A test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-06.js +A test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-07.js +A test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-08.js +A test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-09.js +A test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-10.js +A test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-11.js +A test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-12.js +A test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-13.js +A test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-14.js +A test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-15.js +A test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-16.js +A test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-17.js +A test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-18.js +A test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-19.js +A test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-20.js +A test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-21.js +A test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-22.js +A test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-23.js +A test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-24.js +A test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-25.js +A test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-26.js +A test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-27.js +A test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-28.js +M test/built-ins/Set/valid-values.js +M test/built-ins/ShadowRealm/prototype/evaluate/globalthis-config-only-properties.js +D test/built-ins/Temporal/Calendar/from/calendar-instance-does-not-get-calendar-property.js +D test/built-ins/Temporal/Calendar/from/calendar-object-invalid.js +D test/built-ins/Temporal/Calendar/from/calendar-object-operations.js +M test/built-ins/Temporal/Calendar/from/calendar-object.js +M test/built-ins/Temporal/Calendar/from/calendar-string-leap-second.js M test/built-ins/Temporal/Calendar/from/calendar-temporal-object.js -D test/built-ins/Temporal/Calendar/prototype/dateAdd/argument-calendar-fields-undefined.js +M test/built-ins/Temporal/Calendar/from/calendar-wrong-type.js M test/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-case-insensitive.js -D test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-calendar-fields-undefined.js -A test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-case-insensitive.js -D test/built-ins/Temporal/Calendar/prototype/day/argument-calendar-fields-undefined.js +D test/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-wrong-type.js +M test/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-calendar-annotation.js +A test/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-multiple-calendar.js +M test/built-ins/Temporal/Calendar/prototype/dateAdd/order-of-operations.js +A test/built-ins/Temporal/Calendar/prototype/dateFromFields/one-of-era-erayear-undefined.js +M test/built-ins/Temporal/Calendar/prototype/dateFromFields/order-of-operations.js +M test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-case-insensitive.js +D test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-string.js +M test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-wrong-type.js +M test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-calendar-annotation.js +A test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-multiple-calendar.js +M test/built-ins/Temporal/Calendar/prototype/dateUntil/order-of-operations.js M test/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-case-insensitive.js -D test/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-calendar-fields-undefined.js +D test/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-wrong-type.js +M test/built-ins/Temporal/Calendar/prototype/day/argument-string-calendar-annotation.js +A test/built-ins/Temporal/Calendar/prototype/day/argument-string-multiple-calendar.js M test/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-case-insensitive.js -D test/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-calendar-fields-undefined.js +D test/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-wrong-type.js +M test/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-calendar-annotation.js +A test/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-multiple-calendar.js M test/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-case-insensitive.js -D test/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-calendar-fields-undefined.js +D test/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-wrong-type.js +M test/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-calendar-annotation.js +A test/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-multiple-calendar.js M test/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-case-insensitive.js -D test/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-calendar-fields-undefined.js +D test/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-wrong-type.js +M test/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-calendar-annotation.js +A test/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-multiple-calendar.js M test/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-case-insensitive.js -D test/built-ins/Temporal/Calendar/prototype/daysInYear/argument-calendar-fields-undefined.js +D test/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-wrong-type.js +M test/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-calendar-annotation.js +A test/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-multiple-calendar.js M test/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-case-insensitive.js -D test/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-calendar-fields-undefined.js +D test/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-wrong-type.js +M test/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-calendar-annotation.js +A test/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-multiple-calendar.js M test/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-case-insensitive.js -M test/built-ins/Temporal/Calendar/prototype/mergeFields/arguments-not-object.js +D test/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-wrong-type.js +M test/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-calendar-annotation.js +A test/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-multiple-calendar.js M test/built-ins/Temporal/Calendar/prototype/mergeFields/order-of-operations.js -D test/built-ins/Temporal/Calendar/prototype/month/argument-calendar-fields-undefined.js M test/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-case-insensitive.js -D test/built-ins/Temporal/Calendar/prototype/monthCode/argument-calendar-fields-undefined.js +D test/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-wrong-type.js +M test/built-ins/Temporal/Calendar/prototype/month/argument-string-calendar-annotation.js +A test/built-ins/Temporal/Calendar/prototype/month/argument-string-multiple-calendar.js M test/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-case-insensitive.js -M test/built-ins/Temporal/Calendar/prototype/monthDayFromFields/reference-year-1972.js -D test/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-calendar-fields-undefined.js +D test/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-wrong-type.js +M test/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-calendar-annotation.js +A test/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-multiple-calendar.js +A test/built-ins/Temporal/Calendar/prototype/monthDayFromFields/one-of-era-erayear-undefined.js +M test/built-ins/Temporal/Calendar/prototype/monthDayFromFields/order-of-operations.js M test/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-case-insensitive.js -D test/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-calendar-fields-undefined.js +D test/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-wrong-type.js +M test/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-calendar-annotation.js +A test/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-multiple-calendar.js +A test/built-ins/Temporal/Calendar/prototype/toJSON/returns-identifier-slot.js M test/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-case-insensitive.js -D test/built-ins/Temporal/Calendar/prototype/year/argument-calendar-fields-undefined.js +D test/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-wrong-type.js +M test/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-calendar-annotation.js +A test/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-multiple-calendar.js M test/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-case-insensitive.js -A test/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/reference-day.js -D test/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-calendar-fields-undefined.js -A test/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-case-insensitive.js -A test/built-ins/Temporal/Duration/prototype/add/nanoseconds-to-days-loop-indefinitely-1.js -A test/built-ins/Temporal/Duration/prototype/add/nanoseconds-to-days-loop-indefinitely-2.js -D test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-calendar-fields-undefined.js -A test/built-ins/Temporal/Duration/prototype/add/relativeto-zoneddatetime-nanoseconds-to-days-range-errors.js -M test/built-ins/Temporal/Duration/prototype/round/nanoseconds-to-days-loop-indefinitely-1.js -M test/built-ins/Temporal/Duration/prototype/round/nanoseconds-to-days-loop-indefinitely-2.js -D test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-calendar-fields-undefined.js -A test/built-ins/Temporal/Duration/prototype/round/relativeto-zoneddatetime-nanoseconds-to-days-range-errors.js -A test/built-ins/Temporal/Duration/prototype/round/roundingincrement-non-integer.js -A test/built-ins/Temporal/Duration/prototype/round/roundingincrement-out-of-range.js -A test/built-ins/Temporal/Duration/prototype/subtract/nanoseconds-to-days-loop-indefinitely-1.js -A test/built-ins/Temporal/Duration/prototype/subtract/nanoseconds-to-days-loop-indefinitely-2.js -D test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-calendar-fields-undefined.js -A test/built-ins/Temporal/Duration/prototype/subtract/relativeto-zoneddatetime-nanoseconds-to-days-range-errors.js -A test/built-ins/Temporal/Duration/prototype/total/nanoseconds-to-days-loop-indefinitely-1.js -A test/built-ins/Temporal/Duration/prototype/total/nanoseconds-to-days-loop-indefinitely-2.js -D test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-calendar-fields-undefined.js -A test/built-ins/Temporal/Duration/prototype/total/relativeto-zoneddatetime-nanoseconds-to-days-range-errors.js -M test/built-ins/Temporal/Instant/prototype/round/roundingincrement-non-integer.js -M test/built-ins/Temporal/Instant/prototype/round/roundingincrement-out-of-range.js -M test/built-ins/Temporal/Instant/prototype/since/order-of-operations.js -M test/built-ins/Temporal/Instant/prototype/since/roundingincrement-non-integer.js -M test/built-ins/Temporal/Instant/prototype/since/roundingincrement-out-of-range.js +D test/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-wrong-type.js +M test/built-ins/Temporal/Calendar/prototype/year/argument-string-calendar-annotation.js +A test/built-ins/Temporal/Calendar/prototype/year/argument-string-multiple-calendar.js +A test/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/one-of-era-erayear-undefined.js +M test/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/order-of-operations.js +M test/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-case-insensitive.js +D test/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-wrong-type.js +M test/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-calendar-annotation.js +A test/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-multiple-calendar.js +M test/built-ins/Temporal/Duration/compare/order-of-operations.js +A test/built-ins/Temporal/Duration/compare/relativeto-propertybag-calendar-string.js +D test/built-ins/Temporal/Duration/compare/relativeto-propertybag-timezone-instance-does-not-get-timeZone-property.js +M test/built-ins/Temporal/Duration/compare/relativeto-propertybag-timezone-string-datetime.js +M test/built-ins/Temporal/Duration/compare/relativeto-propertybag-timezone-string-leap-second.js +M test/built-ins/Temporal/Duration/compare/relativeto-propertybag-timezone-string-year-zero.js +M test/built-ins/Temporal/Duration/compare/relativeto-propertybag-timezone-string.js +M test/built-ins/Temporal/Duration/compare/relativeto-propertybag-timezone-wrong-type.js +M test/built-ins/Temporal/Duration/prototype/add/order-of-operations.js +M test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-calendar-number.js +A test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-calendar-string.js +M test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-calendar-wrong-type.js +D test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-timezone-instance-does-not-get-timeZone-property.js +M test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-timezone-string-datetime.js +M test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-timezone-string-leap-second.js +M test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-timezone-string-year-zero.js +M test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-timezone-string.js +M test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-timezone-wrong-type.js +M test/built-ins/Temporal/Duration/prototype/round/calendar-dateadd-called-with-options-undefined.js +M test/built-ins/Temporal/Duration/prototype/round/calendar-dateuntil-called-with-singular-largestunit.js +A test/built-ins/Temporal/Duration/prototype/round/largestunit-correct-rebalancing.js +M test/built-ins/Temporal/Duration/prototype/round/order-of-operations.js +M test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-calendar-number.js +A test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-calendar-string.js +M test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-calendar-wrong-type.js +D test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-timezone-instance-does-not-get-timeZone-property.js +M test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-timezone-string-datetime.js +M test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-timezone-string-leap-second.js +M test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-timezone-string-year-zero.js +M test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-timezone-string.js +M test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-timezone-wrong-type.js +M test/built-ins/Temporal/Duration/prototype/round/relativeto-zoneddatetime-nanoseconds-to-days-range-errors.js +M test/built-ins/Temporal/Duration/prototype/round/throws-in-unbalance-duration-relative-when-sign-mismatched.js +M test/built-ins/Temporal/Duration/prototype/round/timezone-getpossibleinstantsfor-iterable.js +A test/built-ins/Temporal/Duration/prototype/round/zero-day-length-1.js +A test/built-ins/Temporal/Duration/prototype/round/zero-day-length-2.js +M test/built-ins/Temporal/Duration/prototype/subtract/order-of-operations.js +M test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-calendar-number.js +A test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-calendar-string.js +M test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-calendar-wrong-type.js +D test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-timezone-instance-does-not-get-timeZone-property.js +M test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-timezone-string-datetime.js +M test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-timezone-string-leap-second.js +M test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-timezone-string-year-zero.js +M test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-timezone-string.js +M test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-timezone-wrong-type.js +M test/built-ins/Temporal/Duration/prototype/total/order-of-operations.js +M test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-calendar-number.js +A test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-calendar-string.js +M test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-calendar-wrong-type.js +D test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-timezone-instance-does-not-get-timeZone-property.js +M test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-timezone-string-datetime.js +M test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-timezone-string-leap-second.js +M test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-timezone-string-year-zero.js +M test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-timezone-string.js +M test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-timezone-wrong-type.js +M test/built-ins/Temporal/Duration/prototype/total/relativeto-zoneddatetime-nanoseconds-to-days-range-errors.js +A test/built-ins/Temporal/Duration/prototype/total/zero-day-length-1.js +A test/built-ins/Temporal/Duration/prototype/total/zero-day-length-2.js +M test/built-ins/Temporal/Instant/compare/argument-string-calendar-annotation.js +A test/built-ins/Temporal/Instant/compare/argument-string-multiple-calendar.js +M test/built-ins/Temporal/Instant/from/argument-string-calendar-annotation.js +A test/built-ins/Temporal/Instant/from/argument-string-multiple-calendar.js +M test/built-ins/Temporal/Instant/prototype/epochMicroseconds/basic.js +M test/built-ins/Temporal/Instant/prototype/epochMilliseconds/basic.js +M test/built-ins/Temporal/Instant/prototype/epochSeconds/basic.js +M test/built-ins/Temporal/Instant/prototype/equals/argument-string-calendar-annotation.js +A test/built-ins/Temporal/Instant/prototype/equals/argument-string-multiple-calendar.js +M test/built-ins/Temporal/Instant/prototype/since/argument-string-calendar-annotation.js +A test/built-ins/Temporal/Instant/prototype/since/argument-string-multiple-calendar.js +D test/built-ins/Temporal/Instant/prototype/toJSON/timezone-getoffsetnanosecondsfor-not-callable.js +M test/built-ins/Temporal/Instant/prototype/toString/order-of-operations.js +D test/built-ins/Temporal/Instant/prototype/toString/timezone-instance-does-not-get-timeZone-property.js +M test/built-ins/Temporal/Instant/prototype/toString/timezone-string-datetime.js +M test/built-ins/Temporal/Instant/prototype/toString/timezone-string-leap-second.js +M test/built-ins/Temporal/Instant/prototype/toString/timezone-string-multiple-offsets.js +M test/built-ins/Temporal/Instant/prototype/toString/timezone-string-year-zero.js +M test/built-ins/Temporal/Instant/prototype/toString/timezone-string.js +M test/built-ins/Temporal/Instant/prototype/toString/timezone-wrong-type.js +M test/built-ins/Temporal/Instant/prototype/toString/timezone.js M test/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-case-insensitive.js +D test/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-number.js +M test/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-string-leap-second.js +M test/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-string.js M test/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-temporal-object.js -M test/built-ins/Temporal/Instant/prototype/until/order-of-operations.js -M test/built-ins/Temporal/Instant/prototype/until/roundingincrement-non-integer.js -M test/built-ins/Temporal/Instant/prototype/until/roundingincrement-out-of-range.js +M test/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-wrong-type.js +M test/built-ins/Temporal/Instant/prototype/toZonedDateTime/plain-custom-timezone.js +M test/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-case-insensitive.js +D test/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-instance-does-not-get-timeZone-property.js +M test/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-string-datetime.js +M test/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-string-leap-second.js +M test/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-string-multiple-offsets.js +M test/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-string-year-zero.js +M test/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-string.js +M test/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-wrong-type.js +A test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/calendar-is-builtin.js +M test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-case-insensitive.js +D test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-instance-does-not-get-timeZone-property.js +M test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-string-datetime.js +M test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-string-leap-second.js +M test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-string-multiple-offsets.js +M test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-string-year-zero.js +M test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-string.js +M test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-wrong-type.js +M test/built-ins/Temporal/Instant/prototype/until/argument-string-calendar-annotation.js +A test/built-ins/Temporal/Instant/prototype/until/argument-string-multiple-calendar.js +M test/built-ins/Temporal/Now/plainDate/calendar-case-insensitive.js +D test/built-ins/Temporal/Now/plainDate/calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/Now/plainDate/calendar-number.js +M test/built-ins/Temporal/Now/plainDate/calendar-string-leap-second.js +M test/built-ins/Temporal/Now/plainDate/calendar-string.js M test/built-ins/Temporal/Now/plainDate/calendar-temporal-object.js +M test/built-ins/Temporal/Now/plainDate/calendar-wrong-type.js +D test/built-ins/Temporal/Now/plainDate/timezone-instance-does-not-get-timeZone-property.js +M test/built-ins/Temporal/Now/plainDate/timezone-string-datetime.js +M test/built-ins/Temporal/Now/plainDate/timezone-string-leap-second.js +M test/built-ins/Temporal/Now/plainDate/timezone-string-year-zero.js +M test/built-ins/Temporal/Now/plainDate/timezone-string.js +M test/built-ins/Temporal/Now/plainDate/timezone-wrong-type.js +M test/built-ins/Temporal/Now/plainDate/toPlainDate-override.js +M test/built-ins/Temporal/Now/plainDateISO/return-value.js +D test/built-ins/Temporal/Now/plainDateISO/timezone-instance-does-not-get-timeZone-property.js +M test/built-ins/Temporal/Now/plainDateISO/timezone-string-datetime.js +M test/built-ins/Temporal/Now/plainDateISO/timezone-string-leap-second.js +M test/built-ins/Temporal/Now/plainDateISO/timezone-string-year-zero.js +M test/built-ins/Temporal/Now/plainDateISO/timezone-string.js +M test/built-ins/Temporal/Now/plainDateISO/timezone-wrong-type.js +M test/built-ins/Temporal/Now/plainDateTime/calendar-case-insensitive.js +M test/built-ins/Temporal/Now/plainDateTime/calendar-function.js +D test/built-ins/Temporal/Now/plainDateTime/calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/Now/plainDateTime/calendar-number.js +D test/built-ins/Temporal/Now/plainDateTime/calendar-object-fail-call-tostring.js +D test/built-ins/Temporal/Now/plainDateTime/calendar-object-fail-get-calendar.js +D test/built-ins/Temporal/Now/plainDateTime/calendar-object-fail-has-calendar.js +D test/built-ins/Temporal/Now/plainDateTime/calendar-object-fail-has-nested-calendar.js +M test/built-ins/Temporal/Now/plainDateTime/calendar-object.js +M test/built-ins/Temporal/Now/plainDateTime/calendar-string-leap-second.js +M test/built-ins/Temporal/Now/plainDateTime/calendar-string.js M test/built-ins/Temporal/Now/plainDateTime/calendar-temporal-object.js +M test/built-ins/Temporal/Now/plainDateTime/calendar-wrong-type.js +M test/built-ins/Temporal/Now/plainDateTime/return-value.js +M test/built-ins/Temporal/Now/plainDateTime/timezone-getoffsetnanosecondsfor-invocation.js +M test/built-ins/Temporal/Now/plainDateTime/timezone-getoffsetnanosecondsfor-not-a-number.js +M test/built-ins/Temporal/Now/plainDateTime/timezone-getoffsetnanosecondsfor-poisoned.js +M test/built-ins/Temporal/Now/plainDateTime/timezone-getoffsetnanosecondsfor-throws.js +D test/built-ins/Temporal/Now/plainDateTime/timezone-instance-does-not-get-timeZone-property.js +D test/built-ins/Temporal/Now/plainDateTime/timezone-object-fail-call-tostring.js +D test/built-ins/Temporal/Now/plainDateTime/timezone-object-fail-get-timezone.js +D test/built-ins/Temporal/Now/plainDateTime/timezone-object-fail-has-nested-timezone.js +D test/built-ins/Temporal/Now/plainDateTime/timezone-object-fail-has-timezone.js +M test/built-ins/Temporal/Now/plainDateTime/timezone-object.js +M test/built-ins/Temporal/Now/plainDateTime/timezone-string-datetime.js +M test/built-ins/Temporal/Now/plainDateTime/timezone-string-leap-second.js +M test/built-ins/Temporal/Now/plainDateTime/timezone-string-year-zero.js +M test/built-ins/Temporal/Now/plainDateTime/timezone-string.js +M test/built-ins/Temporal/Now/plainDateTime/timezone-wrong-type.js +M test/built-ins/Temporal/Now/plainDateTime/timezone.js +M test/built-ins/Temporal/Now/plainDateTimeISO/return-value-calendar.js +M test/built-ins/Temporal/Now/plainDateTimeISO/return-value.js +M test/built-ins/Temporal/Now/plainDateTimeISO/timezone-getoffsetnanosecondsfor-invocation.js +M test/built-ins/Temporal/Now/plainDateTimeISO/timezone-getoffsetnanosecondsfor-not-a-number.js +M test/built-ins/Temporal/Now/plainDateTimeISO/timezone-getoffsetnanosecondsfor-poisoned.js +M test/built-ins/Temporal/Now/plainDateTimeISO/timezone-getoffsetnanosecondsfor-throws.js +D test/built-ins/Temporal/Now/plainDateTimeISO/timezone-instance-does-not-get-timeZone-property.js +D test/built-ins/Temporal/Now/plainDateTimeISO/timezone-object-fail-call-tostring.js +D test/built-ins/Temporal/Now/plainDateTimeISO/timezone-object-fail-get-timezone.js +D test/built-ins/Temporal/Now/plainDateTimeISO/timezone-object-fail-has-nested-timezone.js +D test/built-ins/Temporal/Now/plainDateTimeISO/timezone-object-fail-has-timezone.js +M test/built-ins/Temporal/Now/plainDateTimeISO/timezone-object.js +M test/built-ins/Temporal/Now/plainDateTimeISO/timezone-string-datetime.js +M test/built-ins/Temporal/Now/plainDateTimeISO/timezone-string-leap-second.js +M test/built-ins/Temporal/Now/plainDateTimeISO/timezone-string-year-zero.js +M test/built-ins/Temporal/Now/plainDateTimeISO/timezone-string.js +M test/built-ins/Temporal/Now/plainDateTimeISO/timezone-wrong-type.js +M test/built-ins/Temporal/Now/plainTimeISO/return-value.js +D test/built-ins/Temporal/Now/plainTimeISO/timezone-instance-does-not-get-timeZone-property.js +M test/built-ins/Temporal/Now/plainTimeISO/timezone-string-datetime.js +M test/built-ins/Temporal/Now/plainTimeISO/timezone-string-leap-second.js +M test/built-ins/Temporal/Now/plainTimeISO/timezone-string-year-zero.js +M test/built-ins/Temporal/Now/plainTimeISO/timezone-string.js +M test/built-ins/Temporal/Now/plainTimeISO/timezone-wrong-type.js +M test/built-ins/Temporal/Now/plainTimeISO/timezone.js +M test/built-ins/Temporal/Now/plainTimeISO/toPlainTime-override.js +D test/built-ins/Temporal/Now/timeZone/new-object.js +D test/built-ins/Temporal/Now/timeZone/return-value.js +R063 test/built-ins/Temporal/Now/timeZone/extensible.js test/built-ins/Temporal/Now/timeZoneId/extensible.js +R087 test/built-ins/Temporal/Now/timeZone/length.js test/built-ins/Temporal/Now/timeZoneId/length.js +R071 test/built-ins/Temporal/Now/timeZone/name.js test/built-ins/Temporal/Now/timeZoneId/name.js +R060 test/built-ins/Temporal/Now/timeZone/not-a-constructor.js test/built-ins/Temporal/Now/timeZoneId/not-a-constructor.js +R069 test/built-ins/Temporal/Now/timeZone/prop-desc.js test/built-ins/Temporal/Now/timeZoneId/prop-desc.js +A test/built-ins/Temporal/Now/timeZoneId/return-value.js +M test/built-ins/Temporal/Now/zonedDateTime/calendar-case-insensitive.js +M test/built-ins/Temporal/Now/zonedDateTime/calendar-function.js +D test/built-ins/Temporal/Now/zonedDateTime/calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/Now/zonedDateTime/calendar-number.js +D test/built-ins/Temporal/Now/zonedDateTime/calendar-object-fail-call-tostring.js +D test/built-ins/Temporal/Now/zonedDateTime/calendar-object-fail-get-calendar.js +D test/built-ins/Temporal/Now/zonedDateTime/calendar-object-fail-has-calendar.js +D test/built-ins/Temporal/Now/zonedDateTime/calendar-object-fail-has-nested-calendar.js +M test/built-ins/Temporal/Now/zonedDateTime/calendar-object.js +M test/built-ins/Temporal/Now/zonedDateTime/calendar-string-leap-second.js +M test/built-ins/Temporal/Now/zonedDateTime/calendar-string.js M test/built-ins/Temporal/Now/zonedDateTime/calendar-temporal-object.js -M test/built-ins/Temporal/PlainDate/argument-convert.js +M test/built-ins/Temporal/Now/zonedDateTime/calendar-wrong-type.js +M test/built-ins/Temporal/Now/zonedDateTime/time-zone-undefined.js +M test/built-ins/Temporal/Now/zonedDateTime/timezone-case-insensitive.js +D test/built-ins/Temporal/Now/zonedDateTime/timezone-instance-does-not-get-timeZone-property.js +D test/built-ins/Temporal/Now/zonedDateTime/timezone-object-fail-call-tostring.js +D test/built-ins/Temporal/Now/zonedDateTime/timezone-object-fail-get-timezone.js +D test/built-ins/Temporal/Now/zonedDateTime/timezone-object-fail-has-nested-timezone.js +D test/built-ins/Temporal/Now/zonedDateTime/timezone-object-fail-has-timezone.js +M test/built-ins/Temporal/Now/zonedDateTime/timezone-object.js +M test/built-ins/Temporal/Now/zonedDateTime/timezone-string-datetime.js +M test/built-ins/Temporal/Now/zonedDateTime/timezone-string-leap-second.js +M test/built-ins/Temporal/Now/zonedDateTime/timezone-string-multiple-offsets.js +M test/built-ins/Temporal/Now/zonedDateTime/timezone-string-year-zero.js +M test/built-ins/Temporal/Now/zonedDateTime/timezone-string.js +M test/built-ins/Temporal/Now/zonedDateTime/timezone-wrong-type.js +M test/built-ins/Temporal/Now/zonedDateTimeISO/return-value.js +M test/built-ins/Temporal/Now/zonedDateTimeISO/time-zone-undefined.js +M test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-case-insensitive.js +D test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-instance-does-not-get-timeZone-property.js +D test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-object-fail-call-tostring.js +D test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-object-fail-get-timezone.js +D test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-object-fail-has-nested-timezone.js +D test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-object-fail-has-timezone.js +M test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-object.js +M test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-string-datetime.js +M test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-string-leap-second.js +M test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-string-multiple-offsets.js +M test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-string-year-zero.js +M test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-string.js +M test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-wrong-type.js +M test/built-ins/Temporal/PlainDate/basic.js +M test/built-ins/Temporal/PlainDate/calendar-case-insensitive.js +D test/built-ins/Temporal/PlainDate/calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/PlainDate/calendar-number.js +M test/built-ins/Temporal/PlainDate/calendar-string.js M test/built-ins/Temporal/PlainDate/calendar-temporal-object.js -D test/built-ins/Temporal/PlainDate/compare/argument-calendar-fields-undefined.js -A test/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-case-insensitive.js -D test/built-ins/Temporal/PlainDate/from/argument-calendar-fields-undefined.js +M test/built-ins/Temporal/PlainDate/calendar-undefined.js +M test/built-ins/Temporal/PlainDate/calendar-wrong-type.js +M test/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-case-insensitive.js +D test/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-string.js +M test/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-wrong-type.js +M test/built-ins/Temporal/PlainDate/compare/argument-string-calendar-annotation.js +A test/built-ins/Temporal/PlainDate/compare/argument-string-multiple-calendar.js +M test/built-ins/Temporal/PlainDate/from/argument-plaindate.js +M test/built-ins/Temporal/PlainDate/from/argument-plaindatetime.js M test/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-case-insensitive.js -M test/built-ins/Temporal/PlainDate/prototype/day/validate-calendar-value.js -M test/built-ins/Temporal/PlainDate/prototype/dayOfWeek/validate-calendar-value.js -M test/built-ins/Temporal/PlainDate/prototype/dayOfYear/validate-calendar-value.js -M test/built-ins/Temporal/PlainDate/prototype/daysInMonth/validate-calendar-value.js -M test/built-ins/Temporal/PlainDate/prototype/daysInWeek/validate-calendar-value.js -M test/built-ins/Temporal/PlainDate/prototype/daysInYear/validate-calendar-value.js -D test/built-ins/Temporal/PlainDate/prototype/equals/argument-calendar-fields-undefined.js +D test/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-string.js +M test/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-wrong-type.js +M test/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar.js +M test/built-ins/Temporal/PlainDate/from/argument-string-calendar-annotation.js +A test/built-ins/Temporal/PlainDate/from/argument-string-multiple-calendar.js +M test/built-ins/Temporal/PlainDate/from/argument-zoneddatetime.js +M test/built-ins/Temporal/PlainDate/from/calendar-temporal-object.js +M test/built-ins/Temporal/PlainDate/from/order-of-operations.js +A test/built-ins/Temporal/PlainDate/prototype/add/builtin-calendar-no-observable-calls.js +D test/built-ins/Temporal/PlainDate/prototype/calendar/branding.js +A test/built-ins/Temporal/PlainDate/prototype/calendarId/branding.js +A test/built-ins/Temporal/PlainDate/prototype/calendarId/builtin-calendar-no-observable-calls.js +R072 test/built-ins/Temporal/PlainDate/prototype/calendar/prop-desc.js test/built-ins/Temporal/PlainDate/prototype/calendarId/prop-desc.js +A test/built-ins/Temporal/PlainDate/prototype/day/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainDate/prototype/dayOfWeek/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainDate/prototype/dayOfYear/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainDate/prototype/daysInMonth/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainDate/prototype/daysInWeek/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainDate/prototype/daysInYear/builtin-calendar-no-observable-calls.js +M test/built-ins/Temporal/PlainDate/prototype/equals/argument-object-valid.js M test/built-ins/Temporal/PlainDate/prototype/equals/argument-propertybag-calendar-case-insensitive.js -M test/built-ins/Temporal/PlainDate/prototype/inLeapYear/validate-calendar-value.js -M test/built-ins/Temporal/PlainDate/prototype/month/validate-calendar-value.js -M test/built-ins/Temporal/PlainDate/prototype/monthCode/validate-calendar-value.js -M test/built-ins/Temporal/PlainDate/prototype/monthsInYear/validate-calendar-value.js -D test/built-ins/Temporal/PlainDate/prototype/since/argument-calendar-fields-undefined.js +D test/built-ins/Temporal/PlainDate/prototype/equals/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/PlainDate/prototype/equals/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/PlainDate/prototype/equals/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/PlainDate/prototype/equals/argument-propertybag-calendar-wrong-type.js +M test/built-ins/Temporal/PlainDate/prototype/equals/argument-string-calendar-annotation.js +A test/built-ins/Temporal/PlainDate/prototype/equals/argument-string-multiple-calendar.js +M test/built-ins/Temporal/PlainDate/prototype/equals/argument-string.js +A test/built-ins/Temporal/PlainDate/prototype/equals/builtin-calendar-no-observable-calls.js +M test/built-ins/Temporal/PlainDate/prototype/equals/calendar-call-different.js +M test/built-ins/Temporal/PlainDate/prototype/equals/calendar-call-same.js +A test/built-ins/Temporal/PlainDate/prototype/getCalendar/branding.js +A test/built-ins/Temporal/PlainDate/prototype/getCalendar/builtin.js +A test/built-ins/Temporal/PlainDate/prototype/getCalendar/length.js +A test/built-ins/Temporal/PlainDate/prototype/getCalendar/name.js +A test/built-ins/Temporal/PlainDate/prototype/getCalendar/not-a-constructor.js +A test/built-ins/Temporal/PlainDate/prototype/getCalendar/prop-desc.js +M test/built-ins/Temporal/PlainDate/prototype/getISOFields/field-names.js +A test/built-ins/Temporal/PlainDate/prototype/inLeapYear/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainDate/prototype/month/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainDate/prototype/monthCode/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainDate/prototype/monthsInYear/builtin-calendar-no-observable-calls.js M test/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-case-insensitive.js +D test/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-wrong-type.js +M test/built-ins/Temporal/PlainDate/prototype/since/argument-string-calendar-annotation.js +A test/built-ins/Temporal/PlainDate/prototype/since/argument-string-multiple-calendar.js +A test/built-ins/Temporal/PlainDate/prototype/since/builtin-calendar-no-observable-calls.js +M test/built-ins/Temporal/PlainDate/prototype/since/calendar-mismatch.js M test/built-ins/Temporal/PlainDate/prototype/since/order-of-operations.js -M test/built-ins/Temporal/PlainDate/prototype/since/roundingincrement-non-integer.js -M test/built-ins/Temporal/PlainDate/prototype/since/roundingincrement-out-of-range.js -D test/built-ins/Temporal/PlainDate/prototype/toPlainMonthDay/calendar-fields-undefined.js -D test/built-ins/Temporal/PlainDate/prototype/toPlainYearMonth/calendar-fields-undefined.js -D test/built-ins/Temporal/PlainDate/prototype/until/argument-calendar-fields-undefined.js +A test/built-ins/Temporal/PlainDate/prototype/subtract/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainDate/prototype/toJSON/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainDate/prototype/toLocaleString/builtin-calendar-no-observable-calls.js +M test/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/argument-string-calendar-annotation.js +A test/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/argument-string-multiple-calendar.js +D test/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/calendar-temporal-object.js +M test/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/custom.js +M test/built-ins/Temporal/PlainDate/prototype/toPlainMonthDay/basic.js +A test/built-ins/Temporal/PlainDate/prototype/toPlainMonthDay/builtin-calendar-no-observable-calls.js +M test/built-ins/Temporal/PlainDate/prototype/toPlainYearMonth/basic.js +A test/built-ins/Temporal/PlainDate/prototype/toPlainYearMonth/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainDate/prototype/toString/builtin-calendar-no-observable-calls.js +M test/built-ins/Temporal/PlainDate/prototype/toString/calendar-tostring.js +M test/built-ins/Temporal/PlainDate/prototype/toString/calendarname-always.js +M test/built-ins/Temporal/PlainDate/prototype/toString/calendarname-auto.js +M test/built-ins/Temporal/PlainDate/prototype/toString/calendarname-critical.js +M test/built-ins/Temporal/PlainDate/prototype/toString/calendarname-never.js +M test/built-ins/Temporal/PlainDate/prototype/toString/calendarname-undefined.js +M test/built-ins/Temporal/PlainDate/prototype/toString/calendarname-wrong-type.js +M test/built-ins/Temporal/PlainDate/prototype/toString/options-undefined.js +M test/built-ins/Temporal/PlainDate/prototype/toString/order-of-operations.js +M test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/argument-string-calendar-annotation.js +A test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/argument-string-multiple-calendar.js +D test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/calendar-temporal-object.js +M test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/calendar.js +M test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-case-insensitive.js +M test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-getpossibleinstantsfor.js +D test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-instance-does-not-get-timeZone-property.js +M test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-string-datetime.js +M test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-string-leap-second.js +M test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-string-multiple-offsets.js +M test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-string-year-zero.js +M test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-string.js +M test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-wrong-type.js M test/built-ins/Temporal/PlainDate/prototype/until/argument-propertybag-calendar-case-insensitive.js +D test/built-ins/Temporal/PlainDate/prototype/until/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/PlainDate/prototype/until/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/PlainDate/prototype/until/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/PlainDate/prototype/until/argument-propertybag-calendar-wrong-type.js +M test/built-ins/Temporal/PlainDate/prototype/until/argument-string-calendar-annotation.js +A test/built-ins/Temporal/PlainDate/prototype/until/argument-string-multiple-calendar.js +A test/built-ins/Temporal/PlainDate/prototype/until/builtin-calendar-no-observable-calls.js +M test/built-ins/Temporal/PlainDate/prototype/until/calendar-mismatch.js M test/built-ins/Temporal/PlainDate/prototype/until/order-of-operations.js -M test/built-ins/Temporal/PlainDate/prototype/until/roundingincrement-non-integer.js -M test/built-ins/Temporal/PlainDate/prototype/until/roundingincrement-out-of-range.js -M test/built-ins/Temporal/PlainDate/prototype/weekOfYear/validate-calendar-value.js -D test/built-ins/Temporal/PlainDate/prototype/with/calendar-fields-undefined.js -M test/built-ins/Temporal/PlainDate/prototype/with/order-of-operations.js +A test/built-ins/Temporal/PlainDate/prototype/weekOfYear/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainDate/prototype/with/builtin-calendar-no-observable-calls.js +M test/built-ins/Temporal/PlainDate/prototype/withCalendar/basic.js +A test/built-ins/Temporal/PlainDate/prototype/withCalendar/builtin-calendar-no-observable-calls.js M test/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-case-insensitive.js +D test/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-number.js +M test/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-string-leap-second.js +M test/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-string.js M test/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-temporal-object.js -M test/built-ins/Temporal/PlainDate/prototype/year/validate-calendar-value.js -M test/built-ins/Temporal/PlainDate/prototype/yearOfWeek/validate-calendar-value.js +M test/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-wrong-type.js +M test/built-ins/Temporal/PlainDate/prototype/withCalendar/subclassing-ignored.js +A test/built-ins/Temporal/PlainDate/prototype/year/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainDate/prototype/yearOfWeek/builtin-calendar-no-observable-calls.js +M test/built-ins/Temporal/PlainDateTime/calendar-case-insensitive.js +D test/built-ins/Temporal/PlainDateTime/calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/PlainDateTime/calendar-number.js +M test/built-ins/Temporal/PlainDateTime/calendar-string.js M test/built-ins/Temporal/PlainDateTime/calendar-temporal-object.js -D test/built-ins/Temporal/PlainDateTime/compare/argument-calendar-fields-undefined.js -A test/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-case-insensitive.js -D test/built-ins/Temporal/PlainDateTime/from/argument-calendar-fields-undefined.js +M test/built-ins/Temporal/PlainDateTime/calendar-undefined.js +M test/built-ins/Temporal/PlainDateTime/calendar-wrong-type.js +M test/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-case-insensitive.js +D test/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-string.js +M test/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-wrong-type.js +M test/built-ins/Temporal/PlainDateTime/compare/argument-string-calendar-annotation.js +A test/built-ins/Temporal/PlainDateTime/compare/argument-string-multiple-calendar.js +M test/built-ins/Temporal/PlainDateTime/compare/calendar-ignored.js +M test/built-ins/Temporal/PlainDateTime/constructor-full.js +M test/built-ins/Temporal/PlainDateTime/from/argument-plaindate.js +M test/built-ins/Temporal/PlainDateTime/from/argument-plaindatetime.js M test/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-case-insensitive.js -M test/built-ins/Temporal/PlainDateTime/prototype/day/validate-calendar-value.js -M test/built-ins/Temporal/PlainDateTime/prototype/dayOfWeek/validate-calendar-value.js -M test/built-ins/Temporal/PlainDateTime/prototype/dayOfYear/validate-calendar-value.js -M test/built-ins/Temporal/PlainDateTime/prototype/daysInMonth/validate-calendar-value.js -M test/built-ins/Temporal/PlainDateTime/prototype/daysInWeek/validate-calendar-value.js -M test/built-ins/Temporal/PlainDateTime/prototype/daysInYear/validate-calendar-value.js -D test/built-ins/Temporal/PlainDateTime/prototype/equals/argument-calendar-fields-undefined.js +D test/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-string.js +M test/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-wrong-type.js +M test/built-ins/Temporal/PlainDateTime/from/argument-string-calendar-annotation.js +A test/built-ins/Temporal/PlainDateTime/from/argument-string-multiple-calendar.js +M test/built-ins/Temporal/PlainDateTime/from/calendar-temporal-object.js +M test/built-ins/Temporal/PlainDateTime/from/order-of-operations.js +A test/built-ins/Temporal/PlainDateTime/prototype/add/builtin-calendar-no-observable-calls.js +D test/built-ins/Temporal/PlainDateTime/prototype/calendar/branding.js +A test/built-ins/Temporal/PlainDateTime/prototype/calendarId/branding.js +A test/built-ins/Temporal/PlainDateTime/prototype/calendarId/builtin-calendar-no-observable-calls.js +R071 test/built-ins/Temporal/PlainTime/prototype/calendar/prop-desc.js test/built-ins/Temporal/PlainDateTime/prototype/calendarId/prop-desc.js +A test/built-ins/Temporal/PlainDateTime/prototype/day/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainDateTime/prototype/dayOfWeek/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainDateTime/prototype/dayOfYear/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainDateTime/prototype/daysInMonth/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainDateTime/prototype/daysInWeek/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainDateTime/prototype/daysInYear/builtin-calendar-no-observable-calls.js M test/built-ins/Temporal/PlainDateTime/prototype/equals/argument-propertybag-calendar-case-insensitive.js -M test/built-ins/Temporal/PlainDateTime/prototype/inLeapYear/validate-calendar-value.js -M test/built-ins/Temporal/PlainDateTime/prototype/month/validate-calendar-value.js -M test/built-ins/Temporal/PlainDateTime/prototype/monthCode/validate-calendar-value.js -M test/built-ins/Temporal/PlainDateTime/prototype/monthsInYear/validate-calendar-value.js -M test/built-ins/Temporal/PlainDateTime/prototype/round/roundingincrement-non-integer.js -M test/built-ins/Temporal/PlainDateTime/prototype/round/roundingincrement-out-of-range.js -D test/built-ins/Temporal/PlainDateTime/prototype/since/argument-calendar-fields-undefined.js +D test/built-ins/Temporal/PlainDateTime/prototype/equals/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/PlainDateTime/prototype/equals/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/PlainDateTime/prototype/equals/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/PlainDateTime/prototype/equals/argument-propertybag-calendar-wrong-type.js +M test/built-ins/Temporal/PlainDateTime/prototype/equals/argument-string-calendar-annotation.js +A test/built-ins/Temporal/PlainDateTime/prototype/equals/argument-string-multiple-calendar.js +A test/built-ins/Temporal/PlainDateTime/prototype/equals/builtin-calendar-no-observable-calls.js +M test/built-ins/Temporal/PlainDateTime/prototype/equals/calendar-checked.js +A test/built-ins/Temporal/PlainDateTime/prototype/getCalendar/branding.js +A test/built-ins/Temporal/PlainDateTime/prototype/getCalendar/builtin.js +A test/built-ins/Temporal/PlainDateTime/prototype/getCalendar/length.js +A test/built-ins/Temporal/PlainDateTime/prototype/getCalendar/name.js +A test/built-ins/Temporal/PlainDateTime/prototype/getCalendar/not-a-constructor.js +A test/built-ins/Temporal/PlainDateTime/prototype/getCalendar/prop-desc.js +M test/built-ins/Temporal/PlainDateTime/prototype/getISOFields/field-names.js +A test/built-ins/Temporal/PlainDateTime/prototype/inLeapYear/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainDateTime/prototype/month/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainDateTime/prototype/monthCode/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainDateTime/prototype/monthsInYear/builtin-calendar-no-observable-calls.js M test/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-case-insensitive.js +D test/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-wrong-type.js +M test/built-ins/Temporal/PlainDateTime/prototype/since/argument-string-calendar-annotation.js +A test/built-ins/Temporal/PlainDateTime/prototype/since/argument-string-multiple-calendar.js +A test/built-ins/Temporal/PlainDateTime/prototype/since/builtin-calendar-no-observable-calls.js +M test/built-ins/Temporal/PlainDateTime/prototype/since/calendar-dateuntil-called-with-plaindate-calendar.js +M test/built-ins/Temporal/PlainDateTime/prototype/since/different-calendars-throws.js M test/built-ins/Temporal/PlainDateTime/prototype/since/order-of-operations.js -M test/built-ins/Temporal/PlainDateTime/prototype/since/roundingincrement-non-integer.js -M test/built-ins/Temporal/PlainDateTime/prototype/since/roundingincrement-out-of-range.js -D test/built-ins/Temporal/PlainDateTime/prototype/toPlainMonthDay/calendar-fields-undefined.js -D test/built-ins/Temporal/PlainDateTime/prototype/toPlainYearMonth/calendar-fields-undefined.js -D test/built-ins/Temporal/PlainDateTime/prototype/until/argument-calendar-fields-undefined.js +A test/built-ins/Temporal/PlainDateTime/prototype/subtract/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainDateTime/prototype/toJSON/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainDateTime/prototype/toLocaleString/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainDateTime/prototype/toPlainMonthDay/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainDateTime/prototype/toPlainYearMonth/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainDateTime/prototype/toString/builtin-calendar-no-observable-calls.js +M test/built-ins/Temporal/PlainDateTime/prototype/toString/calendar-tostring.js +M test/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-always.js +M test/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-auto.js +M test/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-critical.js +M test/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-never.js +M test/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-undefined.js +M test/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-wrong-type.js +M test/built-ins/Temporal/PlainDateTime/prototype/toString/options-undefined.js +M test/built-ins/Temporal/PlainDateTime/prototype/toString/order-of-operations.js +M test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/basic.js +M test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/order-of-operations.js +M test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/plain-custom-timezone.js +M test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-case-insensitive.js +D test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-instance-does-not-get-timeZone-property.js +M test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-string-datetime.js +M test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-string-leap-second.js +M test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-string-multiple-offsets.js +M test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-string-year-zero.js +M test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-string.js +M test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-wrong-type.js M test/built-ins/Temporal/PlainDateTime/prototype/until/argument-propertybag-calendar-case-insensitive.js +D test/built-ins/Temporal/PlainDateTime/prototype/until/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/PlainDateTime/prototype/until/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/PlainDateTime/prototype/until/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/PlainDateTime/prototype/until/argument-propertybag-calendar-wrong-type.js +M test/built-ins/Temporal/PlainDateTime/prototype/until/argument-string-calendar-annotation.js +A test/built-ins/Temporal/PlainDateTime/prototype/until/argument-string-multiple-calendar.js +A test/built-ins/Temporal/PlainDateTime/prototype/until/builtin-calendar-no-observable-calls.js +M test/built-ins/Temporal/PlainDateTime/prototype/until/calendar-dateuntil-called-with-plaindate-calendar.js +M test/built-ins/Temporal/PlainDateTime/prototype/until/different-calendars-throws.js M test/built-ins/Temporal/PlainDateTime/prototype/until/order-of-operations.js -M test/built-ins/Temporal/PlainDateTime/prototype/until/roundingincrement-non-integer.js -M test/built-ins/Temporal/PlainDateTime/prototype/until/roundingincrement-out-of-range.js -M test/built-ins/Temporal/PlainDateTime/prototype/weekOfYear/validate-calendar-value.js -D test/built-ins/Temporal/PlainDateTime/prototype/with/calendar-fields-undefined.js +A test/built-ins/Temporal/PlainDateTime/prototype/weekOfYear/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainDateTime/prototype/with/builtin-calendar-no-observable-calls.js M test/built-ins/Temporal/PlainDateTime/prototype/with/order-of-operations.js +M test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/argument-string.js +M test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/basic.js +A test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/builtin-calendar-no-observable-calls.js M test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-case-insensitive.js +D test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-number.js +M test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-string-leap-second.js +M test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-string.js M test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-temporal-object.js -D test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-calendar-fields-undefined.js +M test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-wrong-type.js +M test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/subclassing-ignored.js +M test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-noniso.js +M test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-same-id.js +M test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-same-object.js +M test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar.js M test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-propertybag-calendar-case-insensitive.js -M test/built-ins/Temporal/PlainDateTime/prototype/year/validate-calendar-value.js -M test/built-ins/Temporal/PlainDateTime/prototype/yearOfWeek/validate-calendar-value.js +D test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-propertybag-calendar-wrong-type.js +M test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-string-calendar-annotation.js +M test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-string-iso-calendar.js +A test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-string-multiple-calendar.js +A test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/builtin-calendar-no-observable-calls.js +M test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/calendar-temporal-object.js +M test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/non-compatible-calendars-throw.js +M test/built-ins/Temporal/PlainDateTime/prototype/withPlainTime/argument-string-calendar-annotation.js +A test/built-ins/Temporal/PlainDateTime/prototype/withPlainTime/argument-string-multiple-calendar.js +D test/built-ins/Temporal/PlainDateTime/prototype/withPlainTime/calendar-temporal-object.js +A test/built-ins/Temporal/PlainDateTime/prototype/year/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainDateTime/prototype/yearOfWeek/builtin-calendar-no-observable-calls.js +M test/built-ins/Temporal/PlainMonthDay/basic.js +M test/built-ins/Temporal/PlainMonthDay/calendar-case-insensitive.js +D test/built-ins/Temporal/PlainMonthDay/calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/PlainMonthDay/calendar-number.js +M test/built-ins/Temporal/PlainMonthDay/calendar-string.js M test/built-ins/Temporal/PlainMonthDay/calendar-temporal-object.js -D test/built-ins/Temporal/PlainMonthDay/from/argument-calendar-fields-undefined.js +M test/built-ins/Temporal/PlainMonthDay/calendar-undefined.js +M test/built-ins/Temporal/PlainMonthDay/calendar-wrong-type.js +M test/built-ins/Temporal/PlainMonthDay/from/argument-plainmonthday.js M test/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-case-insensitive.js -M test/built-ins/Temporal/PlainMonthDay/prototype/day/validate-calendar-value.js -D test/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-calendar-fields-undefined.js +D test/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-string.js +M test/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-wrong-type.js +M test/built-ins/Temporal/PlainMonthDay/from/argument-string-calendar-annotation.js +A test/built-ins/Temporal/PlainMonthDay/from/argument-string-multiple-calendar.js +D test/built-ins/Temporal/PlainMonthDay/from/calendar-monthdayfromfields-called-with-options-undefined.js +M test/built-ins/Temporal/PlainMonthDay/from/calendar-temporal-object.js +M test/built-ins/Temporal/PlainMonthDay/from/fields-object.js +M test/built-ins/Temporal/PlainMonthDay/from/fields-string.js +M test/built-ins/Temporal/PlainMonthDay/from/order-of-operations.js +D test/built-ins/Temporal/PlainMonthDay/prototype/calendar/branding.js +A test/built-ins/Temporal/PlainMonthDay/prototype/calendarId/branding.js +A test/built-ins/Temporal/PlainMonthDay/prototype/calendarId/builtin-calendar-no-observable-calls.js +R071 test/built-ins/Temporal/PlainDateTime/prototype/calendar/prop-desc.js test/built-ins/Temporal/PlainMonthDay/prototype/calendarId/prop-desc.js +A test/built-ins/Temporal/PlainMonthDay/prototype/day/builtin-calendar-no-observable-calls.js M test/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-case-insensitive.js -M test/built-ins/Temporal/PlainMonthDay/prototype/monthCode/validate-calendar-value.js -D test/built-ins/Temporal/PlainMonthDay/prototype/toPlainDate/calendar-fields-undefined.js -D test/built-ins/Temporal/PlainMonthDay/prototype/with/calendar-fields-undefined.js -M test/built-ins/Temporal/PlainMonthDay/prototype/with/order-of-operations.js -M test/built-ins/Temporal/PlainTime/prototype/round/roundingincrement-non-integer.js -M test/built-ins/Temporal/PlainTime/prototype/round/roundingincrement-out-of-range.js +D test/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-wrong-type.js +M test/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-string-calendar-annotation.js +A test/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-string-multiple-calendar.js +A test/built-ins/Temporal/PlainMonthDay/prototype/equals/builtin-calendar-no-observable-calls.js +M test/built-ins/Temporal/PlainMonthDay/prototype/equals/calendar-monthdayfromfields-called-with-options-undefined.js +M test/built-ins/Temporal/PlainMonthDay/prototype/equals/calendars.js +A test/built-ins/Temporal/PlainMonthDay/prototype/getCalendar/branding.js +A test/built-ins/Temporal/PlainMonthDay/prototype/getCalendar/builtin.js +A test/built-ins/Temporal/PlainMonthDay/prototype/getCalendar/length.js +A test/built-ins/Temporal/PlainMonthDay/prototype/getCalendar/name.js +A test/built-ins/Temporal/PlainMonthDay/prototype/getCalendar/not-a-constructor.js +A test/built-ins/Temporal/PlainMonthDay/prototype/getCalendar/prop-desc.js +M test/built-ins/Temporal/PlainMonthDay/prototype/getISOFields/field-names.js +A test/built-ins/Temporal/PlainMonthDay/prototype/monthCode/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainMonthDay/prototype/toJSON/builtin-calendar-no-observable-calls.js +M test/built-ins/Temporal/PlainMonthDay/prototype/toJSON/calendarname.js +M test/built-ins/Temporal/PlainMonthDay/prototype/toJSON/year-format.js +A test/built-ins/Temporal/PlainMonthDay/prototype/toLocaleString/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainMonthDay/prototype/toPlainDate/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainMonthDay/prototype/toString/builtin-calendar-no-observable-calls.js +M test/built-ins/Temporal/PlainMonthDay/prototype/toString/calendar-tostring.js +M test/built-ins/Temporal/PlainMonthDay/prototype/toString/calendarname-always.js +M test/built-ins/Temporal/PlainMonthDay/prototype/toString/calendarname-auto.js +M test/built-ins/Temporal/PlainMonthDay/prototype/toString/calendarname-critical.js +M test/built-ins/Temporal/PlainMonthDay/prototype/toString/calendarname-never.js +M test/built-ins/Temporal/PlainMonthDay/prototype/toString/calendarname-undefined.js +M test/built-ins/Temporal/PlainMonthDay/prototype/toString/calendarname-wrong-type.js +M test/built-ins/Temporal/PlainMonthDay/prototype/toString/options-undefined.js +M test/built-ins/Temporal/PlainMonthDay/prototype/toString/order-of-operations.js +M test/built-ins/Temporal/PlainMonthDay/prototype/toString/year-format.js +A test/built-ins/Temporal/PlainMonthDay/prototype/with/builtin-calendar-no-observable-calls.js +M test/built-ins/Temporal/PlainTime/basic.js +M test/built-ins/Temporal/PlainTime/compare/argument-string-calendar-annotation.js +A test/built-ins/Temporal/PlainTime/compare/argument-string-multiple-calendar.js +D test/built-ins/Temporal/PlainTime/compare/calendar-temporal-object.js +M test/built-ins/Temporal/PlainTime/from/argument-string-calendar-annotation.js +A test/built-ins/Temporal/PlainTime/from/argument-string-multiple-calendar.js +D test/built-ins/Temporal/PlainTime/from/argument-string-with-calendar.js +D test/built-ins/Temporal/PlainTime/from/calendar-temporal-object.js +M test/built-ins/Temporal/PlainTime/from/order-of-operations.js +M test/built-ins/Temporal/PlainTime/prototype/add/order-of-operations.js +D test/built-ins/Temporal/PlainTime/prototype/calendar/basic.js +D test/built-ins/Temporal/PlainTime/prototype/calendar/branding.js +M test/built-ins/Temporal/PlainTime/prototype/equals/argument-string-calendar-annotation.js +A test/built-ins/Temporal/PlainTime/prototype/equals/argument-string-multiple-calendar.js +D test/built-ins/Temporal/PlainTime/prototype/equals/calendar-temporal-object.js +D test/built-ins/Temporal/PlainTime/prototype/getISOFields/custom.js +M test/built-ins/Temporal/PlainTime/prototype/getISOFields/field-names.js +M test/built-ins/Temporal/PlainTime/prototype/getISOFields/field-prop-desc.js +M test/built-ins/Temporal/PlainTime/prototype/getISOFields/field-traversal-order.js +M test/built-ins/Temporal/PlainTime/prototype/since/argument-string-calendar-annotation.js +A test/built-ins/Temporal/PlainTime/prototype/since/argument-string-multiple-calendar.js +D test/built-ins/Temporal/PlainTime/prototype/since/calendar-temporal-object.js M test/built-ins/Temporal/PlainTime/prototype/since/order-of-operations.js -M test/built-ins/Temporal/PlainTime/prototype/since/roundingincrement-non-integer.js -M test/built-ins/Temporal/PlainTime/prototype/since/roundingincrement-out-of-range.js -D test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-calendar-fields-undefined.js +M test/built-ins/Temporal/PlainTime/prototype/subtract/order-of-operations.js M test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-propertybag-calendar-case-insensitive.js -D test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-calendar-fields-undefined.js +D test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-propertybag-calendar-wrong-type.js +M test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-string-calendar-annotation.js +A test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-string-multiple-calendar.js +M test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/calendar-temporal-object.js M test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-propertybag-calendar-case-insensitive.js +D test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-propertybag-calendar-wrong-type.js +M test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-string-calendar-annotation.js +A test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-string-multiple-calendar.js +M test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/basic.js +M test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/calendar-temporal-object.js +M test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-case-insensitive.js +D test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-instance-does-not-get-timeZone-property.js +M test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-string-datetime.js +M test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-string-leap-second.js +M test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-string-multiple-offsets.js +M test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-string-year-zero.js +M test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-string.js +M test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-wrong-type.js +M test/built-ins/Temporal/PlainTime/prototype/until/argument-string-calendar-annotation.js +A test/built-ins/Temporal/PlainTime/prototype/until/argument-string-multiple-calendar.js +D test/built-ins/Temporal/PlainTime/prototype/until/calendar-temporal-object.js M test/built-ins/Temporal/PlainTime/prototype/until/order-of-operations.js -M test/built-ins/Temporal/PlainTime/prototype/until/roundingincrement-non-integer.js -M test/built-ins/Temporal/PlainTime/prototype/until/roundingincrement-out-of-range.js -M test/built-ins/Temporal/PlainTime/prototype/with/order-of-operations.js +M test/built-ins/Temporal/PlainYearMonth/calendar-case-insensitive.js +D test/built-ins/Temporal/PlainYearMonth/calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/PlainYearMonth/calendar-number.js +M test/built-ins/Temporal/PlainYearMonth/calendar-string.js M test/built-ins/Temporal/PlainYearMonth/calendar-temporal-object.js -D test/built-ins/Temporal/PlainYearMonth/compare/argument-calendar-fields-undefined.js -A test/built-ins/Temporal/PlainYearMonth/compare/argument-propertybag-calendar-case-insensitive.js -D test/built-ins/Temporal/PlainYearMonth/from/argument-calendar-fields-undefined.js +M test/built-ins/Temporal/PlainYearMonth/calendar-undefined.js +M test/built-ins/Temporal/PlainYearMonth/calendar-wrong-type.js +M test/built-ins/Temporal/PlainYearMonth/compare/argument-propertybag-calendar-case-insensitive.js +D test/built-ins/Temporal/PlainYearMonth/compare/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +A test/built-ins/Temporal/PlainYearMonth/compare/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/PlainYearMonth/compare/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/PlainYearMonth/compare/argument-propertybag-calendar-string.js +M test/built-ins/Temporal/PlainYearMonth/compare/argument-propertybag-calendar-wrong-type.js +M test/built-ins/Temporal/PlainYearMonth/compare/argument-string-calendar-annotation.js +A test/built-ins/Temporal/PlainYearMonth/compare/argument-string-multiple-calendar.js +M test/built-ins/Temporal/PlainYearMonth/compare/calendar-yearmonthfromfields-called-with-options-undefined.js +M test/built-ins/Temporal/PlainYearMonth/from/argument-plaindate.js +M test/built-ins/Temporal/PlainYearMonth/from/argument-plainyearmonth.js M test/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-case-insensitive.js -D test/built-ins/Temporal/PlainYearMonth/prototype/add/calendar-fields-undefined.js -M test/built-ins/Temporal/PlainYearMonth/prototype/daysInMonth/validate-calendar-value.js -M test/built-ins/Temporal/PlainYearMonth/prototype/daysInYear/validate-calendar-value.js -D test/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-calendar-fields-undefined.js +D test/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-string.js +M test/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-wrong-type.js +M test/built-ins/Temporal/PlainYearMonth/from/argument-string-calendar-annotation.js +A test/built-ins/Temporal/PlainYearMonth/from/argument-string-multiple-calendar.js +M test/built-ins/Temporal/PlainYearMonth/from/argument-string.js +M test/built-ins/Temporal/PlainYearMonth/from/calendar-temporal-object.js +D test/built-ins/Temporal/PlainYearMonth/from/calendar-yearmonthfromfields-called-with-options-undefined.js +M test/built-ins/Temporal/PlainYearMonth/from/order-of-operations.js +A test/built-ins/Temporal/PlainYearMonth/prototype/add/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainYearMonth/prototype/add/calendar-dateadd-called-with-plaindate-instance.js +M test/built-ins/Temporal/PlainYearMonth/prototype/add/calendar-datefromfields-called.js +D test/built-ins/Temporal/PlainYearMonth/prototype/add/calendar-daysinmonth-wrong-value.js +A test/built-ins/Temporal/PlainYearMonth/prototype/add/custom-daysInMonth-irrelevant.js +M test/built-ins/Temporal/PlainYearMonth/prototype/add/order-of-operations.js +D test/built-ins/Temporal/PlainYearMonth/prototype/calendar/branding.js +D test/built-ins/Temporal/PlainYearMonth/prototype/calendar/prop-desc.js +A test/built-ins/Temporal/PlainYearMonth/prototype/calendarId/branding.js +A test/built-ins/Temporal/PlainYearMonth/prototype/calendarId/builtin-calendar-no-observable-calls.js +R070 test/built-ins/Temporal/PlainMonthDay/prototype/calendar/prop-desc.js test/built-ins/Temporal/PlainYearMonth/prototype/calendarId/prop-desc.js +A test/built-ins/Temporal/PlainYearMonth/prototype/daysInMonth/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainYearMonth/prototype/daysInYear/builtin-calendar-no-observable-calls.js M test/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-case-insensitive.js -M test/built-ins/Temporal/PlainYearMonth/prototype/inLeapYear/validate-calendar-value.js -M test/built-ins/Temporal/PlainYearMonth/prototype/month/validate-calendar-value.js -M test/built-ins/Temporal/PlainYearMonth/prototype/monthCode/validate-calendar-value.js -M test/built-ins/Temporal/PlainYearMonth/prototype/monthsInYear/validate-calendar-value.js +D test/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-wrong-type.js +M test/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-string-calendar-annotation.js +A test/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-string-multiple-calendar.js +A test/built-ins/Temporal/PlainYearMonth/prototype/equals/builtin-calendar-no-observable-calls.js +M test/built-ins/Temporal/PlainYearMonth/prototype/equals/calendar-yearmonthfromfields-called-with-options-undefined.js +M test/built-ins/Temporal/PlainYearMonth/prototype/equals/compare-calendar.js +A test/built-ins/Temporal/PlainYearMonth/prototype/getCalendar/branding.js +A test/built-ins/Temporal/PlainYearMonth/prototype/getCalendar/builtin.js +A test/built-ins/Temporal/PlainYearMonth/prototype/getCalendar/length.js +A test/built-ins/Temporal/PlainYearMonth/prototype/getCalendar/name.js +A test/built-ins/Temporal/PlainYearMonth/prototype/getCalendar/not-a-constructor.js +A test/built-ins/Temporal/PlainYearMonth/prototype/getCalendar/prop-desc.js +M test/built-ins/Temporal/PlainYearMonth/prototype/getISOFields/field-names.js +A test/built-ins/Temporal/PlainYearMonth/prototype/inLeapYear/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainYearMonth/prototype/month/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainYearMonth/prototype/monthCode/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainYearMonth/prototype/monthsInYear/builtin-calendar-no-observable-calls.js M test/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-case-insensitive.js -D test/built-ins/Temporal/PlainYearMonth/prototype/since/calendar-fields-undefined.js +D test/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-wrong-type.js +M test/built-ins/Temporal/PlainYearMonth/prototype/since/argument-string-calendar-annotation.js +A test/built-ins/Temporal/PlainYearMonth/prototype/since/argument-string-multiple-calendar.js +A test/built-ins/Temporal/PlainYearMonth/prototype/since/builtin-calendar-no-observable-calls.js +M test/built-ins/Temporal/PlainYearMonth/prototype/since/calendar-yearmonthfromfields-called-with-options-undefined.js +M test/built-ins/Temporal/PlainYearMonth/prototype/since/mixed-calendar-invalid.js M test/built-ins/Temporal/PlainYearMonth/prototype/since/order-of-operations.js -M test/built-ins/Temporal/PlainYearMonth/prototype/since/roundingincrement-non-integer.js -M test/built-ins/Temporal/PlainYearMonth/prototype/since/roundingincrement-out-of-range.js -D test/built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-fields-undefined.js -D test/built-ins/Temporal/PlainYearMonth/prototype/toPlainDate/calendar-fields-undefined.js +A test/built-ins/Temporal/PlainYearMonth/prototype/subtract/builtin-calendar-no-observable-calls.js +M test/built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-arguments-extra-options.js +M test/built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-arguments.js +A test/built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-dateadd-called-with-plaindate-instance.js +M test/built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-dateadd.js +M test/built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-datefromfields-called.js +D test/built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-daysinmonth-wrong-value.js +M test/built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-fromfields-called-with-null-prototype-fields.js +A test/built-ins/Temporal/PlainYearMonth/prototype/subtract/custom-daysInMonth-irrelevant.js +M test/built-ins/Temporal/PlainYearMonth/prototype/subtract/options-undefined.js +M test/built-ins/Temporal/PlainYearMonth/prototype/subtract/order-of-operations.js +A test/built-ins/Temporal/PlainYearMonth/prototype/toJSON/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainYearMonth/prototype/toLocaleString/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainYearMonth/prototype/toPlainDate/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainYearMonth/prototype/toString/builtin-calendar-no-observable-calls.js +M test/built-ins/Temporal/PlainYearMonth/prototype/toString/calendar-tostring.js +M test/built-ins/Temporal/PlainYearMonth/prototype/toString/calendarname-always.js +M test/built-ins/Temporal/PlainYearMonth/prototype/toString/calendarname-auto.js +M test/built-ins/Temporal/PlainYearMonth/prototype/toString/calendarname-critical.js +M test/built-ins/Temporal/PlainYearMonth/prototype/toString/calendarname-never.js +M test/built-ins/Temporal/PlainYearMonth/prototype/toString/calendarname-undefined.js +M test/built-ins/Temporal/PlainYearMonth/prototype/toString/calendarname-wrong-type.js +M test/built-ins/Temporal/PlainYearMonth/prototype/toString/options-undefined.js +M test/built-ins/Temporal/PlainYearMonth/prototype/toString/order-of-operations.js M test/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-case-insensitive.js -D test/built-ins/Temporal/PlainYearMonth/prototype/until/calendar-fields-undefined.js +D test/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-wrong-type.js +M test/built-ins/Temporal/PlainYearMonth/prototype/until/argument-string-calendar-annotation.js +A test/built-ins/Temporal/PlainYearMonth/prototype/until/argument-string-multiple-calendar.js +A test/built-ins/Temporal/PlainYearMonth/prototype/until/builtin-calendar-no-observable-calls.js +M test/built-ins/Temporal/PlainYearMonth/prototype/until/calendar-yearmonthfromfields-called-with-options-undefined.js +M test/built-ins/Temporal/PlainYearMonth/prototype/until/mixed-calendar-invalid.js M test/built-ins/Temporal/PlainYearMonth/prototype/until/order-of-operations.js -M test/built-ins/Temporal/PlainYearMonth/prototype/until/roundingincrement-non-integer.js -M test/built-ins/Temporal/PlainYearMonth/prototype/until/roundingincrement-out-of-range.js -D test/built-ins/Temporal/PlainYearMonth/prototype/with/calendar-fields-undefined.js -M test/built-ins/Temporal/PlainYearMonth/prototype/with/order-of-operations.js -M test/built-ins/Temporal/PlainYearMonth/prototype/year/validate-calendar-value.js -D test/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-calendar-fields-undefined.js +A test/built-ins/Temporal/PlainYearMonth/prototype/with/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/PlainYearMonth/prototype/year/builtin-calendar-no-observable-calls.js +D test/built-ins/Temporal/TimeZone/from/argument-object-invalid.js +M test/built-ins/Temporal/TimeZone/from/argument-object.js +D test/built-ins/Temporal/TimeZone/from/timezone-instance-does-not-get-timeZone-property.js +M test/built-ins/Temporal/TimeZone/from/timezone-string-datetime.js +M test/built-ins/Temporal/TimeZone/from/timezone-string-leap-second.js +M test/built-ins/Temporal/TimeZone/from/timezone-string-multiple-offsets.js +M test/built-ins/Temporal/TimeZone/from/timezone-string-year-zero.js +M test/built-ins/Temporal/TimeZone/from/timezone-string.js +M test/built-ins/Temporal/TimeZone/from/timezone-wrong-type.js M test/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-case-insensitive.js +D test/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-wrong-type.js +M test/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-string-calendar-annotation.js +A test/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-string-multiple-calendar.js +M test/built-ins/Temporal/TimeZone/prototype/getInstantFor/order-of-operations.js +M test/built-ins/Temporal/TimeZone/prototype/getNextTransition/argument-string-calendar-annotation.js +A test/built-ins/Temporal/TimeZone/prototype/getNextTransition/argument-string-multiple-calendar.js +M test/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/argument-string-calendar-annotation.js +A test/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/argument-string-multiple-calendar.js +M test/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-string-calendar-annotation.js +A test/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-string-multiple-calendar.js +M test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-string-calendar-annotation.js +A test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-string-multiple-calendar.js M test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-case-insensitive.js +D test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-number.js +M test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-string-leap-second.js +M test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-string.js M test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-temporal-object.js -D test/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-calendar-fields-undefined.js +M test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-undefined.js +M test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-wrong-type.js M test/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-case-insensitive.js +D test/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-wrong-type.js +M test/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-string-calendar-annotation.js +A test/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-string-multiple-calendar.js +M test/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/fixed-offset-near-date-time-limits.js +M test/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/argument-string-calendar-annotation.js +A test/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/argument-string-multiple-calendar.js +R067 test/built-ins/Temporal/TimeZone/prototype/toJSON/tostring-call.js test/built-ins/Temporal/TimeZone/prototype/toJSON/returns-identifier-slot.js +D test/built-ins/Temporal/TimeZone/prototype/toJSON/tostring-undefined-custom.js +D test/built-ins/Temporal/TimeZone/prototype/toJSON/tostring-undefined.js +M test/built-ins/Temporal/ZonedDateTime/calendar-case-insensitive.js +D test/built-ins/Temporal/ZonedDateTime/calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/ZonedDateTime/calendar-number.js +M test/built-ins/Temporal/ZonedDateTime/calendar-string.js M test/built-ins/Temporal/ZonedDateTime/calendar-temporal-object.js -D test/built-ins/Temporal/ZonedDateTime/compare/argument-calendar-fields-undefined.js -A test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-case-insensitive.js -D test/built-ins/Temporal/ZonedDateTime/from/argument-calendar-fields-undefined.js +M test/built-ins/Temporal/ZonedDateTime/calendar-undefined.js +M test/built-ins/Temporal/ZonedDateTime/calendar-wrong-type.js +M test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-case-insensitive.js +D test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-string.js +M test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-wrong-type.js +D test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-timezone-instance-does-not-get-timeZone-property.js +M test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-timezone-string-datetime.js +M test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-timezone-string-leap-second.js +A test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-timezone-string-multiple-offsets.js +M test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-timezone-string-year-zero.js +M test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-timezone-string.js +M test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-timezone-wrong-type.js +M test/built-ins/Temporal/ZonedDateTime/compare/argument-string-calendar-annotation.js +A test/built-ins/Temporal/ZonedDateTime/compare/argument-string-multiple-calendar.js +M test/built-ins/Temporal/ZonedDateTime/compare/order-of-operations.js M test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-case-insensitive.js -M test/built-ins/Temporal/ZonedDateTime/prototype/day/validate-calendar-value.js -M test/built-ins/Temporal/ZonedDateTime/prototype/dayOfWeek/validate-calendar-value.js -M test/built-ins/Temporal/ZonedDateTime/prototype/dayOfYear/validate-calendar-value.js -M test/built-ins/Temporal/ZonedDateTime/prototype/daysInMonth/validate-calendar-value.js -M test/built-ins/Temporal/ZonedDateTime/prototype/daysInWeek/validate-calendar-value.js -M test/built-ins/Temporal/ZonedDateTime/prototype/daysInYear/validate-calendar-value.js -D test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-calendar-fields-undefined.js +D test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-string.js +M test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-wrong-type.js +D test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-instance-does-not-get-timeZone-property.js +M test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-string-datetime.js +M test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-string-leap-second.js +M test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-string-multiple-offsets.js +M test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-string-year-zero.js +M test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-string.js +M test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-wrong-type.js +M test/built-ins/Temporal/ZonedDateTime/from/argument-string-calendar-annotation.js +M test/built-ins/Temporal/ZonedDateTime/from/argument-string-date-with-utc-offset.js +A test/built-ins/Temporal/ZonedDateTime/from/argument-string-multiple-calendar.js +M test/built-ins/Temporal/ZonedDateTime/from/argument-string-time-separators.js +M test/built-ins/Temporal/ZonedDateTime/from/argument-string-time-zone-annotation.js +M test/built-ins/Temporal/ZonedDateTime/from/argument-zoneddatetime.js +M test/built-ins/Temporal/ZonedDateTime/from/calendar-temporal-object.js +M test/built-ins/Temporal/ZonedDateTime/from/order-of-operations.js +M test/built-ins/Temporal/ZonedDateTime/from/timezone-case-insensitive.js +M test/built-ins/Temporal/ZonedDateTime/from/zoneddatetime-string-multiple-offsets.js +M test/built-ins/Temporal/ZonedDateTime/from/zoneddatetime-string.js +A test/built-ins/Temporal/ZonedDateTime/prototype/add/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/add/builtin-timezone-no-observable-calls.js +D test/built-ins/Temporal/ZonedDateTime/prototype/calendar/branding.js +A test/built-ins/Temporal/ZonedDateTime/prototype/calendarId/branding.js +A test/built-ins/Temporal/ZonedDateTime/prototype/calendarId/builtin-calendar-no-observable-calls.js +R071 test/built-ins/Temporal/ZonedDateTime/prototype/calendar/prop-desc.js test/built-ins/Temporal/ZonedDateTime/prototype/calendarId/prop-desc.js +A test/built-ins/Temporal/ZonedDateTime/prototype/day/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/day/builtin-timezone-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/dayOfWeek/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/dayOfWeek/builtin-timezone-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/dayOfYear/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/dayOfYear/builtin-timezone-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/daysInMonth/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/daysInMonth/builtin-timezone-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/daysInWeek/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/daysInWeek/builtin-timezone-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/daysInYear/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/daysInYear/builtin-timezone-no-observable-calls.js +M test/built-ins/Temporal/ZonedDateTime/prototype/epochMicroseconds/basic.js +M test/built-ins/Temporal/ZonedDateTime/prototype/epochMilliseconds/basic.js +M test/built-ins/Temporal/ZonedDateTime/prototype/epochSeconds/basic.js M test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-case-insensitive.js -M test/built-ins/Temporal/ZonedDateTime/prototype/inLeapYear/validate-calendar-value.js -M test/built-ins/Temporal/ZonedDateTime/prototype/month/validate-calendar-value.js -M test/built-ins/Temporal/ZonedDateTime/prototype/monthCode/validate-calendar-value.js -M test/built-ins/Temporal/ZonedDateTime/prototype/monthsInYear/validate-calendar-value.js -M test/built-ins/Temporal/ZonedDateTime/prototype/round/roundingincrement-non-integer.js -M test/built-ins/Temporal/ZonedDateTime/prototype/round/roundingincrement-out-of-range.js -D test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-calendar-fields-undefined.js +D test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-wrong-type.js +D test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-instance-does-not-get-timeZone-property.js +M test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-string-datetime.js +M test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-string-leap-second.js +M test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-string-multiple-offsets.js +M test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-string-year-zero.js +M test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-string.js +M test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-wrong-type.js +M test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-string-calendar-annotation.js +A test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-string-multiple-calendar.js +A test/built-ins/Temporal/ZonedDateTime/prototype/equals/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/equals/builtin-timezone-no-observable-calls.js +M test/built-ins/Temporal/ZonedDateTime/prototype/equals/order-of-operations.js +A test/built-ins/Temporal/ZonedDateTime/prototype/getCalendar/branding.js +A test/built-ins/Temporal/ZonedDateTime/prototype/getCalendar/builtin.js +A test/built-ins/Temporal/ZonedDateTime/prototype/getCalendar/length.js +A test/built-ins/Temporal/ZonedDateTime/prototype/getCalendar/name.js +A test/built-ins/Temporal/ZonedDateTime/prototype/getCalendar/not-a-constructor.js +A test/built-ins/Temporal/ZonedDateTime/prototype/getCalendar/prop-desc.js +A test/built-ins/Temporal/ZonedDateTime/prototype/getISOFields/builtin-timezone-no-observable-calls.js +M test/built-ins/Temporal/ZonedDateTime/prototype/getISOFields/custom.js +M test/built-ins/Temporal/ZonedDateTime/prototype/getISOFields/field-names.js +A test/built-ins/Temporal/ZonedDateTime/prototype/getISOFields/order-of-operations.js +A test/built-ins/Temporal/ZonedDateTime/prototype/getTimeZone/branding.js +A test/built-ins/Temporal/ZonedDateTime/prototype/getTimeZone/builtin.js +A test/built-ins/Temporal/ZonedDateTime/prototype/getTimeZone/length.js +A test/built-ins/Temporal/ZonedDateTime/prototype/getTimeZone/name.js +A test/built-ins/Temporal/ZonedDateTime/prototype/getTimeZone/not-a-constructor.js +A test/built-ins/Temporal/ZonedDateTime/prototype/getTimeZone/prop-desc.js +A test/built-ins/Temporal/ZonedDateTime/prototype/hour/builtin-timezone-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/inLeapYear/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/inLeapYear/builtin-timezone-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/microsecond/builtin-timezone-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/millisecond/builtin-timezone-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/minute/builtin-timezone-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/month/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/month/builtin-timezone-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/monthCode/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/monthCode/builtin-timezone-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/monthsInYear/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/monthsInYear/builtin-timezone-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/nanosecond/builtin-timezone-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/offset/builtin-timezone-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/offsetNanoseconds/builtin-timezone-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/round/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/round/builtin-timezone-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/round/order-of-operations.js +A test/built-ins/Temporal/ZonedDateTime/prototype/second/builtin-timezone-no-observable-calls.js M test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-case-insensitive.js -A test/built-ins/Temporal/ZonedDateTime/prototype/since/nanoseconds-to-days-loop-indefinitely-1.js -A test/built-ins/Temporal/ZonedDateTime/prototype/since/nanoseconds-to-days-loop-indefinitely-2.js -A test/built-ins/Temporal/ZonedDateTime/prototype/since/nanoseconds-to-days-range-errors.js +D test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-wrong-type.js +D test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-instance-does-not-get-timeZone-property.js +M test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-string-datetime.js +M test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-string-leap-second.js +M test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-string-multiple-offsets.js +M test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-string-year-zero.js +M test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-string.js +M test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-wrong-type.js +M test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-string-calendar-annotation.js +A test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-string-multiple-calendar.js +A test/built-ins/Temporal/ZonedDateTime/prototype/since/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/since/builtin-timezone-no-observable-calls.js M test/built-ins/Temporal/ZonedDateTime/prototype/since/order-of-operations.js -M test/built-ins/Temporal/ZonedDateTime/prototype/since/roundingincrement-non-integer.js -M test/built-ins/Temporal/ZonedDateTime/prototype/since/roundingincrement-out-of-range.js -D test/built-ins/Temporal/ZonedDateTime/prototype/toPlainMonthDay/calendar-fields-undefined.js -D test/built-ins/Temporal/ZonedDateTime/prototype/toPlainYearMonth/calendar-fields-undefined.js -D test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-calendar-fields-undefined.js +A test/built-ins/Temporal/ZonedDateTime/prototype/startOfDay/builtin-timezone-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/subtract/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/subtract/builtin-timezone-no-observable-calls.js +D test/built-ins/Temporal/ZonedDateTime/prototype/timeZone/branding.js +A test/built-ins/Temporal/ZonedDateTime/prototype/timeZoneId/branding.js +A test/built-ins/Temporal/ZonedDateTime/prototype/timeZoneId/builtin-timezone-no-observable-calls.js +R071 test/built-ins/Temporal/ZonedDateTime/prototype/timeZone/prop-desc.js test/built-ins/Temporal/ZonedDateTime/prototype/timeZoneId/prop-desc.js +A test/built-ins/Temporal/ZonedDateTime/prototype/toJSON/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/toJSON/builtin-timezone-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/toLocaleString/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/toLocaleString/builtin-timezone-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/toPlainDate/builtin-timezone-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/toPlainDateTime/builtin-timezone-no-observable-calls.js +M test/built-ins/Temporal/ZonedDateTime/prototype/toPlainDateTime/plain-custom-timezone.js +A test/built-ins/Temporal/ZonedDateTime/prototype/toPlainMonthDay/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/toPlainMonthDay/builtin-timezone-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/toPlainTime/builtin-timezone-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/toPlainYearMonth/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/toPlainYearMonth/builtin-timezone-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/toString/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/toString/builtin-timezone-no-observable-calls.js +M test/built-ins/Temporal/ZonedDateTime/prototype/toString/calendar-tostring.js +M test/built-ins/Temporal/ZonedDateTime/prototype/toString/calendarname-always.js +M test/built-ins/Temporal/ZonedDateTime/prototype/toString/calendarname-auto.js +M test/built-ins/Temporal/ZonedDateTime/prototype/toString/calendarname-critical.js +M test/built-ins/Temporal/ZonedDateTime/prototype/toString/calendarname-never.js +M test/built-ins/Temporal/ZonedDateTime/prototype/toString/calendarname-undefined.js +M test/built-ins/Temporal/ZonedDateTime/prototype/toString/calendarname-wrong-type.js +M test/built-ins/Temporal/ZonedDateTime/prototype/toString/options-undefined.js +M test/built-ins/Temporal/ZonedDateTime/prototype/toString/order-of-operations.js +M test/built-ins/Temporal/ZonedDateTime/prototype/toString/timezonename-auto.js +M test/built-ins/Temporal/ZonedDateTime/prototype/toString/timezonename-critical.js +M test/built-ins/Temporal/ZonedDateTime/prototype/toString/timezonename-never.js M test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-case-insensitive.js -A test/built-ins/Temporal/ZonedDateTime/prototype/until/nanoseconds-to-days-loop-indefinitely-1.js -A test/built-ins/Temporal/ZonedDateTime/prototype/until/nanoseconds-to-days-loop-indefinitely-2.js -A test/built-ins/Temporal/ZonedDateTime/prototype/until/nanoseconds-to-days-range-errors.js +D test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-wrong-type.js +D test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-timezone-instance-does-not-get-timeZone-property.js +M test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-timezone-string-datetime.js +M test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-timezone-string-leap-second.js +M test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-timezone-string-multiple-offsets.js +M test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-timezone-string-year-zero.js +M test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-timezone-string.js +M test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-timezone-wrong-type.js +M test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-string-calendar-annotation.js +A test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-string-multiple-calendar.js +A test/built-ins/Temporal/ZonedDateTime/prototype/until/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/until/builtin-timezone-no-observable-calls.js M test/built-ins/Temporal/ZonedDateTime/prototype/until/order-of-operations.js -M test/built-ins/Temporal/ZonedDateTime/prototype/until/roundingincrement-non-integer.js -M test/built-ins/Temporal/ZonedDateTime/prototype/until/roundingincrement-out-of-range.js -M test/built-ins/Temporal/ZonedDateTime/prototype/weekOfYear/validate-calendar-value.js -D test/built-ins/Temporal/ZonedDateTime/prototype/with/calendar-fields-undefined.js -M test/built-ins/Temporal/ZonedDateTime/prototype/with/copies-merge-fields-object.js -M test/built-ins/Temporal/ZonedDateTime/prototype/with/order-of-operations.js +A test/built-ins/Temporal/ZonedDateTime/prototype/weekOfYear/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/weekOfYear/builtin-timezone-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/with/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/with/builtin-timezone-no-observable-calls.js +M test/built-ins/Temporal/ZonedDateTime/prototype/with/timezone-getoffsetnanosecondsfor-not-callable.js +A test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/builtin-calendar-no-observable-calls.js M test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-case-insensitive.js +D test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-number.js +M test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-string-leap-second.js +M test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-string.js M test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-temporal-object.js -D test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-calendar-fields-undefined.js +M test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-wrong-type.js +M test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/subclassing-ignored.js M test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-propertybag-calendar-case-insensitive.js -M test/built-ins/Temporal/ZonedDateTime/prototype/year/validate-calendar-value.js -M test/built-ins/Temporal/ZonedDateTime/prototype/yearOfWeek/validate-calendar-value.js -M test/harness/assert-throws-same-realm.js -A test/harness/asyncHelpers-asyncTest-func-throws-sync.js -A test/harness/asyncHelpers-asyncTest-rejects-non-callable.js -A test/harness/asyncHelpers-asyncTest-return-not-thenable.js -A test/harness/asyncHelpers-asyncTest-returns-undefined.js -A test/harness/asyncHelpers-asyncTest-then-rejects.js -A test/harness/asyncHelpers-asyncTest-then-resolves.js -A test/harness/asyncHelpers-asyncTest-without-async-flag.js -A test/harness/asyncHelpers-throwsAsync-custom-typeerror.js -A test/harness/asyncHelpers-throwsAsync-custom.js -A test/harness/asyncHelpers-throwsAsync-func-throws-sync.js -A test/harness/asyncHelpers-throwsAsync-incorrect-ctor.js -A test/harness/asyncHelpers-throwsAsync-invalid-func.js -A test/harness/asyncHelpers-throwsAsync-native.js -A test/harness/asyncHelpers-throwsAsync-no-arg.js -A test/harness/asyncHelpers-throwsAsync-no-error.js -A test/harness/asyncHelpers-throwsAsync-null.js -A test/harness/asyncHelpers-throwsAsync-primitive.js -A test/harness/asyncHelpers-throwsAsync-resolved-error.js -A test/harness/asyncHelpers-throwsAsync-same-realm.js -A test/harness/asyncHelpers-throwsAsync-single-arg.js -M test/harness/isConstructor.js -A test/intl402/Array/prototype/toLocaleString/invoke-element-tolocalestring.js -M test/intl402/DateTimeFormat/constructor-no-instanceof.js -M test/intl402/DateTimeFormat/prototype/format/no-instanceof.js -M test/intl402/DateTimeFormat/prototype/format/proleptic-gregorian-calendar.js -M test/intl402/DateTimeFormat/prototype/format/temporal-objects-resolved-time-zone.js +D test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-propertybag-calendar-leap-second.js +M test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-propertybag-calendar-number.js +M test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-propertybag-calendar-wrong-type.js +M test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-string-calendar-annotation.js +A test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-string-multiple-calendar.js +A test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/builtin-timezone-no-observable-calls.js +M test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/calendar-temporal-object.js +M test/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-calendar-annotation.js +A test/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-multiple-calendar.js +A test/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/builtin-timezone-no-observable-calls.js +D test/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/calendar-temporal-object.js +A test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/builtin-timezone-no-observable-calls.js +M test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-case-insensitive.js +D test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-instance-does-not-get-timeZone-property.js +M test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-string-datetime.js +M test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-string-leap-second.js +M test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-string-multiple-offsets.js +M test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-string-year-zero.js +M test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-string.js +M test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-wrong-type.js +A test/built-ins/Temporal/ZonedDateTime/prototype/year/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/year/builtin-timezone-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/yearOfWeek/builtin-calendar-no-observable-calls.js +A test/built-ins/Temporal/ZonedDateTime/prototype/yearOfWeek/builtin-timezone-no-observable-calls.js +M test/built-ins/Temporal/ZonedDateTime/timezone-case-insensitive.js +D test/built-ins/Temporal/ZonedDateTime/timezone-instance-does-not-get-timeZone-property.js +M test/built-ins/Temporal/ZonedDateTime/timezone-string-datetime.js +M test/built-ins/Temporal/ZonedDateTime/timezone-string-leap-second.js +M test/built-ins/Temporal/ZonedDateTime/timezone-string-multiple-offsets.js +M test/built-ins/Temporal/ZonedDateTime/timezone-string.js +M test/built-ins/Temporal/ZonedDateTime/timezone-wrong-type.js +A test/built-ins/TypedArray/prototype/filter/BigInt/speciesctor-destination-resizable.js +A test/built-ins/TypedArray/prototype/filter/BigInt/speciesctor-get-species-custom-ctor-length-throws-resizable-arraybuffer.js +A test/built-ins/TypedArray/prototype/filter/speciesctor-destination-resizable.js +A test/built-ins/TypedArray/prototype/filter/speciesctor-get-species-custom-ctor-length-throws-resizable-arraybuffer.js +A test/built-ins/TypedArray/prototype/map/BigInt/speciesctor-destination-resizable.js +A test/built-ins/TypedArray/prototype/map/BigInt/speciesctor-get-species-custom-ctor-length-throws-resizable-arraybuffer.js +A test/built-ins/TypedArray/prototype/map/speciesctor-destination-resizable.js +A test/built-ins/TypedArray/prototype/map/speciesctor-get-species-custom-ctor-length-throws-resizable-arraybuffer.js +A test/built-ins/TypedArray/prototype/slice/BigInt/speciesctor-destination-resizable.js +A test/built-ins/TypedArray/prototype/slice/BigInt/speciesctor-get-species-custom-ctor-length-throws-resizable-arraybuffer.js +A test/built-ins/TypedArray/prototype/slice/speciesctor-destination-resizable.js +A test/built-ins/TypedArray/prototype/slice/speciesctor-get-species-custom-ctor-length-throws-resizable-arraybuffer.js +M test/intl402/DateTimeFormat/casing-numbering-system-calendar-options.js +M test/intl402/DateTimeFormat/prototype/format/related-year-zh.js +D test/intl402/DateTimeFormat/prototype/format/temporal-objects-timezone-getoffsetnanosecondsfor-not-callable.js +A test/intl402/DateTimeFormat/prototype/format/temporal-zoneddatetime-not-supported.js M test/intl402/DateTimeFormat/prototype/format/timedatestyle-en.js -M test/intl402/DateTimeFormat/prototype/formatRange/en-US.js -M test/intl402/DateTimeFormat/prototype/formatRange/fractionalSecondDigits.js -M test/intl402/DateTimeFormat/prototype/formatRange/temporal-objects-resolved-time-zone.js -M test/intl402/DateTimeFormat/prototype/formatRangeToParts/en-US.js -M test/intl402/DateTimeFormat/prototype/formatRangeToParts/fractionalSecondDigits.js -M test/intl402/DateTimeFormat/prototype/formatRangeToParts/temporal-objects-resolved-time-zone.js -M test/intl402/DateTimeFormat/prototype/formatToParts/temporal-objects-resolved-time-zone.js -M test/intl402/DateTimeFormat/prototype/resolvedOptions/no-instanceof.js -M test/intl402/DurationFormat/prototype/format/invalid-arguments-throws.js -A test/intl402/DurationFormat/prototype/formatToParts/formatToParts-styles-en.js -M test/intl402/DurationFormat/prototype/formatToParts/invalid-arguments-throws.js -M test/intl402/NumberFormat/constructor-no-instanceof.js -M test/intl402/NumberFormat/prototype/format/no-instanceof.js -M test/intl402/NumberFormat/prototype/formatRangeToParts/en-US.js -M test/intl402/NumberFormat/prototype/resolvedOptions/no-instanceof.js -D test/intl402/Temporal/Calendar/prototype/era/argument-calendar-fields-undefined.js +D test/intl402/DateTimeFormat/prototype/formatRange/temporal-objects-timezone-getoffsetnanosecondsfor-not-callable.js +A test/intl402/DateTimeFormat/prototype/formatRange/temporal-zoneddatetime-not-supported.js +D test/intl402/DateTimeFormat/prototype/formatRangeToParts/temporal-objects-timezone-getoffsetnanosecondsfor-not-callable.js +A test/intl402/DateTimeFormat/prototype/formatRangeToParts/temporal-zoneddatetime-not-supported.js +M test/intl402/DateTimeFormat/prototype/formatToParts/main.js +D test/intl402/DateTimeFormat/prototype/formatToParts/temporal-objects-timezone-getoffsetnanosecondsfor-not-callable.js +A test/intl402/DateTimeFormat/prototype/formatToParts/temporal-zoneddatetime-not-supported.js +M test/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle-timeStyle.js +M test/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle.js +A test/intl402/DurationFormat/prototype/format/style-default-en.js +A test/intl402/DurationFormat/prototype/format/style-digital-en.js +A test/intl402/DurationFormat/prototype/format/style-long-en.js +A test/intl402/DurationFormat/prototype/format/style-narrow-en.js +D test/intl402/DurationFormat/prototype/format/style-options-en.js +A test/intl402/DurationFormat/prototype/format/style-short-en.js +A test/intl402/DurationFormat/prototype/formatToParts/formatToParts-style-default-en.js +A test/intl402/DurationFormat/prototype/formatToParts/formatToParts-style-digital-en.js +A test/intl402/DurationFormat/prototype/formatToParts/formatToParts-style-long-en.js +A test/intl402/DurationFormat/prototype/formatToParts/formatToParts-style-narrow-en.js +A test/intl402/DurationFormat/prototype/formatToParts/formatToParts-style-short-en.js +D test/intl402/DurationFormat/prototype/formatToParts/formatToParts-styles-en.js +M test/intl402/Intl/supportedValuesOf/calendars-accepted-by-DateTimeFormat.js +M test/intl402/Intl/supportedValuesOf/calendars-accepted-by-DisplayNames.js +M test/intl402/Intl/supportedValuesOf/calendars.js +M test/intl402/Intl/supportedValuesOf/collations-accepted-by-Collator.js +M test/intl402/Intl/supportedValuesOf/collations.js +M test/intl402/Intl/supportedValuesOf/currencies-accepted-by-DisplayNames.js +M test/intl402/Intl/supportedValuesOf/numberingSystems-accepted-by-DateTimeFormat.js +M test/intl402/Intl/supportedValuesOf/numberingSystems-accepted-by-NumberFormat.js +M test/intl402/Intl/supportedValuesOf/numberingSystems-accepted-by-RelativeTimeFormat.js +M test/intl402/Intl/supportedValuesOf/numberingSystems-with-simple-digit-mappings.js +M test/intl402/Intl/supportedValuesOf/units-accepted-by-NumberFormat.js +M test/intl402/Intl/supportedValuesOf/units.js +M test/intl402/Locale/constructor-non-iana-canon.js +M test/intl402/Locale/prototype/collations/output-array-values.js +M test/intl402/Locale/prototype/hourCycles/output-array-values.js +M test/intl402/Locale/prototype/minimize/removing-likely-subtags-first-adds-likely-subtags.js +M test/intl402/NumberFormat/casing-numbering-system-options.js +M test/intl402/PluralRules/prototype/resolvedOptions/pluralCategories.js +M test/intl402/Segmenter/constructor/constructor/locales-valid.js +A test/intl402/Temporal/Calendar/prototype/dateFromFields/one-of-era-erayear-undefined.js +M test/intl402/Temporal/Calendar/prototype/dateFromFields/order-of-operations.js +A test/intl402/Temporal/Calendar/prototype/dateUntil/until-across-lunisolar-leap-months.js +A test/intl402/Temporal/Calendar/prototype/dateUntil/zero-length-duration-result.js M test/intl402/Temporal/Calendar/prototype/era/argument-propertybag-calendar-case-insensitive.js -D test/intl402/Temporal/Calendar/prototype/eraYear/argument-calendar-fields-undefined.js +D test/intl402/Temporal/Calendar/prototype/era/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/intl402/Temporal/Calendar/prototype/era/argument-propertybag-calendar-leap-second.js +M test/intl402/Temporal/Calendar/prototype/era/argument-propertybag-calendar-number.js +M test/intl402/Temporal/Calendar/prototype/era/argument-propertybag-calendar-wrong-type.js +M test/intl402/Temporal/Calendar/prototype/era/argument-string-calendar-annotation.js +A test/intl402/Temporal/Calendar/prototype/era/argument-string-multiple-calendar.js M test/intl402/Temporal/Calendar/prototype/eraYear/argument-propertybag-calendar-case-insensitive.js -A test/intl402/Temporal/Calendar/prototype/mergeFields/gregorian-mutually-exclusive-fields.js -A test/intl402/Temporal/Calendar/prototype/mergeFields/japanese-mutually-exclusive-fields.js -A test/intl402/Temporal/Calendar/prototype/monthDayFromFields/reference-year-1972.js -A test/intl402/Temporal/Calendar/prototype/yearMonthFromFields/reference-day.js -A test/intl402/Temporal/PlainDate/prototype/era/validate-calendar-value.js -D test/intl402/Temporal/PlainDate/prototype/eraYear/calendar-returns-infinity.js -A test/intl402/Temporal/PlainDate/prototype/eraYear/validate-calendar-value.js -A test/intl402/Temporal/PlainDate/prototype/with/cross-era-boundary.js -A test/intl402/Temporal/PlainDateTime/prototype/era/validate-calendar-value.js -D test/intl402/Temporal/PlainDateTime/prototype/eraYear/calendar-returns-infinity.js -A test/intl402/Temporal/PlainDateTime/prototype/eraYear/validate-calendar-value.js -M test/intl402/Temporal/PlainDateTime/prototype/toLocaleString/resolved-time-zone.js -M test/intl402/Temporal/PlainTime/prototype/toLocaleString/resolved-time-zone.js -A test/intl402/Temporal/PlainYearMonth/prototype/era/validate-calendar-value.js -D test/intl402/Temporal/PlainYearMonth/prototype/eraYear/calendar-returns-infinity.js -A test/intl402/Temporal/PlainYearMonth/prototype/eraYear/validate-calendar-value.js -A test/intl402/Temporal/ZonedDateTime/prototype/era/validate-calendar-value.js -D test/intl402/Temporal/ZonedDateTime/prototype/eraYear/calendar-returns-infinity.js -A test/intl402/Temporal/ZonedDateTime/prototype/eraYear/validate-calendar-value.js -M test/language/expressions/async-function/named-reassign-fn-name-in-body-in-arrow.js -M test/language/expressions/async-function/named-reassign-fn-name-in-body-in-eval.js -M test/language/expressions/async-function/named-reassign-fn-name-in-body.js -M test/language/expressions/async-function/named-strict-error-reassign-fn-name-in-body-in-arrow.js -M test/language/expressions/async-function/named-strict-error-reassign-fn-name-in-body-in-eval.js -M test/language/expressions/async-function/named-strict-error-reassign-fn-name-in-body.js -M test/language/expressions/async-generator/named-no-strict-reassign-fn-name-in-body-in-arrow.js -M test/language/expressions/async-generator/named-no-strict-reassign-fn-name-in-body-in-eval.js -M test/language/expressions/async-generator/named-no-strict-reassign-fn-name-in-body.js -M test/language/expressions/async-generator/named-strict-error-reassign-fn-name-in-body-in-arrow.js -M test/language/expressions/async-generator/named-strict-error-reassign-fn-name-in-body-in-eval.js -M test/language/expressions/async-generator/named-strict-error-reassign-fn-name-in-body.js -M test/language/expressions/await/await-awaits-thenable-not-callable.js -M test/language/expressions/await/await-awaits-thenables-that-throw.js -M test/language/expressions/await/await-awaits-thenables.js -M test/language/expressions/await/await-throws-rejections.js -M test/language/expressions/await/syntax-await-has-UnaryExpression-with-MultiplicativeExpression.js -M test/language/expressions/await/syntax-await-has-UnaryExpression.js -M test/language/expressions/dynamic-import/assignment-expression/additive-expr.js -M test/language/expressions/dynamic-import/assignment-expression/array-literal.js -M test/language/expressions/dynamic-import/assignment-expression/arrow-function.js -M test/language/expressions/dynamic-import/assignment-expression/await-expr.js -M test/language/expressions/dynamic-import/assignment-expression/await-identifier.js -M test/language/expressions/dynamic-import/assignment-expression/call-expr-arguments.js -M test/language/expressions/dynamic-import/assignment-expression/call-expr-expr.js -M test/language/expressions/dynamic-import/assignment-expression/call-expr-identifier.js -M test/language/expressions/dynamic-import/assignment-expression/cover-call-expr.js -M test/language/expressions/dynamic-import/assignment-expression/cover-parenthesized-expr.js -M test/language/expressions/dynamic-import/assignment-expression/identifier.js -M test/language/expressions/dynamic-import/assignment-expression/lhs-assign-operator-assign-expr.js -M test/language/expressions/dynamic-import/assignment-expression/lhs-eq-assign-expr-nostrict.js -M test/language/expressions/dynamic-import/assignment-expression/lhs-eq-assign-expr.js -M test/language/expressions/dynamic-import/assignment-expression/logical-and-expr.js -M test/language/expressions/dynamic-import/assignment-expression/logical-or-expr.js -M test/language/expressions/dynamic-import/assignment-expression/member-expr.js -M test/language/expressions/dynamic-import/assignment-expression/new-target.js -M test/language/expressions/dynamic-import/assignment-expression/object-literal.js -M test/language/expressions/dynamic-import/assignment-expression/tagged-function-call.js -M test/language/expressions/dynamic-import/assignment-expression/ternary.js -M test/language/expressions/dynamic-import/assignment-expression/yield-assign-expr.js -M test/language/expressions/dynamic-import/assignment-expression/yield-expr.js -M test/language/expressions/dynamic-import/assignment-expression/yield-identifier.js -M test/language/expressions/dynamic-import/custom-primitive.js -M test/language/expressions/dynamic-import/for-await-resolution-and-error-agen-yield.js -M test/language/expressions/dynamic-import/for-await-resolution-and-error-agen.js -M test/language/expressions/dynamic-import/imported-self-update.js -M test/language/expressions/dynamic-import/update-to-dynamic-import.js -M test/language/expressions/new.target/unary-expr.js -M test/language/expressions/optional-chaining/iteration-statement-for-await-of.js -M test/language/expressions/optional-chaining/member-expression-async-identifier.js -M test/language/expressions/optional-chaining/member-expression-async-literal.js -M test/language/expressions/optional-chaining/optional-chain-async-optional-chain-square-brackets.js -M test/language/expressions/optional-chaining/optional-chain-async-square-brackets.js -M test/language/statements/async-function/evaluation-this-value-global.js -D test/language/statements/class/decorator/syntax/valid/class-element-decorator-call-expr-identifier-reference-yield.js -D test/language/statements/class/decorator/syntax/valid/class-element-decorator-member-expr-identifier-reference-yield.js -D test/language/statements/class/decorator/syntax/valid/class-element-decorator-parenthesized-expr-identifier-reference-yield.js -M test/language/statements/for-await-of/iterator-close-non-throw-get-method-is-null.js +D test/intl402/Temporal/Calendar/prototype/eraYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +M test/intl402/Temporal/Calendar/prototype/eraYear/argument-propertybag-calendar-leap-second.js +M test/intl402/Temporal/Calendar/prototype/eraYear/argument-propertybag-calendar-number.js +M test/intl402/Temporal/Calendar/prototype/eraYear/argument-propertybag-calendar-wrong-type.js +M test/intl402/Temporal/Calendar/prototype/eraYear/argument-string-calendar-annotation.js +A test/intl402/Temporal/Calendar/prototype/eraYear/argument-string-multiple-calendar.js +M test/intl402/Temporal/Calendar/prototype/mergeFields/gregorian-mutually-exclusive-fields.js +M test/intl402/Temporal/Calendar/prototype/mergeFields/japanese-mutually-exclusive-fields.js +A test/intl402/Temporal/Calendar/prototype/monthDayFromFields/one-of-era-erayear-undefined.js +M test/intl402/Temporal/Calendar/prototype/monthDayFromFields/order-of-operations.js +A test/intl402/Temporal/Calendar/prototype/yearMonthFromFields/one-of-era-erayear-undefined.js +M test/intl402/Temporal/Calendar/prototype/yearMonthFromFields/order-of-operations.js +M test/intl402/Temporal/Duration/prototype/round/relativeto-string-datetime.js +M test/intl402/Temporal/Instant/prototype/toString/timezone-offset.js +M test/intl402/Temporal/Instant/prototype/toString/timezone-string-datetime.js +M test/intl402/Temporal/Instant/prototype/toZonedDateTime/timezone-string-datetime.js +M test/intl402/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-string-datetime.js +M test/intl402/Temporal/Now/plainDate/calendar-string.js +M test/intl402/Temporal/Now/plainDateTime/calendar-string.js +M test/intl402/Temporal/Now/plainDateTimeISO/timezone-string-datetime.js +M test/intl402/Temporal/Now/zonedDateTime/calendar-string.js +M test/intl402/Temporal/Now/zonedDateTime/calendar-timezone-string.js +M test/intl402/Temporal/Now/zonedDateTime/timezone-string-datetime.js +M test/intl402/Temporal/Now/zonedDateTimeISO/timezone-string-datetime.js +M test/intl402/Temporal/Now/zonedDateTimeISO/timezone-string.js +A test/intl402/Temporal/PlainDate/prototype/toLocaleString/calendar-mismatch.js +D test/intl402/Temporal/PlainDate/prototype/toLocaleString/timezone-getoffsetnanosecondsfor-not-callable.js +M test/intl402/Temporal/PlainDate/prototype/toZonedDateTime/timezone-string-datetime.js +A test/intl402/Temporal/PlainDateTime/prototype/toLocaleString/calendar-mismatch.js +D test/intl402/Temporal/PlainDateTime/prototype/toLocaleString/timezone-getoffsetnanosecondsfor-not-callable.js +M test/intl402/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-string-datetime.js +M test/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-noniso.js +M test/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-same-id.js +M test/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-same-object.js +M test/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar.js +M test/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-string-calendar.js +M test/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-string-iso-calendar.js +A test/intl402/Temporal/PlainMonthDay/from/reference-date-noniso-calendar.js +A test/intl402/Temporal/PlainMonthDay/prototype/toLocaleString/calendar-mismatch.js +D test/intl402/Temporal/PlainMonthDay/prototype/toLocaleString/timezone-getoffsetnanosecondsfor-not-callable.js +D test/intl402/Temporal/PlainTime/prototype/toLocaleString/timezone-getoffsetnanosecondsfor-not-callable.js +M test/intl402/Temporal/PlainTime/prototype/toZonedDateTime/timezone-string-datetime.js +A test/intl402/Temporal/PlainYearMonth/prototype/toLocaleString/calendar-mismatch.js +D test/intl402/Temporal/PlainYearMonth/prototype/toLocaleString/timezone-getoffsetnanosecondsfor-not-callable.js +M test/intl402/Temporal/TimeZone/from/argument-object.js +M test/intl402/Temporal/TimeZone/from/timezone-string-datetime.js +M test/intl402/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/nanoseconds-subtracted-or-added-at-dst-transition.js +A test/intl402/Temporal/ZonedDateTime/compare/argument-propertybag-timezone-string-datetime.js +M test/intl402/Temporal/ZonedDateTime/from/argument-propertybag-timezone-string-datetime.js +M test/intl402/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-string-datetime.js +M test/intl402/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-string-datetime.js +A test/intl402/Temporal/ZonedDateTime/prototype/toLocaleString/calendar-mismatch.js +A test/intl402/Temporal/ZonedDateTime/prototype/toLocaleString/custom-time-zone-name-not-supported.js +M test/intl402/Temporal/ZonedDateTime/prototype/toLocaleString/locales-undefined.js +A test/intl402/Temporal/ZonedDateTime/prototype/toLocaleString/offset-time-zone-not-supported.js +A test/intl402/Temporal/ZonedDateTime/prototype/toLocaleString/options-timeZone.js +A test/intl402/Temporal/ZonedDateTime/prototype/toLocaleString/options-timeZoneName-affects-instance-time-zone.js +M test/intl402/Temporal/ZonedDateTime/prototype/toLocaleString/options-undefined.js +A test/intl402/Temporal/ZonedDateTime/prototype/toLocaleString/time-zone-canonicalized.js +M test/intl402/Temporal/ZonedDateTime/prototype/until/argument-propertybag-timezone-string-datetime.js +M test/intl402/Temporal/ZonedDateTime/prototype/withCalendar/calendar-case-insensitive.js +M test/intl402/fallback-locales-are-supported.js +M test/language/expressions/assignmenttargettype/direct-updateexpression-star-star-exponentiationexpression-0.js +M test/language/expressions/assignmenttargettype/direct-updateexpression-star-star-exponentiationexpression-1.js +M test/language/expressions/assignmenttargettype/direct-updateexpression-star-star-exponentiationexpression-2.js +M test/language/expressions/assignmenttargettype/parenthesized-updateexpression-star-star-exponentiationexpression-0.js +M test/language/expressions/assignmenttargettype/parenthesized-updateexpression-star-star-exponentiationexpression-1.js +M test/language/expressions/assignmenttargettype/parenthesized-updateexpression-star-star-exponentiationexpression-2.js +M test/language/expressions/class/cpn-class-expr-accessors-computed-property-name-from-exponetiation-expression.js +M test/language/expressions/class/cpn-class-expr-accessors-computed-property-name-from-math.js +M test/language/expressions/class/cpn-class-expr-computed-property-name-from-exponetiation-expression.js +M test/language/expressions/class/cpn-class-expr-computed-property-name-from-math.js +M test/language/expressions/class/cpn-class-expr-fields-computed-property-name-from-exponetiation-expression.js +M test/language/expressions/class/cpn-class-expr-fields-computed-property-name-from-math.js +M test/language/expressions/class/cpn-class-expr-fields-methods-computed-property-name-from-exponetiation-expression.js +M test/language/expressions/class/cpn-class-expr-fields-methods-computed-property-name-from-math.js +M test/language/expressions/class/decorator/syntax/class-valid/decorator-member-expr-private-identifier.js +M test/language/expressions/class/decorator/syntax/valid/decorator-call-expr-identifier-reference-yield.js +M test/language/expressions/class/decorator/syntax/valid/decorator-call-expr-identifier-reference.js +M test/language/expressions/class/decorator/syntax/valid/decorator-member-expr-decorator-member-expr.js +M test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-exp.js +M test/language/expressions/compound-assignment/left-hand-side-private-reference-data-property-exp.js +M test/language/expressions/compound-assignment/left-hand-side-private-reference-method-exp.js +M test/language/expressions/compound-assignment/left-hand-side-private-reference-readonly-accessor-property-exp.js +M test/language/expressions/dynamic-import/syntax/invalid/invalid-assignmenttargettype-syntax-error-17-lhs-assignment-operator-assignment-expression.js +M test/language/expressions/exponentiation/applying-the-exp-operator_A1.js +M test/language/expressions/exponentiation/applying-the-exp-operator_A11.js +M test/language/expressions/exponentiation/applying-the-exp-operator_A12.js +M test/language/expressions/exponentiation/applying-the-exp-operator_A13.js +M test/language/expressions/exponentiation/applying-the-exp-operator_A14.js +M test/language/expressions/exponentiation/applying-the-exp-operator_A15.js +M test/language/expressions/exponentiation/applying-the-exp-operator_A16.js +M test/language/expressions/exponentiation/applying-the-exp-operator_A17.js +M test/language/expressions/exponentiation/applying-the-exp-operator_A18.js +M test/language/expressions/exponentiation/applying-the-exp-operator_A19.js +M test/language/expressions/exponentiation/applying-the-exp-operator_A2.js +M test/language/expressions/exponentiation/applying-the-exp-operator_A20.js +M test/language/expressions/exponentiation/applying-the-exp-operator_A21.js +M test/language/expressions/exponentiation/applying-the-exp-operator_A22.js +M test/language/expressions/exponentiation/applying-the-exp-operator_A23.js +M test/language/expressions/exponentiation/applying-the-exp-operator_A3.js +M test/language/expressions/exponentiation/applying-the-exp-operator_A4.js +M test/language/expressions/exponentiation/applying-the-exp-operator_A5.js +M test/language/expressions/exponentiation/applying-the-exp-operator_A6.js +M test/language/expressions/exponentiation/applying-the-exp-operator_A7.js +M test/language/expressions/exponentiation/applying-the-exp-operator_A8.js +M test/language/expressions/exponentiation/applying-the-exp-operator_A9.js +M test/language/expressions/exponentiation/bigint-and-number.js +M test/language/expressions/exponentiation/bigint-arithmetic.js +M test/language/expressions/exponentiation/bigint-errors.js +M test/language/expressions/exponentiation/bigint-negative-exponent-throws.js +M test/language/expressions/exponentiation/bigint-toprimitive.js +M test/language/expressions/exponentiation/bigint-wrapped-values.js +M test/language/expressions/exponentiation/bigint-zero-base-zero-exponent.js +M test/language/expressions/exponentiation/exp-assignment-operator.js +M test/language/expressions/exponentiation/exp-operator-evaluation-order.js +M test/language/expressions/exponentiation/exp-operator-precedence-unary-expression-semantics.js +M test/language/expressions/exponentiation/exp-operator-precedence-update-expression-semantics.js +M test/language/expressions/exponentiation/exp-operator-syntax-error-bitnot-unary-expression-base.js +M test/language/expressions/exponentiation/exp-operator-syntax-error-delete-unary-expression-base.js +M test/language/expressions/exponentiation/exp-operator-syntax-error-logical-not-unary-expression-base.js +M test/language/expressions/exponentiation/exp-operator-syntax-error-negate-unary-expression-base.js +M test/language/expressions/exponentiation/exp-operator-syntax-error-plus-unary-expression-base.js +M test/language/expressions/exponentiation/exp-operator-syntax-error-typeof-unary-expression-base.js +M test/language/expressions/exponentiation/exp-operator-syntax-error-void-unary-expression-base.js +M test/language/expressions/exponentiation/exp-operator.js +M test/language/expressions/exponentiation/int32_min-exponent.js +M test/language/expressions/exponentiation/order-of-evaluation.js +M test/language/expressions/object/cpn-obj-lit-computed-property-name-from-exponetiation-expression.js +M test/language/expressions/object/cpn-obj-lit-computed-property-name-from-math.js +A test/language/expressions/postfix-decrement/this.js +A test/language/expressions/postfix-increment/this.js +A test/language/expressions/prefix-decrement/this.js +A test/language/expressions/prefix-increment/this.js +M test/language/module-code/instn-iee-err-ambiguous-as.js +M test/language/module-code/instn-iee-err-ambiguous.js +M test/language/module-code/instn-iee-err-circular-as.js +M test/language/module-code/instn-iee-err-circular.js +M test/language/module-code/instn-iee-err-dflt-thru-star-as.js +M test/language/module-code/instn-iee-err-dflt-thru-star.js +M test/language/module-code/instn-iee-err-not-found-as.js +M test/language/module-code/instn-iee-err-not-found.js +M test/language/module-code/instn-named-err-ambiguous-as.js +M test/language/module-code/instn-named-err-ambiguous.js +M test/language/module-code/instn-named-err-dflt-thru-star-as.js +M test/language/module-code/instn-named-err-dflt-thru-star-dflt.js +M test/language/module-code/instn-named-err-not-found-as.js +M test/language/module-code/instn-named-err-not-found-dflt.js +M test/language/module-code/instn-named-err-not-found.js +M test/language/module-code/instn-star-err-not-found.js +M test/language/statements/class/cpn-class-decl-accessors-computed-property-name-from-exponetiation-expression.js +M test/language/statements/class/cpn-class-decl-accessors-computed-property-name-from-math.js +M test/language/statements/class/cpn-class-decl-computed-property-name-from-exponetiation-expression.js +M test/language/statements/class/cpn-class-decl-computed-property-name-from-math.js +M test/language/statements/class/cpn-class-decl-fields-computed-property-name-from-exponetiation-expression.js +M test/language/statements/class/cpn-class-decl-fields-computed-property-name-from-math.js +M test/language/statements/class/cpn-class-decl-fields-methods-computed-property-name-from-exponetiation-expression.js +M test/language/statements/class/cpn-class-decl-fields-methods-computed-property-name-from-math.js +M test/language/statements/class/decorator/syntax/class-valid/decorator-member-expr-private-identifier.js +M test/language/statements/class/decorator/syntax/valid/class-element-decorator-call-expr-identifier-reference.js +M test/language/statements/class/decorator/syntax/valid/class-element-decorator-member-expr-decorator-member-expr.js +M test/language/statements/class/decorator/syntax/valid/decorator-call-expr-identifier-reference-yield.js +M test/language/statements/class/decorator/syntax/valid/decorator-call-expr-identifier-reference.js +M test/language/statements/class/decorator/syntax/valid/decorator-member-expr-decorator-member-expr.js +M test/staging/ArrayBuffer/resizable/includes-parameter-conversion-resizes.js +M test/staging/ArrayBuffer/resizable/includes.js +M test/staging/ArrayBuffer/resizable/sort-callback-shrinks.js M test/staging/Intl402/Temporal/old/date-time-format.js M test/staging/Intl402/Temporal/old/date-toLocaleString.js M test/staging/Intl402/Temporal/old/datetime-toLocaleString.js -M test/staging/Intl402/Temporal/old/hebrew-leap-months.js -M test/staging/Intl402/Temporal/old/instant-toLocaleString.js M test/staging/Intl402/Temporal/old/japanese-era.js M test/staging/Intl402/Temporal/old/monthday-toLocaleString.js -M test/staging/Intl402/Temporal/old/time-toLocaleString.js +M test/staging/Intl402/Temporal/old/non-iso-calendars.js M test/staging/Intl402/Temporal/old/yearmonth-toLocaleString.js -M test/staging/Intl402/Temporal/old/zoneddatetime-toLocaleString.js -M test/staging/Temporal/Instant/old/round.js +D test/staging/Intl402/Temporal/old/zoneddatetime-toLocaleString.js +A test/staging/JSON/json-parse-with-source-snapshot.js +A test/staging/JSON/json-parse-with-source.js +M test/staging/Temporal/Instant/old/toZonedDateTime.js +M test/staging/Temporal/Regex/old/plaindate.js +M test/staging/Temporal/Regex/old/plaindatetime.js +M test/staging/Temporal/Regex/old/plainmonthday.js +M test/staging/Temporal/Regex/old/plainyearmonth.js +M test/staging/Temporal/UserCalendar/old/calendar-extra-fields.js +M test/staging/Temporal/UserCalendar/old/calendar-non-trivial-mergefields.js M test/staging/Temporal/UserCalendar/old/trivial-protocol-implementation.js +M test/staging/Temporal/UserCalendar/old/trivial-subclass.js +M test/staging/Temporal/UserTimezone/old/subminute-offset.js +M test/staging/Temporal/UserTimezone/old/trivial-protocol.js +M test/staging/Temporal/UserTimezone/old/trivial-subclass.js +M test/staging/Temporal/ZonedDateTime/old/compare.js +M test/staging/Temporal/ZonedDateTime/old/construction-and-properties.js M test/staging/Temporal/ZonedDateTime/old/equals.js +M test/staging/Temporal/ZonedDateTime/old/since.js +M test/staging/Temporal/ZonedDateTime/old/toPlainDate.js M test/staging/Temporal/ZonedDateTime/old/toPlainMonthDay.js -M test/staging/Temporal/ZonedDateTime/old/toPlainYearMonth.js \ No newline at end of file +M test/staging/Temporal/ZonedDateTime/old/toPlainYearMonth.js +M test/staging/Temporal/ZonedDateTime/old/toString.js +M test/staging/Temporal/ZonedDateTime/old/until.js +M test/staging/Temporal/ZonedDateTime/old/withCalendar.js +M test/staging/Temporal/ZonedDateTime/old/withPlainDate.js +M test/staging/Temporal/ZonedDateTime/old/withTimezone.js \ No newline at end of file diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/async-iterable-async-mapped-awaits-once.js b/JSTests/test262/test/built-ins/Array/fromAsync/async-iterable-async-mapped-awaits-once.js new file mode 100644 index 000000000000..c4ae9dd18014 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/async-iterable-async-mapped-awaits-once.js @@ -0,0 +1,30 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Async-iterable awaits each input once with mapping callback +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + async function* generateInput () { + yield* [ 0, 1, 2 ]; + } + const input = generateInput(); + let awaitCounter = 0; + await Array.fromAsync(input, v => { + return { + // This “then” method should occur three times: + // one for each value from the input. + then (resolve, reject) { + awaitCounter ++; + resolve(v); + }, + }; + }); + assert.sameValue(awaitCounter, 3); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/async-iterable-input-does-not-await-input.js b/JSTests/test262/test/built-ins/Array/fromAsync/async-iterable-input-does-not-await-input.js new file mode 100644 index 000000000000..3d27141605fb --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/async-iterable-input-does-not-await-input.js @@ -0,0 +1,38 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Async-iterable input does not await input values. +includes: [compareArray.js, asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const prom = Promise.resolve({}); + const expected = [ prom ]; + + function createInput () { + return { + // The following async iterator will yield one value + // (the promise named “prom”). + [Symbol.asyncIterator]() { + let i = 0; + return { + async next() { + if (i > 0) { + return { done: true }; + } + i++; + return { value: prom, done: false } + }, + }; + }, + }; + } + + const input = createInput(); + const output = await Array.fromAsync(input); + assert.compareArray(output, expected); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/async-iterable-input-iteration-err.js b/JSTests/test262/test/built-ins/Array/fromAsync/async-iterable-input-iteration-err.js new file mode 100644 index 000000000000..2670434bafe1 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/async-iterable-input-iteration-err.js @@ -0,0 +1,20 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Array.fromAsync promise rejects if iteration of input fails. +flags: [async] +features: [Array.fromAsync] +includes: [asyncHelpers.js] +---*/ + +asyncTest(async function () { + async function *generateInput () { + throw new Test262Error('This error should be propagated.'); + } + const input = generateInput(); + const outputPromise = Array.fromAsync(input); + await assert.throwsAsync(Test262Error, () => outputPromise); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/async-iterable-input.js b/JSTests/test262/test/built-ins/Array/fromAsync/async-iterable-input.js new file mode 100644 index 000000000000..6c159d910955 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/async-iterable-input.js @@ -0,0 +1,23 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Async-iterable input is transferred to the output array. +includes: [compareArray.js, asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const expected = [ 0, 1, 2 ]; + + async function* generateInput () { + yield* expected; + } + + const input = generateInput(); + const output = await Array.fromAsync(input); + assert.compareArray(output, expected); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-array-add-to-empty.js b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-array-add-to-empty.js new file mode 100644 index 000000000000..d39b8f22ae05 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-array-add-to-empty.js @@ -0,0 +1,44 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Array.fromAsync respects array mutation +info: | + Array.fromAsync + 3.j.ii.3. Let next be ? Await(IteratorStep(iteratorRecord)). + + IteratorStep + 1. Let result be ? IteratorNext(iteratorRecord). + + IteratorNext + 1.a. Let result be ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]]). + + %AsyncFromSyncIteratorPrototype%.next + 6.a. Let result be Completion(IteratorNext(syncIteratorRecord)). + + IteratorNext + 1.a. Let result be ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]]). + + Array.prototype [ @@iterator ] ( ) + Array.prototype.values ( ) + 2. Return CreateArrayIterator(O, value). + + CreateArrayIterator + 1.b.iii. If index ≥ len, return NormalCompletion(undefined). +includes: [asyncHelpers.js, compareArray.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const items = []; + const promise = Array.fromAsync(items); + // By the time we get here, the first next() call has already happened, and returned + // { done: true }. We then return from the loop in Array.fromAsync 3.j.ii. with the empty array, + // and the following line no longer affects that. + items.push(7); + const result = await promise; + assert.compareArray(result, []); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-array-add-to-singleton.js b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-array-add-to-singleton.js new file mode 100644 index 000000000000..09f9dc9627cd --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-array-add-to-singleton.js @@ -0,0 +1,43 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Array.fromAsync respects array mutation +info: | + Array.fromAsync + 3.j.ii.3. Let next be ? Await(IteratorStep(iteratorRecord)). + + IteratorStep + 1. Let result be ? IteratorNext(iteratorRecord). + + IteratorNext + 1.a. Let result be ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]]). + + %AsyncFromSyncIteratorPrototype%.next + 6.a. Let result be Completion(IteratorNext(syncIteratorRecord)). + + IteratorNext + 1.a. Let result be ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]]). + + Array.prototype [ @@iterator ] ( ) + Array.prototype.values ( ) + 2. Return CreateArrayIterator(O, value). + + CreateArrayIterator + 1.b.iii. If index ≥ len, return NormalCompletion(undefined). +includes: [asyncHelpers.js, compareArray.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const items = [1]; + const promise = Array.fromAsync(items); + // At this point, the first element of `items` has been read, but the iterator will take other + // changes into account. + items.push(7); + const result = await promise; + assert.compareArray(result, [1, 7]); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-array-add.js b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-array-add.js new file mode 100644 index 000000000000..fa47c6f7786d --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-array-add.js @@ -0,0 +1,43 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Array.fromAsync respects array mutation +info: | + Array.fromAsync + 3.j.ii.3. Let next be ? Await(IteratorStep(iteratorRecord)). + + IteratorStep + 1. Let result be ? IteratorNext(iteratorRecord). + + IteratorNext + 1.a. Let result be ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]]). + + %AsyncFromSyncIteratorPrototype%.next + 6.a. Let result be Completion(IteratorNext(syncIteratorRecord)). + + IteratorNext + 1.a. Let result be ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]]). + + Array.prototype [ @@iterator ] ( ) + Array.prototype.values ( ) + 2. Return CreateArrayIterator(O, value). + + CreateArrayIterator + 1.b.iii. If index ≥ len, return NormalCompletion(undefined). +includes: [asyncHelpers.js, compareArray.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const items = [1, 2, 3]; + const promise = Array.fromAsync(items); + // At this point, the first element of `items` has been read, but the iterator will take other + // changes into account. + items.push(4); + const result = await promise; + assert.compareArray(result, [1, 2, 3, 4]); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-array-mutate.js b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-array-mutate.js new file mode 100644 index 000000000000..29a7a1180abd --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-array-mutate.js @@ -0,0 +1,44 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Array.fromAsync respects array mutation +info: | + Array.fromAsync + 3.j.ii.3. Let next be ? Await(IteratorStep(iteratorRecord)). + + IteratorStep + 1. Let result be ? IteratorNext(iteratorRecord). + + IteratorNext + 1.a. Let result be ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]]). + + %AsyncFromSyncIteratorPrototype%.next + 6.a. Let result be Completion(IteratorNext(syncIteratorRecord)). + + IteratorNext + 1.a. Let result be ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]]). + + Array.prototype [ @@iterator ] ( ) + Array.prototype.values ( ) + 2. Return CreateArrayIterator(O, value). + + CreateArrayIterator + 1.b.iii. If index ≥ len, return NormalCompletion(undefined). +includes: [asyncHelpers.js, compareArray.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const items = [1, 2, 3]; + const promise = Array.fromAsync(items); + // At this point, the first element of `items` has been read, but the iterator will take other + // changes into account. + items[0] = 7; + items[1] = 8; + const result = await promise; + assert.compareArray(result, [1, 8, 3]); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-array-remove.js b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-array-remove.js new file mode 100644 index 000000000000..712157db4efe --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-array-remove.js @@ -0,0 +1,43 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Array.fromAsync respects array mutation +info: | + Array.fromAsync + 3.j.ii.3. Let next be ? Await(IteratorStep(iteratorRecord)). + + IteratorStep + 1. Let result be ? IteratorNext(iteratorRecord). + + IteratorNext + 1.a. Let result be ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]]). + + %AsyncFromSyncIteratorPrototype%.next + 6.a. Let result be Completion(IteratorNext(syncIteratorRecord)). + + IteratorNext + 1.a. Let result be ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]]). + + Array.prototype [ @@iterator ] ( ) + Array.prototype.values ( ) + 2. Return CreateArrayIterator(O, value). + + CreateArrayIterator + 1.b.iii. If index ≥ len, return NormalCompletion(undefined). +includes: [asyncHelpers.js, compareArray.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const items = [1, 2, 3]; + const promise = Array.fromAsync(items); + // At this point, the first element of `items` has been read, but the iterator will take other + // changes into account. + items.pop(); + const result = await promise; + assert.compareArray(result, [1, 2]); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-arraybuffer.js b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-arraybuffer.js new file mode 100644 index 000000000000..30a740082798 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-arraybuffer.js @@ -0,0 +1,17 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Array.fromAsync doesn't special-case ArrayBuffer +includes: [asyncHelpers.js, compareArray.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const items = new ArrayBuffer(7); + const result = await Array.fromAsync(items); + assert.compareArray(result, []); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-arraylike-holes.js b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-arraylike-holes.js new file mode 100644 index 000000000000..3fa3ce97c339 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-arraylike-holes.js @@ -0,0 +1,24 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Array-like object with holes treats the holes as undefined +info: | + 3.k.vii.2. Let _kValue_ be ? Get(_arrayLike_, _Pk_). +features: [Array.fromAsync] +flags: [async] +includes: [asyncHelpers.js, compareArray.js] +---*/ + +asyncTest(async function () { + const arrayLike = Object.create(null); + arrayLike.length = 5; + arrayLike[0] = 0; + arrayLike[1] = 1; + arrayLike[2] = 2; + arrayLike[4] = 4; + + const array = await Array.fromAsync(arrayLike); + assert.compareArray(array, [0, 1, 2, undefined, 4], "holes in array-like treated as undefined"); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-arraylike-length-accessor-throws.js b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-arraylike-length-accessor-throws.js new file mode 100644 index 000000000000..58ee4e7d1e5c --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-arraylike-length-accessor-throws.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Rejects on array-like object whose length cannot be gotten +info: | + 3.k.iii. Let _len_ be ? LengthOfArrayLike(_arrayLike_). +features: [Array.fromAsync] +flags: [async] +includes: [asyncHelpers.js] +---*/ + +asyncTest(async function () { + await assert.throwsAsync(Test262Error, () => Array.fromAsync({ + get length() { + throw new Test262Error('accessing length property fails'); + } + }), "Promise should be rejected if array-like length getter throws"); + + await assert.throwsAsync(TypeError, () => Array.fromAsync({ + length: 1n, + 0: 0 + }), "Promise should be rejected if array-like length can't be converted to a number"); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-arraylike-promise.js b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-arraylike-promise.js new file mode 100644 index 000000000000..e01919314fc4 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-arraylike-promise.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-array.fromasync +description: > + Array.fromAsync tries the various properties in order and awaits promises +includes: [asyncHelpers.js, compareArray.js, temporalHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const actual = []; + const items = TemporalHelpers.propertyBagObserver(actual, { + length: 2, + 0: Promise.resolve(2), + 1: Promise.resolve(1), + }, "items"); + const result = await Array.fromAsync(items); + assert.compareArray(result, [2, 1]); + assert.compareArray(actual, [ + "get items[Symbol.asyncIterator]", + "get items[Symbol.iterator]", + "get items.length", + "get items.length.valueOf", + "call items.length.valueOf", + "get items[0]", + "get items[1]", + ]); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-arraylike-too-long.js b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-arraylike-too-long.js new file mode 100644 index 000000000000..7d292e76fc67 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-arraylike-too-long.js @@ -0,0 +1,31 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Promise is rejected if the length of the array-like to copy is out of range +info: | + j. If _iteratorRecord_ is not *undefined*, then + ... + k. Else, + ... + iv. If IsConstructor(_C_) is *true*, then + ... + v. Else, + 1. Let _A_ be ? ArrayCreate(_len_). + + ArrayCreate, step 1: + 1. If _length_ > 2³² - 1, throw a *RangeError* exception. +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const notConstructor = {}; + + await assert.throwsAsync(RangeError, () => Array.fromAsync.call(notConstructor, { + length: 4294967296 // 2³² + }), "Array-like with excessive length"); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-asynciterator-exists.js b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-asynciterator-exists.js new file mode 100644 index 000000000000..3ca3eb7a496c --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-asynciterator-exists.js @@ -0,0 +1,32 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Array.fromAsync tries the various properties in order +includes: [asyncHelpers.js, compareArray.js, temporalHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + async function * asyncGen() { + for (let i = 0; i < 4; i++) { + yield Promise.resolve(i * 2); + } + } + + const actual = []; + const items = {}; + TemporalHelpers.observeProperty(actual, items, Symbol.asyncIterator, asyncGen, "items"); + TemporalHelpers.observeProperty(actual, items, Symbol.iterator, undefined, "items"); + TemporalHelpers.observeProperty(actual, items, "length", 2, "items"); + TemporalHelpers.observeProperty(actual, items, 0, 2, "items"); + TemporalHelpers.observeProperty(actual, items, 1, 1, "items"); + const result = await Array.fromAsync(items); + assert.compareArray(result, [0, 2, 4, 6]); + assert.compareArray(actual, [ + "get items[Symbol.asyncIterator]", + ]); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-asynciterator-not-callable.js b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-asynciterator-not-callable.js new file mode 100644 index 000000000000..b23280a4f4b5 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-asynciterator-not-callable.js @@ -0,0 +1,19 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Array.fromAsync rejects if the @@asyncIterator property is not callable +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + for (const v of [true, "", Symbol(), 1, 1n, {}]) { + await assert.throwsAsync(TypeError, + () => Array.fromAsync({ [Symbol.asyncIterator]: v }), + `@@asyncIterator = ${typeof v}`); + } +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-asynciterator-null.js b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-asynciterator-null.js new file mode 100644 index 000000000000..989959d44ae2 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-asynciterator-null.js @@ -0,0 +1,30 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Array.fromAsync tries the various properties in order +includes: [asyncHelpers.js, compareArray.js, temporalHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const actual = []; + const items = {}; + TemporalHelpers.observeProperty(actual, items, Symbol.asyncIterator, null, "items"); + TemporalHelpers.observeProperty(actual, items, Symbol.iterator, undefined, "items"); + TemporalHelpers.observeProperty(actual, items, "length", 2, "items"); + TemporalHelpers.observeProperty(actual, items, 0, 2, "items"); + TemporalHelpers.observeProperty(actual, items, 1, 1, "items"); + const result = await Array.fromAsync(items); + assert.compareArray(result, [2, 1]); + assert.compareArray(actual, [ + "get items[Symbol.asyncIterator]", + "get items[Symbol.iterator]", + "get items.length", + "get items[0]", + "get items[1]", + ]); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-asynciterator-sync.js b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-asynciterator-sync.js new file mode 100644 index 000000000000..d74375c55c81 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-asynciterator-sync.js @@ -0,0 +1,32 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Array.fromAsync handles a sync iterator returned from @@asyncIterator +includes: [asyncHelpers.js, compareArray.js, temporalHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + function * syncGen() { + for (let i = 0; i < 4; i++) { + yield i * 2; + } + } + + const actual = []; + const items = {}; + TemporalHelpers.observeProperty(actual, items, Symbol.asyncIterator, syncGen, "items"); + TemporalHelpers.observeProperty(actual, items, Symbol.iterator, undefined, "items"); + TemporalHelpers.observeProperty(actual, items, "length", 2, "items"); + TemporalHelpers.observeProperty(actual, items, 0, 2, "items"); + TemporalHelpers.observeProperty(actual, items, 1, 1, "items"); + const result = await Array.fromAsync(items); + assert.compareArray(result, [0, 2, 4, 6]); + assert.compareArray(actual, [ + "get items[Symbol.asyncIterator]", + ]); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-asynciterator-throws.js b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-asynciterator-throws.js new file mode 100644 index 000000000000..64e3f159d766 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-asynciterator-throws.js @@ -0,0 +1,16 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Array.fromAsync rejects if getting the @@asyncIterator property throws +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + await assert.throwsAsync(Test262Error, + () => Array.fromAsync({ get [Symbol.asyncIterator]() { throw new Test262Error() } })); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-bigint.js b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-bigint.js new file mode 100644 index 000000000000..dbc4c02ae11f --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-bigint.js @@ -0,0 +1,20 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Array.fromAsync treats a BigInt as an array-like +includes: [asyncHelpers.js, compareArray.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + BigInt.prototype.length = 2; + BigInt.prototype[0] = 1; + BigInt.prototype[1] = 2; + + const result = await Array.fromAsync(1n); + assert.compareArray(result, [1, 2]); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-boolean.js b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-boolean.js new file mode 100644 index 000000000000..884fe8f0e2c5 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-boolean.js @@ -0,0 +1,20 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Array.fromAsync treats a boolean as an array-like +includes: [asyncHelpers.js, compareArray.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + Boolean.prototype.length = 2; + Boolean.prototype[0] = 1; + Boolean.prototype[1] = 2; + + const result = await Array.fromAsync(true); + assert.compareArray(result, [1, 2]); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-function.js b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-function.js new file mode 100644 index 000000000000..f2227cb38245 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-function.js @@ -0,0 +1,21 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Array.fromAsync treats a function as an array-like, reading elements up to fn.length +includes: [asyncHelpers.js, compareArray.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const fn = function(a, b) {}; + fn[0] = 1; + fn[1] = 2; + fn[2] = 3; + + const result = await Array.fromAsync(fn); + assert.compareArray(result, [1, 2]); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-iterator-exists.js b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-iterator-exists.js new file mode 100644 index 000000000000..20b4a488e15f --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-iterator-exists.js @@ -0,0 +1,33 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Array.fromAsync handles a sync iterator returned from @@iterator +includes: [asyncHelpers.js, compareArray.js, temporalHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + function * syncGen() { + for (let i = 0; i < 4; i++) { + yield i * 2; + } + } + + const actual = []; + const items = {}; + TemporalHelpers.observeProperty(actual, items, Symbol.asyncIterator, undefined, "items"); + TemporalHelpers.observeProperty(actual, items, Symbol.iterator, syncGen, "items"); + TemporalHelpers.observeProperty(actual, items, "length", 2, "items"); + TemporalHelpers.observeProperty(actual, items, 0, 2, "items"); + TemporalHelpers.observeProperty(actual, items, 1, 1, "items"); + const result = await Array.fromAsync(items); + assert.compareArray(result, [0, 2, 4, 6]); + assert.compareArray(actual, [ + "get items[Symbol.asyncIterator]", + "get items[Symbol.iterator]", + ]); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-iterator-not-callable.js b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-iterator-not-callable.js new file mode 100644 index 000000000000..e0eedeb24ba5 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-iterator-not-callable.js @@ -0,0 +1,19 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Array.fromAsync rejects if the @@iterator property is not callable +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + for (const v of [true, "", Symbol(), 1, 1n, {}]) { + await assert.throwsAsync(TypeError, + () => Array.fromAsync({ [Symbol.iterator]: v }), + `@@iterator = ${typeof v}`); + } +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-iterator-null.js b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-iterator-null.js new file mode 100644 index 000000000000..357d3d39c5ba --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-iterator-null.js @@ -0,0 +1,30 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Array.fromAsync tries the various properties in order +includes: [asyncHelpers.js, compareArray.js, temporalHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const actual = []; + const items = {}; + TemporalHelpers.observeProperty(actual, items, Symbol.asyncIterator, undefined, "items"); + TemporalHelpers.observeProperty(actual, items, Symbol.iterator, null, "items"); + TemporalHelpers.observeProperty(actual, items, "length", 2, "items"); + TemporalHelpers.observeProperty(actual, items, 0, 2, "items"); + TemporalHelpers.observeProperty(actual, items, 1, 1, "items"); + const result = await Array.fromAsync(items); + assert.compareArray(result, [2, 1]); + assert.compareArray(actual, [ + "get items[Symbol.asyncIterator]", + "get items[Symbol.iterator]", + "get items.length", + "get items[0]", + "get items[1]", + ]); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-iterator-promise.js b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-iterator-promise.js new file mode 100644 index 000000000000..5feed624f124 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-iterator-promise.js @@ -0,0 +1,33 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Array.fromAsync handles an async iterator returned from @@iterator +includes: [asyncHelpers.js, compareArray.js, temporalHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + function * asyncGen() { + for (let i = 0; i < 4; i++) { + yield Promise.resolve(i * 2); + } + } + + const actual = []; + const items = {}; + TemporalHelpers.observeProperty(actual, items, Symbol.asyncIterator, undefined, "items"); + TemporalHelpers.observeProperty(actual, items, Symbol.iterator, asyncGen, "items"); + TemporalHelpers.observeProperty(actual, items, "length", 2, "items"); + TemporalHelpers.observeProperty(actual, items, 0, 2, "items"); + TemporalHelpers.observeProperty(actual, items, 1, 1, "items"); + const result = await Array.fromAsync(items); + assert.compareArray(result, [0, 2, 4, 6]); + assert.compareArray(actual, [ + "get items[Symbol.asyncIterator]", + "get items[Symbol.iterator]", + ]); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-iterator-throws.js b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-iterator-throws.js new file mode 100644 index 000000000000..4e187021cfa5 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-iterator-throws.js @@ -0,0 +1,16 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Array.fromAsync rejects if getting the @@iterator property throws +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + await assert.throwsAsync(Test262Error, + () => Array.fromAsync({ get [Symbol.iterator]() { throw new Test262Error() } })); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-null-undefined.js b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-null-undefined.js new file mode 100644 index 000000000000..198deb5d5b45 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-null-undefined.js @@ -0,0 +1,18 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Array.fromAsync rejects with a TypeError if the asyncItems argument is null or undefined +info: | + 3.c. Let usingAsyncIterator be ? GetMethod(asyncItems, @@asyncIterator). +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + await assert.throwsAsync(TypeError, () => Array.fromAsync(null), "null asyncItems"); + await assert.throwsAsync(TypeError, () => Array.fromAsync(undefined), "undefined asyncItems"); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-number.js b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-number.js new file mode 100644 index 000000000000..893fafea4368 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-number.js @@ -0,0 +1,20 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Array.fromAsync treats a Number as an array-like +includes: [asyncHelpers.js, compareArray.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + Number.prototype.length = 2; + Number.prototype[0] = 1; + Number.prototype[1] = 2; + + const result = await Array.fromAsync(1); + assert.compareArray(result, [1, 2]); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-object-not-arraylike.js b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-object-not-arraylike.js new file mode 100644 index 000000000000..5452bdd94229 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-object-not-arraylike.js @@ -0,0 +1,23 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Treats an asyncItems object that isn't an array-like as a 0-length array-like +info: | + 3.k.iii. Let _len_ be ? LengthOfArrayLike(_arrayLike_). +features: [Array.fromAsync] +flags: [async] +includes: [asyncHelpers.js, compareArray.js] +---*/ + +asyncTest(async function () { + const notArrayLike = Object.create(null); + notArrayLike[0] = 0; + notArrayLike[1] = 1; + notArrayLike[2] = 2; + + const array = await Array.fromAsync(notArrayLike); + assert.compareArray(array, [], "non-array-like object is treated as 0-length array-like"); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-operations.js b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-operations.js new file mode 100644 index 000000000000..33b96b614ee8 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-operations.js @@ -0,0 +1,30 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Array.fromAsync tries the various properties in order +includes: [asyncHelpers.js, compareArray.js, temporalHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const actual = []; + const items = {}; + TemporalHelpers.observeProperty(actual, items, Symbol.asyncIterator, undefined, "items"); + TemporalHelpers.observeProperty(actual, items, Symbol.iterator, undefined, "items"); + TemporalHelpers.observeProperty(actual, items, "length", 2, "items"); + TemporalHelpers.observeProperty(actual, items, 0, 2, "items"); + TemporalHelpers.observeProperty(actual, items, 1, 1, "items"); + const result = await Array.fromAsync(items); + assert.compareArray(result, [2, 1]); + assert.compareArray(actual, [ + "get items[Symbol.asyncIterator]", + "get items[Symbol.iterator]", + "get items.length", + "get items[0]", + "get items[1]", + ]); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-string.js b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-string.js new file mode 100644 index 000000000000..4d991b070b88 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-string.js @@ -0,0 +1,16 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Array.fromAsync iterates over a string +includes: [asyncHelpers.js, compareArray.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const result = await Array.fromAsync("test"); + assert.compareArray(result, ["t", "e", "s", "t"]); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-symbol.js b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-symbol.js new file mode 100644 index 000000000000..3764f173dec4 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-symbol.js @@ -0,0 +1,20 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Array.fromAsync treats a Symbol as an array-like +includes: [asyncHelpers.js, compareArray.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + Symbol.prototype.length = 2; + Symbol.prototype[0] = 1; + Symbol.prototype[1] = 2; + + const result = await Array.fromAsync(Symbol()); + assert.compareArray(result, [1, 2]); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-uses-intrinsic-iterator-symbols.js b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-uses-intrinsic-iterator-symbols.js new file mode 100644 index 000000000000..8e33a274cb45 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/asyncitems-uses-intrinsic-iterator-symbols.js @@ -0,0 +1,40 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Use the intrinsic @@iterator and @@asyncIterator to check iterability +includes: [compareArray.js, asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + // Replace the user-reachable Symbol.iterator and Symbol.asyncIterator with + // fake symbol keys + const originalSymbol = globalThis.Symbol; + const fakeIteratorSymbol = Symbol("iterator"); + const fakeAsyncIteratorSymbol = Symbol("asyncIterator"); + globalThis.Symbol = { + iterator: fakeIteratorSymbol, + asyncIterator: fakeAsyncIteratorSymbol, + }; + + const input = { + length: 3, + 0: 0, + 1: 1, + 2: 2, + [fakeIteratorSymbol]() { + throw new Test262Error("The fake Symbol.iterator method should not be called"); + }, + [fakeAsyncIteratorSymbol]() { + throw new Test262Error("The fake Symbol.asyncIterator method should not be called"); + } + }; + const output = await Array.fromAsync(input); + assert.compareArray(output, [0, 1, 2]); + + globalThis.Symbol = originalSymbol; +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-async-arraylike.js b/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-async-arraylike.js new file mode 100644 index 000000000000..7e032a2bdc1c --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-async-arraylike.js @@ -0,0 +1,35 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + An asynchronous mapping function is applied to each (awaited) item of an + arraylike. +info: | + 3.k.vii.4. If _mapping_ is *true*, then + a. Let _mappedValue_ be ? Call(_mapfn_, _thisArg_, « _nextValue_, 𝔽(_k_) »). + b. Let _mappedValue_ be ? Await(_mappedValue_). + ... + 6. Perform ? CreateDataPropertyOrThrow(_A_, _Pk_, _mappedValue_). +flags: [async] +includes: [asyncHelpers.js, compareArray.js] +features: [Array.fromAsync] +---*/ + +const arrayLike = { + length: 4, + 0: 0, + 1: 2, + 2: Promise.resolve(4), + 3: 6, +}; + +async function asyncMap(val, ix) { + return Promise.resolve(val * ix); +} + +asyncTest(async () => { + const result = await Array.fromAsync(arrayLike, asyncMap); + assert.compareArray(result, [0, 2, 8, 18], "async mapfn should be applied to arraylike"); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-async-iterable-async.js b/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-async-iterable-async.js new file mode 100644 index 000000000000..24cf748b50c9 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-async-iterable-async.js @@ -0,0 +1,35 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + An asynchronous mapping function is applied to each item yielded by an + asynchronous iterable. +info: | + 3.j.ii.6. If _mapping_ is *true*, then + a. Let _mappedValue_ be Call(_mapfn_, _thisArg_, « _nextValue_, 𝔽(_k_) »). + ... + c. Set _mappedValue_ to Await(_mappedValue_). + ... + ... + 8. Let _defineStatus_ be CreateDataPropertyOrThrow(_A_, _Pk_, _mappedValue_). +flags: [async] +includes: [asyncHelpers.js, compareArray.js] +features: [Array.fromAsync] +---*/ + +async function* asyncGen() { + for (let i = 0; i < 4; i++) { + yield Promise.resolve(i * 2); + } +} + +async function asyncMap(val, ix) { + return Promise.resolve(val * ix); +} + +asyncTest(async () => { + const result = await Array.fromAsync({ [Symbol.asyncIterator]: asyncGen }, asyncMap); + assert.compareArray(result, [0, 2, 8, 18], "async mapfn should be applied to async iterable"); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-async-iterable-sync.js b/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-async-iterable-sync.js new file mode 100644 index 000000000000..1211d7b8eeab --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-async-iterable-sync.js @@ -0,0 +1,35 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + An asynchronous mapping function is applied to each item yielded by a + synchronous iterable. +info: | + 3.j.ii.6. If _mapping_ is *true*, then + a. Let _mappedValue_ be Call(_mapfn_, _thisArg_, « _nextValue_, 𝔽(_k_) »). + ... + c. Set _mappedValue_ to Await(_mappedValue_). + ... + ... + 8. Let _defineStatus_ be CreateDataPropertyOrThrow(_A_, _Pk_, _mappedValue_). +flags: [async] +includes: [asyncHelpers.js, compareArray.js] +features: [Array.fromAsync] +---*/ + +function* syncGen() { + for (let i = 0; i < 4; i++) { + yield i * 2; + } +} + +async function asyncMap(val, ix) { + return Promise.resolve(val * ix); +} + +asyncTest(async () => { + const result = await Array.fromAsync({ [Symbol.iterator]: syncGen }, asyncMap); + assert.compareArray(result, [0, 2, 8, 18], "async mapfn should be applied to sync iterable"); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-async-throws-close-async-iterator.js b/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-async-throws-close-async-iterator.js new file mode 100644 index 000000000000..fdb769fbb78c --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-async-throws-close-async-iterator.js @@ -0,0 +1,40 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + The iterator of an asynchronous iterable is closed when the asynchronous + mapping function throws. +info: | + 3.j.ii.6. If _mapping_ is *true*, then + a. Let _mappedValue_ be Call(_mapfn_, _thisArg_, « _nextValue_, 𝔽(_k_) »). + ... + c. Set _mappedValue_ to Await(_mappedValue_). + d. IfAbruptCloseAsyncIterator(_mappedValue_, _iteratorRecord_). +flags: [async] +includes: [asyncHelpers.js] +features: [Array.fromAsync] +---*/ + +let closed = false; +const iterator = { + next() { + return Promise.resolve({ value: 1, done: false }); + }, + return() { + closed = true; + return Promise.resolve({ done: true }); + }, + [Symbol.asyncIterator]() { + return this; + } +} + +asyncTest(async () => { + await assert.throwsAsync(Error, () => Array.fromAsync(iterator, async (val) => { + assert.sameValue(val, 1, "mapfn receives value from iterator"); + throw new Error("mapfn throws"); + }), "async mapfn rejecting should cause fromAsync to reject"); + assert(closed, "async mapfn rejecting should close iterator") +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-async-throws-close-sync-iterator.js b/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-async-throws-close-sync-iterator.js new file mode 100644 index 000000000000..13b21d7a64c9 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-async-throws-close-sync-iterator.js @@ -0,0 +1,40 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + The iterator of a synchronous iterable is closed when the asynchronous mapping + function throws. +info: | + 3.j.ii.6. If _mapping_ is *true*, then + a. Let _mappedValue_ be Call(_mapfn_, _thisArg_, « _nextValue_, 𝔽(_k_) »). + ... + c. Set _mappedValue_ to Await(_mappedValue_). + d. IfAbruptCloseAsyncIterator(_mappedValue_, _iteratorRecord_). +flags: [async] +includes: [asyncHelpers.js] +features: [Array.fromAsync] +---*/ + +let closed = false; +const iterator = { + next() { + return { value: 1, done: false }; + }, + return() { + closed = true; + return { done: true }; + }, + [Symbol.iterator]() { + return this; + } +} + +asyncTest(async () => { + await assert.throwsAsync(Error, () => Array.fromAsync(iterator, async (val) => { + assert.sameValue(val, 1, "mapfn receives value from iterator"); + throw new Error("mapfn throws"); + }), "async mapfn rejecting should cause fromAsync to reject"); + assert(closed, "async mapfn rejecting should close iterator") +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-async-throws.js b/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-async-throws.js new file mode 100644 index 000000000000..8d148a356ba9 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-async-throws.js @@ -0,0 +1,23 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + The output promise rejects if the asynchronous mapping function rejects. +info: | + 3.j.ii.6. If _mapping_ is *true*, then + a. Let _mappedValue_ be Call(_mapfn_, _thisArg_, « _nextValue_, 𝔽(_k_) »). + ... + c. Set _mappedValue_ to Await(_mappedValue_). + d. IfAbruptCloseAsyncIterator(_mappedValue_, _iteratorRecord_). +flags: [async] +includes: [asyncHelpers.js] +features: [Array.fromAsync] +---*/ + +asyncTest(async () => { + await assert.throwsAsync(Test262Error, () => Array.fromAsync([1, 2, 3], async () => { + throw new Test262Error("mapfn throws"); + }), "async mapfn rejecting should cause fromAsync to reject"); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-not-callable.js b/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-not-callable.js new file mode 100644 index 000000000000..c3f8e2f9d2ae --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-not-callable.js @@ -0,0 +1,25 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + A TypeError is thrown if the mapfn argument to Array.fromAsync is not callable +info: | + 3.a. If _mapfn_ is *undefined*, let _mapping_ be *false*. + b. Else, + i. If IsCallable(_mapfn_) is *false*, throw a *TypeError* exception. +flags: [async] +includes: [asyncHelpers.js] +features: [Array.fromAsync, BigInt, Symbol] +---*/ + +asyncTest(async () => { + await assert.throwsAsync(TypeError, () => Array.fromAsync([], null), "null mapfn"); + await assert.throwsAsync(TypeError, () => Array.fromAsync([], {}), "non-callable object mapfn"); + await assert.throwsAsync(TypeError, () => Array.fromAsync([], "String"), "string mapfn"); + await assert.throwsAsync(TypeError, () => Array.fromAsync([], true), "boolean mapfn"); + await assert.throwsAsync(TypeError, () => Array.fromAsync([], 3.1416), "number mapfn"); + await assert.throwsAsync(TypeError, () => Array.fromAsync([], 42n), "bigint mapfn"); + await assert.throwsAsync(TypeError, () => Array.fromAsync([], Symbol()), "symbol mapfn"); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-result-awaited-once-per-iteration.js b/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-result-awaited-once-per-iteration.js new file mode 100644 index 000000000000..0b3e60eff5c7 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-result-awaited-once-per-iteration.js @@ -0,0 +1,47 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + The returned value from each invocation of the asynchronous mapping function + is awaited exactly once. +info: | + 3.j.ii.6. If _mapping_ is *true*, then + a. Let _mappedValue_ be Call(_mapfn_, _thisArg_, « _nextValue_, 𝔽(_k_) »). + ... + c. Set _mappedValue_ to Await(_mappedValue_). +flags: [async] +includes: [asyncHelpers.js, compareArray.js, temporalHelpers.js] +features: [Array.fromAsync] +---*/ + +const calls = []; +const expected = [ + "call mapping", + "get thenable_0.then", + "call thenable_0.then", + "call mapping", + "get thenable_1.then", + "call thenable_1.then", + "call mapping", + "get thenable_2.then", + "call thenable_2.then", +]; + +function mapping(val, ix) { + calls.push("call mapping"); + const thenableName = `thenable_${ix}`; + return TemporalHelpers.propertyBagObserver(calls, { + then(resolve, reject) { + calls.push(`call ${thenableName}.then`); + resolve(val * 2); + } + }, thenableName) +} + +asyncTest(async () => { + const result = await Array.fromAsync([1, 2, 3], mapping); + assert.compareArray(result, [2, 4, 6], "mapping function applied"); + assert.compareArray(calls, expected, "observable operations"); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-sync-arraylike.js b/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-sync-arraylike.js new file mode 100644 index 000000000000..2ebf437341cc --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-sync-arraylike.js @@ -0,0 +1,35 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + A synchronous mapping function is applied to each (awaited) item of an + arraylike. +info: | + 3.k.vii.4. If _mapping_ is *true*, then + a. Let _mappedValue_ be ? Call(_mapfn_, _thisArg_, « _nextValue_, 𝔽(_k_) »). + ... + ... + 6. Perform ? CreateDataPropertyOrThrow(_A_, _Pk_, _mappedValue_). +flags: [async] +includes: [asyncHelpers.js, compareArray.js] +features: [Array.fromAsync] +---*/ + +const arrayLike = { + length: 4, + 0: 0, + 1: 2, + 2: Promise.resolve(4), + 3: 6, +}; + +function syncMap(val, ix) { + return val * ix; +} + +asyncTest(async () => { + const result = await Array.fromAsync(arrayLike, syncMap); + assert.compareArray(result, [0, 2, 8, 18], "sync mapfn should be applied to arraylike"); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-sync-iterable-async.js b/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-sync-iterable-async.js new file mode 100644 index 000000000000..4ffe4cc84b66 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-sync-iterable-async.js @@ -0,0 +1,33 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + A synchronous mapping function is applied to each item yielded by an + asynchronous iterable. +info: | + 3.j.ii.6. If _mapping_ is *true*, then + a. Let _mappedValue_ be Call(_mapfn_, _thisArg_, « _nextValue_, 𝔽(_k_) »). + ... + ... + 8. Let _defineStatus_ be CreateDataPropertyOrThrow(_A_, _Pk_, _mappedValue_). +flags: [async] +includes: [asyncHelpers.js, compareArray.js] +features: [Array.fromAsync] +---*/ + +async function* asyncGen() { + for (let i = 0; i < 4; i++) { + yield Promise.resolve(i * 2); + } +} + +function syncMap(val, ix) { + return val * ix; +} + +asyncTest(async () => { + const result = await Array.fromAsync({ [Symbol.asyncIterator]: asyncGen }, syncMap); + assert.compareArray(result, [0, 2, 8, 18], "sync mapfn should be applied to async iterable"); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-sync-iterable-sync.js b/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-sync-iterable-sync.js new file mode 100644 index 000000000000..b2a00ec2a25a --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-sync-iterable-sync.js @@ -0,0 +1,33 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + A synchronous mapping function is applied to each item yielded by a + synchronous iterable. +info: | + 3.j.ii.6. If _mapping_ is *true*, then + a. Let _mappedValue_ be Call(_mapfn_, _thisArg_, « _nextValue_, 𝔽(_k_) »). + ... + ... + 8. Let _defineStatus_ be CreateDataPropertyOrThrow(_A_, _Pk_, _mappedValue_). +flags: [async] +includes: [asyncHelpers.js, compareArray.js] +features: [Array.fromAsync] +---*/ + +function* syncGen() { + for (let i = 0; i < 4; i++) { + yield i * 2; + } +} + +function syncMap(val, ix) { + return val * ix; +} + +asyncTest(async () => { + const result = await Array.fromAsync({ [Symbol.iterator]: syncGen }, syncMap); + assert.compareArray(result, [0, 2, 8, 18], "sync mapfn should be applied to sync iterable"); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-sync-throws-close-async-iterator.js b/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-sync-throws-close-async-iterator.js new file mode 100644 index 000000000000..722a53bd36c4 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-sync-throws-close-async-iterator.js @@ -0,0 +1,39 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + The iterator of an asynchronous iterable is closed when the synchronous + mapping function throws. +info: | + 3.j.ii.6. If _mapping_ is *true*, then + a. Let _mappedValue_ be Call(_mapfn_, _thisArg_, « _nextValue_, 𝔽(_k_) »). + b. IfAbruptCloseAsyncIterator(_mappedValue_, _iteratorRecord_). + ... +flags: [async] +includes: [asyncHelpers.js] +features: [Array.fromAsync] +---*/ + +let closed = false; +const iterator = { + next() { + return Promise.resolve({ value: 1, done: false }); + }, + return() { + closed = true; + return Promise.resolve({ done: true }); + }, + [Symbol.asyncIterator]() { + return this; + } +} + +asyncTest(async () => { + await assert.throwsAsync(Error, () => Array.fromAsync(iterator, (val) => { + assert.sameValue(val, 1, "mapfn receives value from iterator"); + throw new Error("mapfn throws"); + }), "sync mapfn throwing should cause fromAsync to reject"); + assert(closed, "sync mapfn throwing should close iterator") +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-sync-throws-close-sync-iterator.js b/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-sync-throws-close-sync-iterator.js new file mode 100644 index 000000000000..15fea81c2d21 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-sync-throws-close-sync-iterator.js @@ -0,0 +1,39 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + The iterator of a synchronous iterable is closed when the synchronous mapping + function throws. +info: | + 3.j.ii.6. If _mapping_ is *true*, then + a. Let _mappedValue_ be Call(_mapfn_, _thisArg_, « _nextValue_, 𝔽(_k_) »). + b. IfAbruptCloseAsyncIterator(_mappedValue_, _iteratorRecord_). + ... +flags: [async] +includes: [asyncHelpers.js] +features: [Array.fromAsync] +---*/ + +let closed = false; +const iterator = { + next() { + return { value: 1, done: false }; + }, + return() { + closed = true; + return { done: true }; + }, + [Symbol.iterator]() { + return this; + } +} + +asyncTest(async () => { + await assert.throwsAsync(Error, () => Array.fromAsync(iterator, (val) => { + assert.sameValue(val, 1, "mapfn receives value from iterator"); + throw new Error("mapfn throws"); + }), "sync mapfn throwing should cause fromAsync to reject"); + assert(closed, "sync mapfn throwing should close iterator") +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-sync-throws.js b/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-sync-throws.js new file mode 100644 index 000000000000..c3bc739ff5d6 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/mapfn-sync-throws.js @@ -0,0 +1,22 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + The output promise rejects if the synchronous mapping function throws. +info: | + 3.j.ii.6. If _mapping_ is *true*, then + a. Let _mappedValue_ be Call(_mapfn_, _thisArg_, « _nextValue_, 𝔽(_k_) »). + b. IfAbruptCloseAsyncIterator(_mappedValue_, _iteratorRecord_). + ... +flags: [async] +includes: [asyncHelpers.js] +features: [Array.fromAsync] +---*/ + +asyncTest(async () => { + await assert.throwsAsync(Test262Error, () => Array.fromAsync([1, 2, 3], () => { + throw new Test262Error("mapfn throws"); + }), "sync mapfn throwing should cause fromAsync to reject"); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-input-does-not-use-array-prototype.js b/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-input-does-not-use-array-prototype.js new file mode 100644 index 000000000000..14206d12255e --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-input-does-not-use-array-prototype.js @@ -0,0 +1,46 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Non-iterable input does not use Array.prototype +includes: [compareArray.js, asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { +const arrayIterator = [].values(); +const IntrinsicArrayIteratorPrototype = +Object.getPrototypeOf(arrayIterator); +const intrinsicArrayIteratorPrototypeNext = +IntrinsicArrayIteratorPrototype.next; + +try { +// Temporarily mutate the array iterator prototype to have an invalid +// “next” method. Just like Array.from, the fromAsync function should +// still work on non-iterable arraylike arguments. +IntrinsicArrayIteratorPrototype.next = function fakeNext () { + throw new Test262Error( + 'This fake next function should not be called; ' + + 'instead, each element should have been directly accessed.', + ); +}; + +const expected = [ 0, 1, 2 ]; +const input = { + length: 3, + 0: 0, + 1: 1, + 2: 2, +}; +const output = await Array.fromAsync(input); +assert.compareArray(output, expected); +} + +finally { +// Reset the intrinsic array iterator +IntrinsicArrayIteratorPrototype.next = + intrinsicArrayIteratorPrototypeNext; +} +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-input-element-access-err.js b/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-input-element-access-err.js new file mode 100644 index 000000000000..09f594c4e892 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-input-element-access-err.js @@ -0,0 +1,21 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Result promise rejects if element access fails +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const input = { + length: 1, + get 0 () { + throw new Test262Error; + }, + }; + const outputPromise = Array.fromAsync(input); + assert.throwsAsync(Test262Error, () => outputPromise); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-input-with-thenable-async-mapped-awaits-callback-result-once.js b/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-input-with-thenable-async-mapped-awaits-callback-result-once.js new file mode 100644 index 000000000000..13c69c9d4576 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-input-with-thenable-async-mapped-awaits-callback-result-once.js @@ -0,0 +1,32 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Non-iterable input with thenable result with async mapped awaits each callback result once. +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + let awaitCounter = 0; + const input = { + length: 3, + 0: 0, + 1: Promise.resolve(1), + 2: Promise.resolve(2), + 3: Promise.resolve(3), // This is ignored because the length is 3. + }; + await Array.fromAsync(input, async v => { + return { + // This “then” method should occur three times: + // one for each value from the input. + then (resolve, reject) { + awaitCounter ++; + resolve(v); + }, + }; + }); + assert.sameValue(awaitCounter, 3); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-input-with-thenable-async-mapped-callback-err.js b/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-input-with-thenable-async-mapped-callback-err.js new file mode 100644 index 000000000000..6d29d2fa49ca --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-input-with-thenable-async-mapped-callback-err.js @@ -0,0 +1,27 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Non-iterable input with thenable result promise rejects if async map function callback throws. +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const expectedValue = {}; + const inputThenable = { + then (resolve, reject) { + resolve(expectedValue); + }, + }; + const input = { + length: 1, + 0: inputThenable, + }; + const outputPromise = Array.fromAsync(input, async v => { + throw new Test262Error; + }); + assert.throwsAsync(Test262Error, () => outputPromise); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-input-with-thenable-element-rejects.js b/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-input-with-thenable-element-rejects.js new file mode 100644 index 000000000000..cf8ad3d1df8e --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-input-with-thenable-element-rejects.js @@ -0,0 +1,26 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Non-iterable input with thenable result promise rejects if thenable element rejects. +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const expectedValue = {}; + const expected = [ expectedValue ]; + const inputThenable = { + then (resolve, reject) { + reject(new Test262Error); + }, + }; + const input = { + length: 1, + 0: inputThenable, + }; + const output = Array.fromAsync(input); + await assert.throwsAsync(Test262Error, () => output); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-input-with-thenable-sync-mapped-callback-err.js b/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-input-with-thenable-sync-mapped-callback-err.js new file mode 100644 index 000000000000..8eacb723ec19 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-input-with-thenable-sync-mapped-callback-err.js @@ -0,0 +1,21 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Non iterable result promise rejects if sync map function callback throws. +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const input = { + length: 1, + 0: 0, + }; + const outputPromise = Array.fromAsync(input, v => { + throw new Test262Error; + }); + assert.throwsAsync(Test262Error, () => outputPromise); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-input-with-thenable.js b/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-input-with-thenable.js new file mode 100644 index 000000000000..1fd840d5b175 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-input-with-thenable.js @@ -0,0 +1,24 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Non iterable input with thenables is transferred to the output array. +includes: [compareArray.js, asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const expected = [ 0, 1, 2 ]; + const input = { + length: 3, + 0: 0, + 1: Promise.resolve(1), + 2: Promise.resolve(2), + 3: Promise.resolve(3), // This is ignored because the length is 3. + }; + const output = await Array.fromAsync(input); + assert.compareArray(output, expected); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-input.js b/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-input.js new file mode 100644 index 000000000000..a212cc5d2e90 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-input.js @@ -0,0 +1,24 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Non iterable input without thenables is transferred to the output array. +includes: [compareArray.js, asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const expected = [ 0, 1, 2 ]; + const input = { + length: 3, + 0: 0, + 1: 1, + 2: 2, + 3: 3, // This is ignored because the length is 3. + }; + const output = await Array.fromAsync(input); + assert.compareArray(output, expected); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-sync-mapped-callback-err.js b/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-sync-mapped-callback-err.js new file mode 100644 index 000000000000..30e25c20bd47 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-sync-mapped-callback-err.js @@ -0,0 +1,27 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Non iterable input with thenables awaits each input once without mapping callback +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const expectedValue = {}; + const inputThenable = { + then (resolve, reject) { + resolve(expectedValue); + }, + }; + const input = { + length: 1, + 0: inputThenable, + }; + const outputPromise = Array.fromAsync(input, v => { + throw new Test262Error; + }); + await assert.throwsAsync(Test262Error, () => outputPromise); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-with-non-promise-thenable.js b/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-with-non-promise-thenable.js new file mode 100644 index 000000000000..5a8005306822 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-with-non-promise-thenable.js @@ -0,0 +1,26 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Non iterable input with non-promise thenables works. +includes: [compareArray.js, asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const expectedValue = {}; + const expected = [ expectedValue ]; + const inputThenable = { + then (resolve, reject) { + resolve(expectedValue); + }, + }; + const input = { + length: 1, + 0: inputThenable, + }; + const output = await Array.fromAsync(input); + assert.compareArray(output, expected); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-with-thenable-async-mapped-awaits-once.js b/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-with-thenable-async-mapped-awaits-once.js new file mode 100644 index 000000000000..187f479e2f52 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-with-thenable-async-mapped-awaits-once.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Non-iterable input with thenables awaits each input once without mapping callback +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const expectedValue = {}; + const expected = [ expectedValue ]; + let awaitCounter = 0; + const inputThenable = { + then (resolve, reject) { + awaitCounter++; + resolve(expectedValue); + }, + }; + const input = { + length: 1, + 0: inputThenable, + }; + await Array.fromAsync(input, async v => v); + assert.sameValue(awaitCounter, 1); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-with-thenable-awaits-once.js b/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-with-thenable-awaits-once.js new file mode 100644 index 000000000000..7a0cb0058260 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-with-thenable-awaits-once.js @@ -0,0 +1,27 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Non-iterable with thenables awaits each input value once without mapping callback. +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const expectedValue = {}; + let awaitCounter = 0; + const inputThenable = { + then (resolve, reject) { + awaitCounter ++; + resolve(expectedValue); + }, + }; + const input = { + length: 1, + 0: inputThenable, + }; + await Array.fromAsync(input); + assert.sameValue(awaitCounter, 1); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-with-thenable-sync-mapped-awaits-once.js b/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-with-thenable-sync-mapped-awaits-once.js new file mode 100644 index 000000000000..5e23cf559a09 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-with-thenable-sync-mapped-awaits-once.js @@ -0,0 +1,28 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Non-iterable input with thenables awaits each input once with mapping callback +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const expectedValue = {}; + let awaitCounter = 0; + const inputThenable = { + then (resolve, reject) { + awaitCounter++; + resolve(expectedValue); + }, + }; + const input = { + length: 1, + 0: inputThenable, + }; + await Array.fromAsync(input, v => v); + assert.sameValue(awaitCounter, 1); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-with-thenable-then-method-err.js b/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-with-thenable-then-method-err.js new file mode 100644 index 000000000000..68f9eae8ce0b --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/non-iterable-with-thenable-then-method-err.js @@ -0,0 +1,24 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Non-iterable input with thenable result promise is rejected if element's then method throws. +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const inputThenable = { + then (resolve, reject) { + throw new Test262Error; + }, + }; + const input = { + length: 1, + 0: inputThenable, + }; + const outputPromise = Array.fromAsync(input); + assert.throwsAsync(Test262Error, () => outputPromise); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/returned-promise-resolves-to-array.js b/JSTests/test262/test/built-ins/Array/fromAsync/returned-promise-resolves-to-array.js new file mode 100644 index 000000000000..576140e58e43 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/returned-promise-resolves-to-array.js @@ -0,0 +1,22 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Array.fromAsync returns a Promise that resolves to an Array in the normal case +info: | + 1. Let _C_ be the *this* value. + ... + 3.e. If IsConstructor(_C_) is *true*, then + i. Let _A_ be ? Construct(_C_). +features: [Array.fromAsync] +flags: [async] +includes: [asyncHelpers.js] +---*/ + +asyncTest(async function () { + const promise = Array.fromAsync([0, 1, 2]); + const array = await promise; + assert(Array.isArray(array), "Array.fromAsync returns a Promise that resolves to an Array"); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/returns-promise.js b/JSTests/test262/test/built-ins/Array/fromAsync/returns-promise.js new file mode 100644 index 000000000000..76f01a5b5fa8 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/returns-promise.js @@ -0,0 +1,35 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Array.fromAsync returns a Promise +info: | + 5. Return _promiseCapability_.[[Promise]]. +flags: [async] +includes: [asyncHelpers.js] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + let p = Array.fromAsync([0, 1, 2]); + + assert(p instanceof Promise, "Array.fromAsync returns a Promise"); + assert.sameValue( + Object.getPrototypeOf(p), + Promise.prototype, + "Array.fromAsync returns an object with prototype Promise.prototype" + ); + + p = Array.fromAsync([0, 1, 2], () => { + throw new Test262Error("this will make the Promise reject"); + }) + assert(p instanceof Promise, "Array.fromAsync returns a Promise even on error"); + assert.sameValue( + Object.getPrototypeOf(p), + Promise.prototype, + "Array.fromAsync returns an object with prototype Promise.prototype even on error" + ); + + await assert.throwsAsync(Test262Error, () => p, "Prevent unhandled rejection"); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/sync-iterable-input-with-non-promise-thenable.js b/JSTests/test262/test/built-ins/Array/fromAsync/sync-iterable-input-with-non-promise-thenable.js new file mode 100644 index 000000000000..0abfe52b72ce --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/sync-iterable-input-with-non-promise-thenable.js @@ -0,0 +1,23 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Sync-iterable input with non-promise thenables works. +includes: [compareArray.js, asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const expectedValue = {}; + const expected = [ expectedValue ]; + const inputThenable = { + then (resolve, reject) { + resolve(expectedValue); + }, + }; + const input = [ inputThenable ].values(); + const output = await Array.fromAsync(input); + assert.compareArray(output, expected); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/sync-iterable-input-with-thenable.js b/JSTests/test262/test/built-ins/Array/fromAsync/sync-iterable-input-with-thenable.js new file mode 100644 index 000000000000..8a9bf7c7f4f8 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/sync-iterable-input-with-thenable.js @@ -0,0 +1,17 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Sync-iterable input with thenables is transferred to the output array. +includes: [compareArray.js, asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const expected = [ 0, 1, 2 ]; + const input = [ 0, Promise.resolve(1), Promise.resolve(2) ].values(); + const output = await Array.fromAsync(input); + assert.compareArray(output, expected); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/sync-iterable-input.js b/JSTests/test262/test/built-ins/Array/fromAsync/sync-iterable-input.js new file mode 100644 index 000000000000..e2ec5524ac06 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/sync-iterable-input.js @@ -0,0 +1,17 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Sync-iterable input with no promises is transferred to the output array. +includes: [compareArray.js, asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const expected = [ 0, 1, 2 ]; + const input = [ 0, 1, 2 ].values(); + const output = await Array.fromAsync(input); + assert.compareArray(output, expected); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/sync-iterable-iteration-err.js b/JSTests/test262/test/built-ins/Array/fromAsync/sync-iterable-iteration-err.js new file mode 100644 index 000000000000..c3b94994f968 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/sync-iterable-iteration-err.js @@ -0,0 +1,19 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Sync iterable result promise rejects if iteration of input fails. +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + function *generateInput () { + throw new Test262Error; + } + const input = generateInput(); + const outputPromise = Array.fromAsync(input); + await assert.throwsAsync(Test262Error, () => outputPromise); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-async-mapped-awaits-once.js b/JSTests/test262/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-async-mapped-awaits-once.js new file mode 100644 index 000000000000..443fd8f21450 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-async-mapped-awaits-once.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Sync-iterable input with thenables awaits each input once with async mapping callback. +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const expectedValue = {}; + let awaitCounter = 0; + const inputThenable = { + then (resolve, reject) { + awaitCounter++; + resolve(expectedValue); + }, + }; + const input = [ inputThenable ].values(); + await Array.fromAsync(input, async v => v); + assert.sameValue(awaitCounter, 1); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-async-mapped-callback-err.js b/JSTests/test262/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-async-mapped-callback-err.js new file mode 100644 index 000000000000..dae13c011875 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-async-mapped-callback-err.js @@ -0,0 +1,18 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Sync-iterable input with thenable result promise rejects if async map function callback throws. +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const input = [ Promise.resolve(0) ].values(); + const outputPromise = Array.fromAsync(input, async v => { + throw new Test262Error; + }); + await assert.throwsAsync(Test262Error, () => outputPromise); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-awaits-once.js b/JSTests/test262/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-awaits-once.js new file mode 100644 index 000000000000..5d30f8dc13df --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-awaits-once.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Sync-iterable input with thenables awaits each input once without mapping callback +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const expectedValue = {}; + let awaitCounter = 0; + const inputThenable = { + then (resolve, reject) { + awaitCounter++; + resolve(expectedValue); + }, + }; + const input = [ inputThenable ].values(); + await Array.fromAsync(input); + assert.sameValue(awaitCounter, 1); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-element-rejects.js b/JSTests/test262/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-element-rejects.js new file mode 100644 index 000000000000..53179d2f3e14 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-element-rejects.js @@ -0,0 +1,21 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Result promise rejects if then method of input fails. +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const inputThenable = { + then (resolve, reject) { + reject(new Test262Error); + }, + }; + const input = [ inputThenable ].values(); + const output = Array.fromAsync(input); + await assert.throwsAsync(Test262Error, () => output); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-sync-mapped-awaits-once.js b/JSTests/test262/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-sync-mapped-awaits-once.js new file mode 100644 index 000000000000..a9ab3282aec7 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-sync-mapped-awaits-once.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Sync-iterable input with mapfn awaits each input once with sync mapping callback +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const expectedValue = {}; + let awaitCounter = 0; + const inputThenable = { + then (resolve, reject) { + awaitCounter++; + resolve(expectedValue); + }, + }; + const input = [ inputThenable ].values(); + await Array.fromAsync(input, v => v); + assert.sameValue(awaitCounter, 1); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-sync-mapped-callback-err.js b/JSTests/test262/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-sync-mapped-callback-err.js new file mode 100644 index 000000000000..023d6aae2a42 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-sync-mapped-callback-err.js @@ -0,0 +1,18 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Sync-iterable input with thenable result promise rejects if sync map function callback throws. +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const input = [ Promise.resolve(0) ].values(); + const outputPromise = Array.fromAsync(input, v => { + throw new Test262Error; + }); + await assert.throwsAsync(Test262Error, () => outputPromise); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-then-method-err.js b/JSTests/test262/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-then-method-err.js new file mode 100644 index 000000000000..965fe38c67b0 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-then-method-err.js @@ -0,0 +1,23 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Result promise rejects if then method of input fails. +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const expectedValue = {}; + const expected = [ expectedValue ]; + const inputThenable = { + then (resolve, reject) { + throw new Test262Error(); + }, + }; + const input = [ inputThenable ].values(); + const output = Array.fromAsync(input); + await assert.throwsAsync(Test262Error, () => output); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/this-constructor-operations.js b/JSTests/test262/test/built-ins/Array/fromAsync/this-constructor-operations.js new file mode 100644 index 000000000000..1a66f19a7c52 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/this-constructor-operations.js @@ -0,0 +1,75 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Order of user-observable operations on a custom this-value and its instances +includes: [compareArray.js, asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +function formatPropertyName(propertyKey, objectName = "") { + switch (typeof propertyKey) { + case "symbol": + if (Symbol.keyFor(propertyKey) !== undefined) { + return `${objectName}[Symbol.for('${Symbol.keyFor(propertyKey)}')]`; + } else if (propertyKey.description.startsWith('Symbol.')) { + return `${objectName}[${propertyKey.description}]`; + } else { + return `${objectName}[Symbol('${propertyKey.description}')]` + } + case "string": + if (propertyKey !== String(Number(propertyKey))) + return objectName ? `${objectName}.${propertyKey}` : propertyKey; + // fall through + default: + // integer or string integer-index + return `${objectName}[${propertyKey}]`; + } +} + +asyncTest(async function () { + const expectedCalls = [ + "construct MyArray", + "defineProperty A[0]", + "defineProperty A[1]", + "set A.length" + ]; + const actualCalls = []; + + function MyArray(...args) { + actualCalls.push("construct MyArray"); + return new Proxy(Object.create(null), { + set(target, key, value) { + actualCalls.push(`set ${formatPropertyName(key, "A")}`); + return Reflect.set(target, key, value); + }, + defineProperty(target, key, descriptor) { + actualCalls.push(`defineProperty ${formatPropertyName(key, "A")}`); + return Reflect.defineProperty(target, key, descriptor); + } + }); + } + + let result = await Array.fromAsync.call(MyArray, [1, 2]); + assert.compareArray(expectedCalls, actualCalls, "order of operations for array argument"); + + actualCalls.splice(0); // reset + + // Note https://github.com/tc39/proposal-array-from-async/issues/35 + const expectedCallsForArrayLike = [ + "construct MyArray", + "construct MyArray", + "defineProperty A[0]", + "defineProperty A[1]", + "set A.length" + ]; + result = await Array.fromAsync.call(MyArray, { + length: 2, + 0: 1, + 1: 2 + }); + assert.compareArray(expectedCallsForArrayLike, actualCalls, "order of operations for array-like argument"); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/this-constructor-with-bad-length-setter.js b/JSTests/test262/test/built-ins/Array/fromAsync/this-constructor-with-bad-length-setter.js new file mode 100644 index 000000000000..a4f70621a24b --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/this-constructor-with-bad-length-setter.js @@ -0,0 +1,33 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Rejects the promise if setting the length fails on an instance of a custom + this-value +info: | + 3.j.ii.4.a. Perform ? Set(_A_, *"length"*, 𝔽(_k_), *true*). + ... + 3.k.viii. Perform ? Set(_A_, *"length"*, 𝔽(_len_), *true*) +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + class MyArray { + set length(v) { + throw new Test262Error("setter of length property throws") + } + } + + await assert.throwsAsync(Test262Error, () => Array.fromAsync.call(MyArray, [0, 1, 2]), "Promise rejected if setting length fails"); + + await assert.throwsAsync(Test262Error, () => Array.fromAsync.call(MyArray, { + length: 3, + 0: 0, + 1: 1, + 2: 2 + }), "Promise rejected if setting length from array-like fails"); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/this-constructor-with-readonly-elements.js b/JSTests/test262/test/built-ins/Array/fromAsync/this-constructor-with-readonly-elements.js new file mode 100644 index 000000000000..ca243a301aab --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/this-constructor-with-readonly-elements.js @@ -0,0 +1,50 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Overwrites non-writable element properties on an instance of a custom + this-value +info: | + 3.j.ii.8. Let _defineStatus_ be CreateDataPropertyOrThrow(_A_, _Pk_, _mappedValue_). + ... + 3.k.vii.6. Perform ? CreateDataPropertyOrThrow(_A_, _Pk_, _mappedValue_). +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + function MyArray() { + this.length = 4; + for (let ix = 0; ix < this.length; ix++) { + Object.defineProperty(this, ix, { + enumerable: true, + writable: false, + configurable: true, + value: 99 + }); + } + } + + let result = await Array.fromAsync.call(MyArray, [0, 1, 2]); + assert.sameValue(result.length, 3, "Length property is overwritten"); + assert.sameValue(result[0], 0, "Read-only element 0 is overwritten"); + assert.sameValue(result[1], 1, "Read-only element 1 is overwritten"); + assert.sameValue(result[2], 2, "Read-only element 2 is overwritten"); + assert.sameValue(result[3], 99, "Element 3 is not overwritten"); + + result = await Array.fromAsync.call(MyArray, { + length: 3, + 0: 0, + 1: 1, + 2: 2, + 3: 3 // ignored + }); + assert.sameValue(result.length, 3, "Length property is overwritten"); + assert.sameValue(result[0], 0, "Read-only element 0 is overwritten"); + assert.sameValue(result[1], 1, "Read-only element 1 is overwritten"); + assert.sameValue(result[2], 2, "Read-only element 2 is overwritten"); + assert.sameValue(result[3], 99, "Element 3 is not overwritten"); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/this-constructor-with-readonly-length.js b/JSTests/test262/test/built-ins/Array/fromAsync/this-constructor-with-readonly-length.js new file mode 100644 index 000000000000..ff0e91e6f9ae --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/this-constructor-with-readonly-length.js @@ -0,0 +1,38 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Promise is rejected if length property on an instance of a custom this-value + is non-writable +info: | + 3.j.ii.4.a. Perform ? Set(_A_, *"length"*, 𝔽(_k_), *true*). + ... + 3.k.viii. Perform ? Set(_A_, *"length"*, 𝔽(_len_), *true*). + + Note that there is no difference between strict mode and sloppy mode, because + we are not following runtime evaluation semantics. +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + function MyArray() { + Object.defineProperty(this, "length", { + enumerable: true, + writable: false, + configurable: true, + value: 99 + }); + } + + await assert.throwsAsync(TypeError, () => Array.fromAsync.call(MyArray, [0, 1, 2]), "Setting read-only length fails"); + await assert.throwsAsync(TypeError, () => Array.fromAsync.call(MyArray, { + length: 3, + 0: 0, + 1: 1, + 2: 2 + }), "Setting read-only length fails in array-like case"); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/this-constructor-with-unsettable-element-closes-async-iterator.js b/JSTests/test262/test/built-ins/Array/fromAsync/this-constructor-with-unsettable-element-closes-async-iterator.js new file mode 100644 index 000000000000..c9b2b08ee761 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/this-constructor-with-unsettable-element-closes-async-iterator.js @@ -0,0 +1,43 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Closes an async iterator if setting an element fails on an instance of a + custom this-value +info: | + 3.j.ii.8. Let _defineStatus_ be CreateDataPropertyOrThrow(_A_, _Pk_, _mappedValue_). + 9. If _defineStatus_ is an abrupt completion, return ? AsyncIteratorClose(_iteratorRecord_, _defineStatus_). +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + function MyArray() { + Object.defineProperty(this, 0, { + enumerable: true, + writable: true, + configurable: false, + value: 0 + }); + } + + let closed = false; + const iterator = { + next() { + return Promise.resolve({ value: 1, done: false }); + }, + return() { + closed = true; + return Promise.resolve({ done: true }); + }, + [Symbol.asyncIterator]() { + return this; + } + } + + await assert.throwsAsync(TypeError, () => Array.fromAsync.call(MyArray, iterator), "Promise rejected if defining element fails"); + assert(closed, "element define failure should close iterator"); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/this-constructor-with-unsettable-element-closes-sync-iterator.js b/JSTests/test262/test/built-ins/Array/fromAsync/this-constructor-with-unsettable-element-closes-sync-iterator.js new file mode 100644 index 000000000000..44a94156ab01 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/this-constructor-with-unsettable-element-closes-sync-iterator.js @@ -0,0 +1,43 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Closes a sync iterator if setting an element fails on an instance of a custom + this-value +info: | + 3.j.ii.8. Let _defineStatus_ be CreateDataPropertyOrThrow(_A_, _Pk_, _mappedValue_). + 9. If _defineStatus_ is an abrupt completion, return ? AsyncIteratorClose(_iteratorRecord_, _defineStatus_). +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + function MyArray() { + Object.defineProperty(this, 0, { + enumerable: true, + writable: true, + configurable: false, + value: 0 + }); + } + + let closed = false; + const iterator = { + next() { + return { value: 1, done: false }; + }, + return() { + closed = true; + return { done: true }; + }, + [Symbol.iterator]() { + return this; + } + } + + await assert.throwsAsync(TypeError, () => Array.fromAsync.call(MyArray, iterator), "Promise rejected if defining element fails"); + assert(closed, "element define failure should close iterator"); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/this-constructor-with-unsettable-element.js b/JSTests/test262/test/built-ins/Array/fromAsync/this-constructor-with-unsettable-element.js new file mode 100644 index 000000000000..c001be0e4418 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/this-constructor-with-unsettable-element.js @@ -0,0 +1,28 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Rejects the promise if setting an element fails on an instance of a custom + this-value +info: | + 3.j.ii.8. Let _defineStatus_ be CreateDataPropertyOrThrow(_A_, _Pk_, _mappedValue_). + 9. If _defineStatus_ is an abrupt completion, return ? AsyncIteratorClose(_iteratorRecord_, _defineStatus_). +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + function MyArray() { + Object.defineProperty(this, 0, { + enumerable: true, + writable: true, + configurable: false, + value: 0 + }); + } + + await assert.throwsAsync(TypeError, () => Array.fromAsync.call(MyArray, [0, 1, 2]), "Promise rejected if defining element fails"); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/this-constructor.js b/JSTests/test262/test/built-ins/Array/fromAsync/this-constructor.js new file mode 100644 index 000000000000..c95db50c6cd1 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/this-constructor.js @@ -0,0 +1,53 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Constructs the this-value once if asyncItems is iterable, twice if not, and + length and element properties are set correctly on the result +info: | + 3.e. If IsConstructor(_C_) is *true*, then + i. Let _A_ be ? Construct(_C_). + ... + j. If _iteratorRecord_ is not *undefined*, then + ... + k. Else, + ... + iv. If IsConstructor(_C_) is *true*, then + 1. Let _A_ be ? Construct(_C_, « 𝔽(_len_) »). +includes: [compareArray.js, asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const constructorCalls = []; + + function MyArray(...args) { + constructorCalls.push(args); + } + + let result = await Array.fromAsync.call(MyArray, [1, 2]); + assert(result instanceof MyArray, "result is an instance of the constructor this-value"); + assert.sameValue(result.length, 2, "length is set on result"); + assert.sameValue(result[0], 1, "element 0 is set on result"); + assert.sameValue(result[1], 2, "element 1 is set on result"); + assert.sameValue(constructorCalls.length, 1, "constructor is called once"); + assert.compareArray(constructorCalls[0], [], "constructor is called with no arguments"); + + constructorCalls.splice(0); // reset + + result = await Array.fromAsync.call(MyArray, { + length: 2, + 0: 1, + 1: 2 + }); + assert(result instanceof MyArray, "result is an instance of the constructor this-value"); + assert.sameValue(result.length, 2, "length is set on result"); + assert.sameValue(result[0], 1, "element 0 is set on result"); + assert.sameValue(result[1], 2, "element 1 is set on result"); + assert.sameValue(constructorCalls.length, 2, "constructor is called twice"); + assert.compareArray(constructorCalls[0], [], "constructor is called first with no arguments"); + assert.compareArray(constructorCalls[1], [2], "constructor is called second with a length argument"); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/this-non-constructor.js b/JSTests/test262/test/built-ins/Array/fromAsync/this-non-constructor.js new file mode 100644 index 000000000000..f65101940265 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/this-non-constructor.js @@ -0,0 +1,48 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Constructs an intrinsic Array if this-value is not a constructor, and length + and element properties are set accordingly. +info: | + 3.e. If IsConstructor(_C_) is *true*, then + ... + f. Else, + i. Let _A_ be ! ArrayCreate(0). + + ... + j. If _iteratorRecord_ is not *undefined*, then + ... + k. Else, + ... + iv. If IsConstructor(_C_) is *true*, then + ... + v. Else, + 1. Let _A_ be ? ArrayCreate(_len_). +includes: [compareArray.js, asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const thisValue = { + length: 4000, + 0: 32, + 1: 64, + 2: 128 + }; + + let result = await Array.fromAsync.call(thisValue, [1, 2]); + assert(Array.isArray(result), "result is an intrinsic Array"); + assert.compareArray(result, [1, 2], "result is not disrupted by properties of this-value"); + + result = await Array.fromAsync.call(thisValue, { + length: 2, + 0: 1, + 1: 2 + }); + assert(Array.isArray(result), "result is an intrinsic Array"); + assert.compareArray(result, [1, 2], "result is not disrupted by properties of this-value"); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/thisarg-object.js b/JSTests/test262/test/built-ins/Array/fromAsync/thisarg-object.js new file mode 100644 index 000000000000..1f27785692c3 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/thisarg-object.js @@ -0,0 +1,21 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: If thisArg is an object, it's bound to mapfn as the this-value +info: | + 6. If _mapping_ is *true*, then + a. Let _mappedValue_ be Call(_mapfn_, _thisArg_, « _nextValue_, 𝔽(_k_) »). +flags: [async] +includes: [asyncHelpers.js] +features: [Array.fromAsync] +---*/ + +asyncTest(async () => { + const myThisValue = {}; + + await Array.fromAsync([1, 2, 3], async function () { + assert.sameValue(this, myThisValue, "thisArg should be bound as the this-value of mapfn"); + }, myThisValue); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/thisarg-omitted-sloppy.js b/JSTests/test262/test/built-ins/Array/fromAsync/thisarg-omitted-sloppy.js new file mode 100644 index 000000000000..b17ed5f33985 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/thisarg-omitted-sloppy.js @@ -0,0 +1,33 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + If thisArg is omitted, mapfn is called with the global object as the + this-value in sloppy mode +info: | + 6. If _mapping_ is *true*, then + a. Let _mappedValue_ be Call(_mapfn_, _thisArg_, « _nextValue_, 𝔽(_k_) »). + + OrdinaryCallBindThis, when _F_.[[ThisMode]] is ~global~, where _F_ is the + function object: + 6. Else, + a. If _thisArgument_ is *undefined* or *null*, then + i. Let _globalEnv_ be _calleeRealm_.[[GlobalEnv]]. + ii. Assert: _globalEnv_ is a Global Environment Record. + iii. Let _thisValue_ be _globalEnv_.[[GlobalThisValue]]. +flags: [async, noStrict] +includes: [asyncHelpers.js] +features: [Array.fromAsync] +---*/ + +asyncTest(async () => { + await Array.fromAsync([1, 2, 3], async function () { + assert.sameValue( + this, + globalThis, + "the global should be bound as the this-value of mapfn when thisArg is omitted" + ); + }); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/thisarg-omitted-strict.js b/JSTests/test262/test/built-ins/Array/fromAsync/thisarg-omitted-strict.js new file mode 100644 index 000000000000..3dead992e2bf --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/thisarg-omitted-strict.js @@ -0,0 +1,28 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + If thisArg is omitted, mapfn is called with undefined as the this-value in + strict mode +info: | + 6. If _mapping_ is *true*, then + a. Let _mappedValue_ be Call(_mapfn_, _thisArg_, « _nextValue_, 𝔽(_k_) »). + + In OrdinaryCallBindThis, _thisArgument_ is always bound as the this-value in + strict mode (_F_.[[ThisMode]] is ~strict~, where _F_ is the function object.) +flags: [async, onlyStrict] +includes: [asyncHelpers.js] +features: [Array.fromAsync] +---*/ + +asyncTest(async () => { + await Array.fromAsync([1, 2, 3], async function () { + assert.sameValue( + this, + undefined, + "undefined should be bound as the this-value of mapfn when thisArg is omitted" + ); + }); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/thisarg-primitive-sloppy.js b/JSTests/test262/test/built-ins/Array/fromAsync/thisarg-primitive-sloppy.js new file mode 100644 index 000000000000..c459102a54b0 --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/thisarg-primitive-sloppy.js @@ -0,0 +1,75 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + If thisArg is a primitive, mapfn is called with a wrapper this-value or the + global, according to the usual rules of sloppy mode +info: | + 6. If _mapping_ is *true*, then + a. Let _mappedValue_ be Call(_mapfn_, _thisArg_, « _nextValue_, 𝔽(_k_) »). + + OrdinaryCallBindThis, when _F_.[[ThisMode]] is ~global~, where _F_ is the + function object: + 6. Else, + a. If _thisArgument_ is *undefined* or *null*, then + i. Let _globalEnv_ be _calleeRealm_.[[GlobalEnv]]. + ii. Assert: _globalEnv_ is a Global Environment Record. + iii. Let _thisValue_ be _globalEnv_.[[GlobalThisValue]]. + b. Else, + i. Let _thisValue_ be ! ToObject(_thisArgument_). + ii. NOTE: ToObject produces wrapper objects using _calleeRealm_. +flags: [async, noStrict] +includes: [asyncHelpers.js] +features: [Array.fromAsync] +---*/ + +asyncTest(async () => { + await Array.fromAsync([1, 2, 3], async function () { + assert.sameValue( + this, + globalThis, + "the global should be bound as the this-value of mapfn when thisArg is undefined" + ); + }, undefined); + + await Array.fromAsync([1, 2, 3], async function () { + assert.sameValue( + this, + globalThis, + "the global should be bound as the this-value of mapfn when thisArg is null" + ); + }, null); + + await Array.fromAsync([1, 2, 3], async function () { + assert.notSameValue(this, "string", "string thisArg should not be bound as the this-value of mapfn"); + assert.sameValue(typeof this, "object", "a String wrapper object should be bound as the this-value of mapfn when thisArg is a string") + assert.sameValue(this.valueOf(), "string", "String wrapper object should have the same primitive value as thisArg"); + }, "string"); + + await Array.fromAsync([1, 2, 3], async function () { + assert.notSameValue(this, 3.1416, "number thisArg should be not bound as the this-value of mapfn"); + assert.sameValue(typeof this, "object", "a Number wrapper object should be bound as the this-value of mapfn when thisArg is a number") + assert.sameValue(this.valueOf(), 3.1416, "Number wrapper object should have the same primitive value as thisArg"); + }, 3.1416); + + await Array.fromAsync([1, 2, 3], async function () { + assert.notSameValue(this, 42n, "bigint thisArg should not be bound as the this-value of mapfn"); + assert.sameValue(typeof this, "object", "a BigInt wrapper object should be bound as the this-value of mapfn when thisArg is a bigint") + assert.sameValue(this.valueOf(), 42n, "BigInt wrapper object should have the same primitive value as thisArg"); + }, 42n); + + await Array.fromAsync([1, 2, 3], async function () { + assert.notSameValue(this, true, "boolean thisArg should not be bound as the this-value of mapfn"); + assert.sameValue(typeof this, "object", "a Boolean wrapper object should be bound as the this-value of mapfn when thisArg is a boolean") + assert.sameValue(this.valueOf(), true, "Boolean wrapper object should have the same primitive value as thisArg"); + }, true); + + const symbolThis = Symbol("symbol"); + await Array.fromAsync([1, 2, 3], async function () { + assert.notSameValue(this, symbolThis, "symbol thisArg should not be bound as the this-value of mapfn"); + assert.sameValue(typeof this, "object", "a Symbol wrapper object should be bound as the this-value of mapfn when thisArg is a symbol") + assert.sameValue(this.valueOf(), symbolThis, "Symbol wrapper object should have the same primitive value as thisArg"); + }, symbolThis); +}); diff --git a/JSTests/test262/test/built-ins/Array/fromAsync/thisarg-primitive-strict.js b/JSTests/test262/test/built-ins/Array/fromAsync/thisarg-primitive-strict.js new file mode 100644 index 000000000000..34118d1953af --- /dev/null +++ b/JSTests/test262/test/built-ins/Array/fromAsync/thisarg-primitive-strict.js @@ -0,0 +1,49 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + If thisArg is a primitive, mapfn is called with it as the this-value in strict + mode +info: | + 6. If _mapping_ is *true*, then + a. Let _mappedValue_ be Call(_mapfn_, _thisArg_, « _nextValue_, 𝔽(_k_) »). + + In OrdinaryCallBindThis, _thisArgument_ is always bound as the this-value in + strict mode (_F_.[[ThisMode]] is ~strict~, where _F_ is the function object.) +flags: [async, onlyStrict] +includes: [asyncHelpers.js] +features: [Array.fromAsync] +---*/ + +asyncTest(async () => { + await Array.fromAsync([1, 2, 3], async function () { + assert.sameValue(this, undefined, "undefined thisArg should be bound as the this-value of mapfn"); + }, undefined); + + await Array.fromAsync([1, 2, 3], async function () { + assert.sameValue(this, null, "null thisArg should be bound as the this-value of mapfn"); + }, null); + + await Array.fromAsync([1, 2, 3], async function () { + assert.sameValue(this, "string", "string thisArg should be bound as the this-value of mapfn"); + }, "string"); + + await Array.fromAsync([1, 2, 3], async function () { + assert.sameValue(this, 3.1416, "number thisArg should be bound as the this-value of mapfn"); + }, 3.1416); + + await Array.fromAsync([1, 2, 3], async function () { + assert.sameValue(this, 42n, "bigint thisArg should be bound as the this-value of mapfn"); + }, 42n); + + await Array.fromAsync([1, 2, 3], async function () { + assert.sameValue(this, true, "boolean thisArg should be bound as the this-value of mapfn"); + }, true); + + const symbolThis = Symbol("symbol"); + await Array.fromAsync([1, 2, 3], async function () { + assert.sameValue(this, symbolThis, "symbol thisArg should be bound as the this-value of mapfn"); + }, symbolThis); +}); diff --git a/JSTests/test262/test/built-ins/Array/prototype/Symbol.unscopables/array-grouping.js b/JSTests/test262/test/built-ins/Array/prototype/Symbol.unscopables/array-grouping.js deleted file mode 100644 index 0631ccf37c04..000000000000 --- a/JSTests/test262/test/built-ins/Array/prototype/Symbol.unscopables/array-grouping.js +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (C) 2022 Chengzhong Wu. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-array.prototype-@@unscopables -description: > - Initial value of `Symbol.unscopables` property -info: | - 22.1.3.32 Array.prototype [ @@unscopables ] - - ... - 10. Perform ! CreateDataPropertyOrThrow(unscopableList, "group", true). - 11. Perform ! CreateDataPropertyOrThrow(unscopableList, "groupToMap", true). - ... - -includes: [propertyHelper.js] -features: [Symbol.unscopables, array-grouping] ----*/ - -var unscopables = Array.prototype[Symbol.unscopables]; - -assert.sameValue(Object.getPrototypeOf(unscopables), null); - -assert.sameValue(unscopables.group, true, '`group` property value'); -verifyEnumerable(unscopables, 'group'); -verifyWritable(unscopables, 'group'); -verifyConfigurable(unscopables, 'group'); - -assert.sameValue(unscopables.groupToMap, true, '`groupToMap` property value'); -verifyEnumerable(unscopables, 'groupToMap'); -verifyWritable(unscopables, 'groupToMap'); -verifyConfigurable(unscopables, 'groupToMap'); diff --git a/JSTests/test262/test/built-ins/Array/prototype/group/array-like.js b/JSTests/test262/test/built-ins/Array/prototype/group/array-like.js deleted file mode 100644 index 42a7b085ae9e..000000000000 --- a/JSTests/test262/test/built-ins/Array/prototype/group/array-like.js +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) 2021 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-array.prototype.group -description: Array.prototype.group iterates array-like up to length -info: | - 22.1.3.14 Array.prototype.group ( callbackfn [ , thisArg ] ) - - ... - - 2. Let len be ? LengthOfArrayLike(O). - ... - 4. Let k be 0. - ... - 6. Repeat, while k < len - - ... -includes: [compareArray.js] -features: [array-grouping] ----*/ - -const arrayLike = {0: 1, 1: 2, 2: 3, 3: 4, length: 3 }; - -let calls = 0; - -const obj = Array.prototype.group.call(arrayLike, function (i) { calls++; return i % 2 === 0 ? 'even' : 'odd'; }); - -assert.sameValue(calls, 3, 'only calls length times'); -assert.compareArray(Object.keys(obj), ['odd', 'even']); -assert.compareArray(obj['even'], [2]); -assert.compareArray(obj['odd'], [1, 3]); diff --git a/JSTests/test262/test/built-ins/Array/prototype/group/callback-arg.js b/JSTests/test262/test/built-ins/Array/prototype/group/callback-arg.js deleted file mode 100644 index 5d38d65df735..000000000000 --- a/JSTests/test262/test/built-ins/Array/prototype/group/callback-arg.js +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) 2021 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-array.prototype.group -description: Array.prototype.group calls function with correct arguments -info: | - 22.1.3.14 Array.prototype.group ( callbackfn [ , thisArg ] ) - - ... - - 6. Repeat, while k < len - - a. Let Pk be ! ToString(𝔽(k)). - b. Let kValue be ? Get(O, Pk). - c. Let propertyKey be ? ToPropertyKey(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)). - d. Perform ! AddValueToKeyedGroup(groups, propertyKey, kValue). - e. Set k to k + 1. - ... -features: [array-grouping] ----*/ - - -const arr = [-0, 0, 1, 2, 3]; - -let calls = 0; - -const map = arr.group(function (n, i, testArr) { - calls++; - assert.sameValue(n, arr[i], "selected element aligns with index"); - assert.sameValue(testArr, arr, "original array is passed as final argument"); - return null; -}); - -assert.sameValue(calls, 5, 'called for all 5 elements'); diff --git a/JSTests/test262/test/built-ins/Array/prototype/group/callback-throws.js b/JSTests/test262/test/built-ins/Array/prototype/group/callback-throws.js deleted file mode 100644 index 785a7b74a337..000000000000 --- a/JSTests/test262/test/built-ins/Array/prototype/group/callback-throws.js +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) 2021 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-array.prototype.group -description: Array.prototype.group errors when return value cannot be converted to a property key. -info: | - 22.1.3.14 Array.prototype.group ( callbackfn [ , thisArg ] ) - - ... - - 6. Repeat, while k < len - c. Let propertyKey be ? ToPropertyKey(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)). - - ... -features: [array-grouping] ----*/ - -assert.throws(Test262Error, function() { - const array = [1]; - array.group(function() { - throw new Test262Error('throw in callback'); - }) -}); diff --git a/JSTests/test262/test/built-ins/Array/prototype/group/emptyList.js b/JSTests/test262/test/built-ins/Array/prototype/group/emptyList.js deleted file mode 100644 index 366c12d08d06..000000000000 --- a/JSTests/test262/test/built-ins/Array/prototype/group/emptyList.js +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2021 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-array.prototype.group -description: Callback is not called and object is not populated if the array is empty -info: | - 22.1.3.14 Array.prototype.group ( callbackfn [ , thisArg ] ) - - ... - - 8. For each Record { [[Key]], [[Elements]] } g of groups, do - - a. Let elements be ! CreateArrayFromList(g.[[Elements]]). - b. Perform ! CreateDataPropertyOrThrow(obj, g.[[Key]], elements). - - ... -features: [array-grouping] ----*/ - -const original = []; - -const obj = original.group(function () { - throw new Test262Error('callback function should not be called') -}); - -assert.notSameValue(original, obj, 'group returns a object'); -assert.sameValue(Object.keys(obj).length, 0); diff --git a/JSTests/test262/test/built-ins/Array/prototype/group/evenOdd.js b/JSTests/test262/test/built-ins/Array/prototype/group/evenOdd.js deleted file mode 100644 index 6d22cb694005..000000000000 --- a/JSTests/test262/test/built-ins/Array/prototype/group/evenOdd.js +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) 2021 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-array.prototype.group -description: Array.prototype.group populates object with correct keys and values -info: | - 22.1.3.14 Array.prototype.group ( callbackfn [ , thisArg ] ) - - ... - - 8. For each Record { [[Key]], [[Elements]] } g of groups, do - - a. Let elements be ! CreateArrayFromList(g.[[Elements]]). - b. Perform ! CreateDataPropertyOrThrow(obj, g.[[Key]], elements). - - ... -includes: [compareArray.js] -features: [array-grouping] ----*/ - -const array = [1, 2, 3]; - -const obj = array.group(function (i) { - return i % 2 === 0 ? 'even' : 'odd'; -}); - -assert.compareArray(Object.keys(obj), ['odd', 'even']); -assert.compareArray(obj['even'], [2]); -assert.compareArray(obj['odd'], [1, 3]); diff --git a/JSTests/test262/test/built-ins/Array/prototype/group/get-throws.js b/JSTests/test262/test/built-ins/Array/prototype/group/get-throws.js deleted file mode 100644 index d9182c661d56..000000000000 --- a/JSTests/test262/test/built-ins/Array/prototype/group/get-throws.js +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) 2021 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-array.prototype.group -description: Array.prototype.group errors when accessing a getter throws. -info: | - 22.1.3.14 Array.prototype.group ( callbackfn [ , thisArg ] ) - - ... - - 6. Repeat, while k < len - a. Let Pk be ! ToString(𝔽(k)). - b. Let kValue be ? Get(O, Pk). - - ... -features: [array-grouping] ----*/ - -assert.throws(Test262Error, function() { - const arrayLike = Object.defineProperty({ - length: 1, - }, '0', { - get: function() { - throw new Test262Error('no element for you'); - } - }); - Array.prototype.group.call(arrayLike, function() { - return 'key'; - }); -}); diff --git a/JSTests/test262/test/built-ins/Array/prototype/group/groupLength.js b/JSTests/test262/test/built-ins/Array/prototype/group/groupLength.js deleted file mode 100644 index 2123378e1132..000000000000 --- a/JSTests/test262/test/built-ins/Array/prototype/group/groupLength.js +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2021 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-array.prototype.group -description: Callback can return numbers that are converted to property keys -info: | - 22.1.3.14 Array.prototype.group ( callbackfn [ , thisArg ] ) - - ... - - 8. For each Record { [[Key]], [[Elements]] } g of groups, do - - a. Let elements be ! CreateArrayFromList(g.[[Elements]]). - b. Perform ! CreateDataPropertyOrThrow(obj, g.[[Key]], elements). - - ... -includes: [compareArray.js] -features: [array-grouping] ----*/ - -const arr = ['hello', 'test', 'world']; - -const obj = arr.group(function (i) { return i.length; }); - -assert.compareArray(Object.keys(obj), ['4', '5']); -assert.compareArray(obj['5'], ['hello', 'world']); -assert.compareArray(obj['4'], ['test']); diff --git a/JSTests/test262/test/built-ins/Array/prototype/group/invalid-callback.js b/JSTests/test262/test/built-ins/Array/prototype/group/invalid-callback.js deleted file mode 100644 index ee5253c21d68..000000000000 --- a/JSTests/test262/test/built-ins/Array/prototype/group/invalid-callback.js +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) 2021 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-array.prototype.group -description: Array.prototype.group called with non-callable throws TypeError -info: | - 22.1.3.14 Array.prototype.group ( callbackfn [ , thisArg ] ) - - ... - - 3. If IsCallable(callbackfn) is false, throw a TypeError exception. - - ... -features: [array-grouping] ----*/ - - -assert.throws(TypeError, function() { - [].group(null) -}, "null callback throws TypeError"); - -assert.throws(TypeError, function() { - [].group(undefined) -}, "undefined callback throws TypeError"); - -assert.throws(TypeError, function() { - [].group({}) -}, "object callback throws TypeError"); diff --git a/JSTests/test262/test/built-ins/Array/prototype/group/invalid-object.js b/JSTests/test262/test/built-ins/Array/prototype/group/invalid-object.js deleted file mode 100644 index 244377832a55..000000000000 --- a/JSTests/test262/test/built-ins/Array/prototype/group/invalid-object.js +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2021 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-array.prototype.group -description: Array.prototype.group applied to null/undefined throws a TypeError -info: | - 22.1.3.14 Array.prototype.group ( callbackfn [ , thisArg ] ) - - ... - - 1. Let O be ? ToObject(this value). - - ... -features: [array-grouping] ----*/ - -const throws = function() { - throw new Test262Error('callback function should not be called') -}; - -assert.throws(TypeError, function() { - Array.prototype.group.call(undefined, throws); -}, 'undefined this value'); - -assert.throws(TypeError, function() { - Array.prototype.group.call(undefined, throws); -}, 'null this value'); diff --git a/JSTests/test262/test/built-ins/Array/prototype/group/invalid-property-key.js b/JSTests/test262/test/built-ins/Array/prototype/group/invalid-property-key.js deleted file mode 100644 index ce92006f1d85..000000000000 --- a/JSTests/test262/test/built-ins/Array/prototype/group/invalid-property-key.js +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2021 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-array.prototype.group -description: Array.prototype.group errors when return value cannot be converted to a property key. -info: | - 22.1.3.14 Array.prototype.group ( callbackfn [ , thisArg ] ) - - ... - - 6. Repeat, while k < len - c. Let propertyKey be ? ToPropertyKey(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)). - - ... -features: [array-grouping] ----*/ - -assert.throws(Test262Error, function() { - const array = [1]; - array.group(function() { - return { - toString() { - throw new Test262Error('not a property key'); - } - }; - }) -}); diff --git a/JSTests/test262/test/built-ins/Array/prototype/group/length-throw.js b/JSTests/test262/test/built-ins/Array/prototype/group/length-throw.js deleted file mode 100644 index e3d1747e1290..000000000000 --- a/JSTests/test262/test/built-ins/Array/prototype/group/length-throw.js +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) 2021 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-array.prototype.group -description: Array.prototype.group errors when array-like's length can't be coerced. -info: | - 22.1.3.14 Array.prototype.group ( callbackfn [ , thisArg ] ) - - ... - - 2. Let len be ? LengthOfArrayLike(O). - - ... -features: [array-grouping] ----*/ - -assert.throws(Test262Error, function() { - const arrayLike = Object.defineProperty({}, 'length', { - get: function() { - throw new Test262Error('no length for you'); - } - }); - Array.prototype.group.call(arrayLike, function() { - return 'key'; - }); -}); - -assert.throws(TypeError, function() { - const arrayLike = { - length: 1n, - }; - Array.prototype.group.call(arrayLike, function() { - return 'key'; - }); -}); diff --git a/JSTests/test262/test/built-ins/Array/prototype/group/length.js b/JSTests/test262/test/built-ins/Array/prototype/group/length.js deleted file mode 100644 index ea4896c73d85..000000000000 --- a/JSTests/test262/test/built-ins/Array/prototype/group/length.js +++ /dev/null @@ -1,26 +0,0 @@ - -// Copyright (c) 2021 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-array.prototype.group -description: Array.prototype.group property length descriptor -info: | - 22.1.3.14 Array.prototype.group ( callbackfn [ , thisArg ] ) - - ... - - 17 ECMAScript Standard Built-in Objects - - ... - -includes: [propertyHelper.js] -features: [array-grouping] ----*/ - -verifyProperty(Array.prototype.group, "length", { - value: 1, - enumerable: false, - writable: false, - configurable: true -}); diff --git a/JSTests/test262/test/built-ins/Array/prototype/group/name.js b/JSTests/test262/test/built-ins/Array/prototype/group/name.js deleted file mode 100644 index 26ea6e395e16..000000000000 --- a/JSTests/test262/test/built-ins/Array/prototype/group/name.js +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) 2021 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-array.prototype.group -description: Array.prototype.group property name descriptor -info: | - 22.1.3.14 Array.prototype.group ( callbackfn [ , thisArg ] ) - - ... - - 17 ECMAScript Standard Built-in Objects - - ... - -includes: [propertyHelper.js] -features: [array-grouping] ----*/ - -verifyProperty(Array.prototype.group, "name", { - value: "group", - enumerable: false, - writable: false, - configurable: true -}); diff --git a/JSTests/test262/test/built-ins/Array/prototype/group/null-prototype.js b/JSTests/test262/test/built-ins/Array/prototype/group/null-prototype.js deleted file mode 100644 index c977ee39e485..000000000000 --- a/JSTests/test262/test/built-ins/Array/prototype/group/null-prototype.js +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2021 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-array.prototype.group -description: Array.prototype.group returns a null prototype object -info: | - 22.1.3.14 Array.prototype.group ( callbackfn [ , thisArg ] ) - - ... - - 7. Let obj be OrdinaryObjectCreate(null). - ... - 9. Return obj. - - ... -features: [array-grouping] ----*/ - -const array = [1, 2, 3]; - -const obj = array.group(function (i) { - return i % 2 === 0 ? 'even' : 'odd'; -}); - -assert.sameValue(Object.getPrototypeOf(obj), null); -assert.sameValue(obj.hasOwnProperty, undefined); diff --git a/JSTests/test262/test/built-ins/Array/prototype/group/sparse-array.js b/JSTests/test262/test/built-ins/Array/prototype/group/sparse-array.js deleted file mode 100644 index ab794d169b25..000000000000 --- a/JSTests/test262/test/built-ins/Array/prototype/group/sparse-array.js +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) 2021 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-array.prototype.group -description: Array.prototype.group adds undefined to the group for sparse arrays -info: | - 22.1.3.14 Array.prototype.group ( callbackfn [ , thisArg ] ) - - ... - - 6. Repeat, while k < len - a. Let Pk be ! ToString(𝔽(k)). - b. Let kValue be ? Get(O, Pk). - c. Let propertyKey be ? ToPropertyKey(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)). - d. Perform AddValueToKeyedGroup(groups, propertyKey, kValue). - - ... -includes: [compareArray.js] -features: [array-grouping] ----*/ - -let calls = 0; -const array = [, , ,]; - -const obj = array.group(function () { - calls++; - return 'key'; -}); - -assert.sameValue(calls, 3); - -assert(0 in obj['key'], 'group has a first element'); -assert(1 in obj['key'], 'group has a second element'); -assert(2 in obj['key'], 'group has a third element'); -assert.compareArray(obj['key'], [void 0, void 0, void 0]); diff --git a/JSTests/test262/test/built-ins/Array/prototype/group/this-arg-strict.js b/JSTests/test262/test/built-ins/Array/prototype/group/this-arg-strict.js deleted file mode 100644 index 7f3cfc71230b..000000000000 --- a/JSTests/test262/test/built-ins/Array/prototype/group/this-arg-strict.js +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) 2021 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-array.prototype.group -description: Array.prototype.group calls with thisArg -info: | - 22.1.3.14 Array.prototype.group ( callbackfn [ , thisArg ] ) - - ... - - 6. Repeat, while k < len - c. Let propertyKey be ? ToPropertyKey(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)). - - ... -flags: [onlyStrict] -features: [array-grouping] ----*/ - - -let sentinel = {}; -let result; - -[1].group(function() { - result = this; -}, "TestString"); -assert.sameValue(result, "TestString"); - -[1].group(function() { - result = this; -}, 1); -assert.sameValue(result, 1); - -[1].group(function() { - result = this; -}, true); -assert.sameValue(result, true); - -[1].group(function() { - result = this; -}, null); -assert.sameValue(result, null); - -[1].group(function() { - result = this; -}, sentinel); -assert.sameValue(result, sentinel); - -[1].group(function() { - result = this; -}, void 0); -assert.sameValue(result, void 0); - -[1].group(function() { - result = this; -}); -assert.sameValue(result, void 0); diff --git a/JSTests/test262/test/built-ins/Array/prototype/group/this-arg.js b/JSTests/test262/test/built-ins/Array/prototype/group/this-arg.js deleted file mode 100644 index 15d36c5c6b17..000000000000 --- a/JSTests/test262/test/built-ins/Array/prototype/group/this-arg.js +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) 2021 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-array.prototype.group -description: Array.prototype.group calls with thisArg -info: | - 22.1.3.14 Array.prototype.group ( callbackfn [ , thisArg ] ) - - ... - - 6. Repeat, while k < len - c. Let propertyKey be ? ToPropertyKey(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)). - - ... -flags: [noStrict] -features: [array-grouping] ----*/ - - -let sentinel = {}; -let result; - -[1].group(function() { - result = this; -}, "TestString"); -assert.sameValue(result instanceof String, true); -assert.sameValue(result.valueOf(), "TestString"); - -[1].group(function() { - result = this; -}, 1); -assert.sameValue(result instanceof Number, true); -assert.sameValue(result.valueOf(), 1); - -[1].group(function() { - result = this; -}, true); -assert.sameValue(result instanceof Boolean, true); -assert.sameValue(result.valueOf(), true); - -[1].group(function() { - result = this; -}, null); -assert.sameValue(result, globalThis); - -[1].group(function() { - result = this; -}, sentinel); -assert.sameValue(result, sentinel); - -[1].group(function() { - result = this; -}, void 0); -assert.sameValue(result, globalThis); - -[1].group(function() { - result = this; -}); -assert.sameValue(result, globalThis); diff --git a/JSTests/test262/test/built-ins/Array/prototype/group/toPropertyKey.js b/JSTests/test262/test/built-ins/Array/prototype/group/toPropertyKey.js deleted file mode 100644 index b14ad7488ac8..000000000000 --- a/JSTests/test262/test/built-ins/Array/prototype/group/toPropertyKey.js +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) 2021 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-array.prototype.group -description: Array.prototype.group coerces return value with ToPropertyKey -info: | - 22.1.3.14 Array.prototype.group ( callbackfn [ , thisArg ] ) - - ... - - 6. Repeat, while k < len - c. Let propertyKey be ? ToPropertyKey(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)). - d. Perform AddValueToKeyedGroup(groups, propertyKey, kValue). - ... - 8. For each Record { [[Key]], [[Elements]] } g of groups, do - a. Let elements be ! CreateArrayFromList(g.[[Elements]]). - b. Perform ! CreateDataPropertyOrThrow(obj, g.[[Key]], elements). - - ... -includes: [compareArray.js] -features: [array-grouping] ----*/ - -let calls = 0; -const stringable = { - toString() { - return 1; - } -} - -const array = [1, '1', stringable]; - -const obj = array.group(function (v) { return v; }); - -assert.compareArray(Object.keys(obj), ['1']); -assert.compareArray(obj['1'], [1, '1', stringable]); diff --git a/JSTests/test262/test/built-ins/Array/prototype/groupToMap/array-like.js b/JSTests/test262/test/built-ins/Array/prototype/groupToMap/array-like.js deleted file mode 100644 index a9686063d324..000000000000 --- a/JSTests/test262/test/built-ins/Array/prototype/groupToMap/array-like.js +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) 2021 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-array.prototype.groupToMap -description: Array.prototype.groupToMap iterates array-like up to length -info: | - 22.1.3.15 Array.prototype.groupToMap ( callbackfn [ , thisArg ] ) - - ... - - 2. Let len be ? LengthOfArrayLike(O). - ... - 4. Let k be 0. - ... - 6. Repeat, while k < len - - ... -includes: [compareArray.js] -features: [array-grouping, Map, Symbol.iterator] ----*/ - -const arrayLike = {0: 1, 1: 2, 2: 3, 3: 4, length: 3 }; - -let calls = 0; - -const map = Array.prototype.groupToMap.call(arrayLike, function (i) { - calls++; - return i % 2 === 0 ? 'even' : 'odd'; -}); - -assert.sameValue(calls, 3, 'only calls length times'); -assert.compareArray(Array.from(map.keys()), ['odd', 'even']); -assert.compareArray(map.get('even'), [2]); -assert.compareArray(map.get('odd'), [1, 3]); diff --git a/JSTests/test262/test/built-ins/Array/prototype/groupToMap/callback-arg.js b/JSTests/test262/test/built-ins/Array/prototype/groupToMap/callback-arg.js deleted file mode 100644 index 6f6a38a2e16d..000000000000 --- a/JSTests/test262/test/built-ins/Array/prototype/groupToMap/callback-arg.js +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) 2021 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-array.prototype.groupToMap -description: Array.prototype.groupToMap calls function with correct arguments -info: | - 22.1.3.15 Array.prototype.groupToMap ( callbackfn [ , thisArg ] ) - - ... - - 6. Repeat, while k < len - a. Let Pk be ! ToString(𝔽(k)). - b. Let kValue be ? Get(O, Pk). - c. Let key be ? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »). - e. Perform ! AddValueToKeyedGroup(groups, key, kValue). - ... -features: [array-grouping, Map] ----*/ - - -const arr = [-0, 0, 1, 2, 3]; - -let calls = 0; - -arr.groupToMap(function (n, i, testArr) { - calls++; - assert.sameValue(n, arr[i], "selected element aligns with index"); - assert.sameValue(testArr, arr, "original array is passed as final argument"); - return null; -}); - -assert.sameValue(calls, 5, 'called for all 5 elements'); diff --git a/JSTests/test262/test/built-ins/Array/prototype/groupToMap/callback-throws.js b/JSTests/test262/test/built-ins/Array/prototype/groupToMap/callback-throws.js deleted file mode 100644 index 162d8b0180e4..000000000000 --- a/JSTests/test262/test/built-ins/Array/prototype/groupToMap/callback-throws.js +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) 2021 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-array.prototype.groupToMap -description: Array.prototype.groupToMap errors when return value cannot be converted to a property key. -info: | - 22.1.3.15 Array.prototype.groupToMap ( callbackfn [ , thisArg ] ) - - ... - - 6. Repeat, while k < len - c. Let propertyKey be ? ToPropertyKey(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)). - - ... -features: [array-grouping] ----*/ - -assert.throws(Test262Error, function() { - const array = [1]; - array.groupToMap(function() { - throw new Test262Error('throw in callback'); - }) -}); diff --git a/JSTests/test262/test/built-ins/Array/prototype/groupToMap/emptyList.js b/JSTests/test262/test/built-ins/Array/prototype/groupToMap/emptyList.js deleted file mode 100644 index e5834ff4a200..000000000000 --- a/JSTests/test262/test/built-ins/Array/prototype/groupToMap/emptyList.js +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2021 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-array.prototype.groupToMap -description: Callback is not called and object is not populated if the array is empty -info: | - 22.1.3.15 Array.prototype.groupToMap ( callbackfn [ , thisArg ] ) - - ... - - 8. For each Record { [[Key]], [[Elements]] } g of groups, do - - a. Let elements be ! CreateArrayFromList(g.[[Elements]]). - b. Perform ! CreateDataPropertyOrThrow(map, g.[[Key]], elements). - - ... -features: [array-grouping] ----*/ - -const original = []; - -const map = original.groupToMap(function () { - throw new Test262Error('callback function should not be called') -}); - -assert.notSameValue(original, map, 'groupToMap returns a map'); -assert.sameValue(map.size, 0); diff --git a/JSTests/test262/test/built-ins/Array/prototype/groupToMap/evenOdd.js b/JSTests/test262/test/built-ins/Array/prototype/groupToMap/evenOdd.js deleted file mode 100644 index 1c675de51d15..000000000000 --- a/JSTests/test262/test/built-ins/Array/prototype/groupToMap/evenOdd.js +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) 2021 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-array.prototype.groupToMap -description: Array.prototype.groupToMap populates object with correct keys and values -info: | - 22.1.3.15 Array.prototype.groupToMap ( callbackfn [ , thisArg ] ) - - ... - - 8. For each Record { [[Key]], [[Elements]] } g of groups, do - - a. Let elements be ! CreateArrayFromList(g.[[Elements]]). - b. Perform ! CreateDataPropertyOrThrow(map, g.[[Key]], elements). - - ... -includes: [compareArray.js] -features: [array-grouping, Map, Symbol.iterator] ----*/ - -const array = [1, 2, 3]; - -const map = array.groupToMap(function (i) { - return i % 2 === 0 ? 'even' : 'odd'; -}); - -assert.compareArray(Array.from(map.keys()), ['odd', 'even']); -assert.compareArray(map.get('even'), [2]); -assert.compareArray(map.get('odd'), [1, 3]); diff --git a/JSTests/test262/test/built-ins/Array/prototype/groupToMap/get-throws.js b/JSTests/test262/test/built-ins/Array/prototype/groupToMap/get-throws.js deleted file mode 100644 index cd64d474bf99..000000000000 --- a/JSTests/test262/test/built-ins/Array/prototype/groupToMap/get-throws.js +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) 2021 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-array.prototype.groupToMap -description: Array.prototype.groupToMap errors when accessing a getter throws. -info: | - 22.1.3.15 Array.prototype.groupToMap ( callbackfn [ , thisArg ] ) - - ... - - 6. Repeat, while k < len - a. Let Pk be ! ToString(𝔽(k)). - b. Let kValue be ? Get(O, Pk). - - ... -features: [array-grouping] ----*/ - -assert.throws(Test262Error, function() { - const arrayLike = Object.defineProperty({ - length: 1, - }, '0', { - get: function() { - throw new Test262Error('no element for you'); - } - }); - Array.prototype.groupToMap.call(arrayLike, function() { - return 'key'; - }); -}); diff --git a/JSTests/test262/test/built-ins/Array/prototype/groupToMap/groupLength.js b/JSTests/test262/test/built-ins/Array/prototype/groupToMap/groupLength.js deleted file mode 100644 index b06d5f0d673c..000000000000 --- a/JSTests/test262/test/built-ins/Array/prototype/groupToMap/groupLength.js +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2021 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-array.prototype.groupToMap -description: Array.prototype.groupToMap populates object with correct keys and values -info: | - 22.1.3.15 Array.prototype.groupToMap ( callbackfn [ , thisArg ] ) - - ... - - 8. For each Record { [[Key]], [[Elements]] } g of groups, do - - a. Let elements be ! CreateArrayFromList(g.[[Elements]]). - b. Perform ! CreateDataPropertyOrThrow(map, g.[[Key]], elements). - - ... -includes: [compareArray.js] -features: [array-grouping, Map, Symbol.iterator] ----*/ - -const arr = ['hello', 'test', 'world']; - -const map = arr.groupToMap(function (i) { return i.length; }); - -assert.compareArray(Array.from(map.keys()), [5, 4]); -assert.compareArray(map.get(5), ['hello', 'world']); -assert.compareArray(map.get(4), ['test']); diff --git a/JSTests/test262/test/built-ins/Array/prototype/groupToMap/invalid-callback.js b/JSTests/test262/test/built-ins/Array/prototype/groupToMap/invalid-callback.js deleted file mode 100644 index b59d57c6ba82..000000000000 --- a/JSTests/test262/test/built-ins/Array/prototype/groupToMap/invalid-callback.js +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) 2021 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-array.prototype.groupToMap -description: Array.prototype.groupToMap called with non-callable throws TypeError -info: | - 22.1.3.15 Array.prototype.groupToMap ( callbackfn [ , thisArg ] ) - - ... - - 3. If IsCallable(callbackfn) is false, throw a TypeError exception. - - ... -features: [array-grouping] ----*/ - - -assert.throws(TypeError, function() { - [].groupToMap(null) -}, "null callback throws TypeError"); - -assert.throws(TypeError, function() { - [].groupToMap(undefined) -}, "undefined callback throws TypeError"); - -assert.throws(TypeError, function() { - [].groupToMap({}) -}, "object callback throws TypeError"); diff --git a/JSTests/test262/test/built-ins/Array/prototype/groupToMap/invalid-object.js b/JSTests/test262/test/built-ins/Array/prototype/groupToMap/invalid-object.js deleted file mode 100644 index f7e95b63ad25..000000000000 --- a/JSTests/test262/test/built-ins/Array/prototype/groupToMap/invalid-object.js +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2021 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-array.prototype.groupToMap -description: Array.prototype.groupToMap applied to null/undefined throws a TypeError -info: | - 22.1.3.15 Array.prototype.groupToMap ( callbackfn [ , thisArg ] ) - - ... - - 1. Let O be ? ToObject(this value). - - ... -features: [array-grouping] ----*/ - -const throws = function() { - throw new Test262Error('callback function should not be called') -}; - -assert.throws(TypeError, function() { - Array.prototype.groupToMap.call(undefined, throws); -}, 'undefined this value'); - -assert.throws(TypeError, function() { - Array.prototype.groupToMap.call(undefined, throws); -}, 'null this value'); diff --git a/JSTests/test262/test/built-ins/Array/prototype/groupToMap/invalid-property-key.js b/JSTests/test262/test/built-ins/Array/prototype/groupToMap/invalid-property-key.js deleted file mode 100644 index 990eea14f82f..000000000000 --- a/JSTests/test262/test/built-ins/Array/prototype/groupToMap/invalid-property-key.js +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) 2021 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-array.prototype.groupToMap -description: Array.prototype.groupToMap does not error when return value cannot be converted to a property key. -info: | - 22.1.3.15 Array.prototype.groupToMap ( callbackfn [ , thisArg ] ) - - ... - - 6. Repeat, while k < len - c. Let propertyKey be ? ToPropertyKey(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)). - - ... -includes: [compareArray.js] -features: [array-grouping, Map, Symbol.iterator] ----*/ - -const key = { - toString() { - throw new Test262Error('not a property key'); - } -}; - -const map = [1].groupToMap(function() { - return key; -}); - -assert.compareArray(Array.from(map.keys()), [key]); -assert.compareArray(map.get(key), [1]); diff --git a/JSTests/test262/test/built-ins/Array/prototype/groupToMap/length-throw.js b/JSTests/test262/test/built-ins/Array/prototype/groupToMap/length-throw.js deleted file mode 100644 index 63eb8581cf4c..000000000000 --- a/JSTests/test262/test/built-ins/Array/prototype/groupToMap/length-throw.js +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) 2021 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-array.prototype.groupToMap -description: Array.prototype.groupToMap errors when array-like's length can't be coerced. -info: | - 22.1.3.15 Array.prototype.groupToMap ( callbackfn [ , thisArg ] ) - - ... - - 2. Let len be ? LengthOfArrayLike(O). - - ... -features: [array-grouping] ----*/ - -assert.throws(Test262Error, function() { - const arrayLike = Object.defineProperty({}, 'length', { - get: function() { - throw new Test262Error('no length for you'); - } - }); - Array.prototype.groupToMap.call(arrayLike, function() { - return 'key'; - }); -}); - -assert.throws(TypeError, function() { - const arrayLike = { - length: 1n, - }; - Array.prototype.groupToMap.call(arrayLike, function() { - return 'key'; - }); -}); diff --git a/JSTests/test262/test/built-ins/Array/prototype/groupToMap/length.js b/JSTests/test262/test/built-ins/Array/prototype/groupToMap/length.js deleted file mode 100644 index 822764026c28..000000000000 --- a/JSTests/test262/test/built-ins/Array/prototype/groupToMap/length.js +++ /dev/null @@ -1,26 +0,0 @@ - -// Copyright (c) 2021 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-array.prototype.groupToMap -description: Array.prototype.groupToMap property length descriptor -info: | - 22.1.3.15 Array.prototype.groupToMap ( callbackfn [ , thisArg ] ) - - ... - - 17 ECMAScript Standard Built-in Objects - - ... - -includes: [propertyHelper.js] -features: [array-grouping] ----*/ - -verifyProperty(Array.prototype.groupToMap, "length", { - value: 1, - enumerable: false, - writable: false, - configurable: true -}); diff --git a/JSTests/test262/test/built-ins/Array/prototype/groupToMap/map-instance.js b/JSTests/test262/test/built-ins/Array/prototype/groupToMap/map-instance.js deleted file mode 100644 index bd5c6987f76e..000000000000 --- a/JSTests/test262/test/built-ins/Array/prototype/groupToMap/map-instance.js +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) 2021 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-array.prototype.groupToMap -description: Array.prototype.groupToMap returns a Map instance -info: | - 22.1.3.15 Array.prototype.groupToMap ( callbackfn [ , thisArg ] ) - - ... - - 7. Let map be ! Construct(%Map%). - ... - 9. Return map. - - ... -features: [array-grouping, Map] ----*/ - -const array = [1, 2, 3]; - -const map = array.groupToMap(function (i) { - return i % 2 === 0 ? 'even' : 'odd'; -}); - -assert.sameValue(map instanceof Map, true); diff --git a/JSTests/test262/test/built-ins/Array/prototype/groupToMap/name.js b/JSTests/test262/test/built-ins/Array/prototype/groupToMap/name.js deleted file mode 100644 index 26212fead5ad..000000000000 --- a/JSTests/test262/test/built-ins/Array/prototype/groupToMap/name.js +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) 2021 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-array.prototype.groupToMap -description: Array.prototype.groupToMap property name descriptor -info: | - 22.1.3.15 Array.prototype.groupToMap ( callbackfn [ , thisArg ] ) - - ... - - 17 ECMAScript Standard Built-in Objects - - ... - -includes: [propertyHelper.js] -features: [array-grouping] ----*/ - -verifyProperty(Array.prototype.groupToMap, "name", { - value: "groupToMap", - enumerable: false, - writable: false, - configurable: true -}); diff --git a/JSTests/test262/test/built-ins/Array/prototype/groupToMap/negativeZero.js b/JSTests/test262/test/built-ins/Array/prototype/groupToMap/negativeZero.js deleted file mode 100644 index 7e6cc0acb91a..000000000000 --- a/JSTests/test262/test/built-ins/Array/prototype/groupToMap/negativeZero.js +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) 2021 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-array.prototype.groupToMap -description: Array.prototype.groupToMap normalize 0 for Map key -info: | - 22.1.3.15 Array.prototype.groupToMap ( callbackfn [ , thisArg ] ) - - ... - - 6.d. If key is -0𝔽, set key to +0𝔽. - - ... -includes: [compareArray.js] -features: [array-grouping, Map] ----*/ - - -const arr = [-0, +0]; - -const map = arr.groupToMap(function (i) { return i; }); - -assert.sameValue(map.size, 1); -assert.compareArray(map.get(0), [-0, 0]); diff --git a/JSTests/test262/test/built-ins/Array/prototype/groupToMap/sparse-array.js b/JSTests/test262/test/built-ins/Array/prototype/groupToMap/sparse-array.js deleted file mode 100644 index 801fc5f2ced6..000000000000 --- a/JSTests/test262/test/built-ins/Array/prototype/groupToMap/sparse-array.js +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) 2021 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-array.prototype.groupToMap -description: Array.prototype.groupToMap adds undefined to the group for sparse arrays -info: | - 22.1.3.15 Array.prototype.groupToMap ( callbackfn [ , thisArg ] ) - - ... - - 6. Repeat, while k < len - a. Let Pk be ! ToString(𝔽(k)). - b. Let kValue be ? Get(O, Pk). - c. Let key be ? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »). - e. Perform AddValueToKeyedGroup(groups, key, kValue). - - ... -includes: [compareArray.js] -features: [array-grouping, Map] ----*/ - -let calls = 0; -const array = [, , ,]; - -const map = array.groupToMap(function () { - calls++; - return 'key'; -}); - -assert.sameValue(calls, 3); - -const key = map.get('key'); -assert(0 in key, 'group has a first element'); -assert(1 in key, 'group has a second element'); -assert(2 in key, 'group has a third element'); -assert.compareArray(key, [void 0, void 0, void 0]); diff --git a/JSTests/test262/test/built-ins/Array/prototype/groupToMap/this-arg-strict.js b/JSTests/test262/test/built-ins/Array/prototype/groupToMap/this-arg-strict.js deleted file mode 100644 index 7d3ec3c1cd1e..000000000000 --- a/JSTests/test262/test/built-ins/Array/prototype/groupToMap/this-arg-strict.js +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) 2021 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-array.prototype.groupToMap -description: Array.prototype.groupToMap calls with thisArg -info: | - 22.1.3.15 Array.prototype.groupToMap ( callbackfn [ , thisArg ] ) - - ... - - 6. Repeat, while k < len - c. Let key be ? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »). - - ... -flags: [onlyStrict] -features: [array-grouping, Map] ----*/ - - -let sentinel = {}; -let result; - -[1].groupToMap(function() { - result = this; -}, "TestString"); -assert.sameValue(result, "TestString"); - -[1].groupToMap(function() { - result = this; -}, 1); -assert.sameValue(result, 1); - -[1].groupToMap(function() { - result = this; -}, true); -assert.sameValue(result, true); - -[1].groupToMap(function() { - result = this; -}, null); -assert.sameValue(result, null); - -[1].groupToMap(function() { - result = this; -}, sentinel); -assert.sameValue(result, sentinel); - -[1].groupToMap(function() { - result = this; -}, void 0); -assert.sameValue(result, void 0); - -[1].groupToMap(function() { - result = this; -}); -assert.sameValue(result, void 0); diff --git a/JSTests/test262/test/built-ins/Array/prototype/groupToMap/this-arg.js b/JSTests/test262/test/built-ins/Array/prototype/groupToMap/this-arg.js deleted file mode 100644 index dbe05972e327..000000000000 --- a/JSTests/test262/test/built-ins/Array/prototype/groupToMap/this-arg.js +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) 2021 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-array.prototype.groupToMap -description: Array.prototype.groupToMap calls with thisArg -info: | - 22.1.3.15 Array.prototype.groupToMap ( callbackfn [ , thisArg ] ) - - ... - - 6. Repeat, while k < len - c. Let key be ? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »). - - ... -flags: [noStrict] -features: [array-grouping, Map] ----*/ - - -let sentinel = {}; -let result; - -[1].groupToMap(function() { - result = this; -}, "TestString"); -assert.sameValue(result instanceof String, true); -assert.sameValue(result.valueOf(), "TestString"); - -[1].groupToMap(function() { - result = this; -}, 1); -assert.sameValue(result instanceof Number, true); -assert.sameValue(result.valueOf(), 1); - -[1].groupToMap(function() { - result = this; -}, true); -assert.sameValue(result instanceof Boolean, true); -assert.sameValue(result.valueOf(), true); - -[1].groupToMap(function() { - result = this; -}, null); -assert.sameValue(result, globalThis); - -[1].groupToMap(function() { - result = this; -}, sentinel); -assert.sameValue(result, sentinel); - -[1].groupToMap(function() { - result = this; -}, void 0); -assert.sameValue(result, globalThis); - -[1].groupToMap(function() { - result = this; -}); -assert.sameValue(result, globalThis); diff --git a/JSTests/test262/test/built-ins/Array/prototype/groupToMap/toPropertyKey.js b/JSTests/test262/test/built-ins/Array/prototype/groupToMap/toPropertyKey.js deleted file mode 100644 index f3f8c5f46ff5..000000000000 --- a/JSTests/test262/test/built-ins/Array/prototype/groupToMap/toPropertyKey.js +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2021 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-array.prototype.groupToMap -description: Array.prototype.groupToMap does not coerce return value with ToPropertyKey -info: | - 22.1.3.15 Array.prototype.groupToMap ( callbackfn [ , thisArg ] ) - - ... - - 6. Repeat, while k < len - c. Let key be ? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »). - e. Perform AddValueToKeyedGroup(groups, key, kValue). - ... - 8. For each Record { [[Key]], [[Elements]] } g of groups, do - a. Let elements be ! CreateArrayFromList(g.[[Elements]]). - b. Perform ! CreateDataPropertyOrThrow(map, g.[[Key]], elements). - - ... -includes: [compareArray.js] -features: [array-grouping] ----*/ - -let calls = 0; -const stringable = { - toString() { - return 1; - } -} - -const array = [1, '1', stringable]; - -const map = array.groupToMap(v => v); - -assert.compareArray(Array.from(map.keys()), [1, '1', stringable]); -assert.compareArray(map.get('1'), ['1']); -assert.compareArray(map.get(1), [1]); -assert.compareArray(map.get(stringable), [stringable]); diff --git a/JSTests/test262/test/built-ins/Array/prototype/includes/call-with-boolean.js b/JSTests/test262/test/built-ins/Array/prototype/includes/call-with-boolean.js index 695c249baa57..30b214243e6c 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/includes/call-with-boolean.js +++ b/JSTests/test262/test/built-ins/Array/prototype/includes/call-with-boolean.js @@ -4,6 +4,7 @@ /*--- esid: sec-array.prototype.includes description: Array.prototype.includes applied to boolean primitive +features: [Array.prototype.includes] ---*/ assert.sameValue(Array.prototype.includes.call(true), false, 'Array.prototype.includes.call(true) must return false'); diff --git a/JSTests/test262/test/built-ins/Array/prototype/includes/fromIndex-equal-or-greater-length-returns-false.js b/JSTests/test262/test/built-ins/Array/prototype/includes/fromIndex-equal-or-greater-length-returns-false.js index 84bb4526d8ec..fbb10381b1bd 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/includes/fromIndex-equal-or-greater-length-returns-false.js +++ b/JSTests/test262/test/built-ins/Array/prototype/includes/fromIndex-equal-or-greater-length-returns-false.js @@ -16,6 +16,7 @@ info: | 7. Repeat, while k < len ... 8. Return false. +features: [Array.prototype.includes] ---*/ var sample = [7, 7, 7, 7]; diff --git a/JSTests/test262/test/built-ins/Array/prototype/includes/fromIndex-infinity.js b/JSTests/test262/test/built-ins/Array/prototype/includes/fromIndex-infinity.js index 0c5d3bb270b4..86d0c76595ea 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/includes/fromIndex-infinity.js +++ b/JSTests/test262/test/built-ins/Array/prototype/includes/fromIndex-infinity.js @@ -18,6 +18,7 @@ info: | 7. Repeat, while k < len ... 8. Return false. +features: [Array.prototype.includes] ---*/ var sample = [42, 43, 43, 41]; diff --git a/JSTests/test262/test/built-ins/Array/prototype/includes/fromIndex-minus-zero.js b/JSTests/test262/test/built-ins/Array/prototype/includes/fromIndex-minus-zero.js index 7a6e0087a671..9751a40759f4 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/includes/fromIndex-minus-zero.js +++ b/JSTests/test262/test/built-ins/Array/prototype/includes/fromIndex-minus-zero.js @@ -13,6 +13,7 @@ info: | ... 7. Repeat, while k < len ... +features: [Array.prototype.includes] ---*/ var sample = [42, 43]; diff --git a/JSTests/test262/test/built-ins/Array/prototype/includes/get-prop.js b/JSTests/test262/test/built-ins/Array/prototype/includes/get-prop.js index bea3d5a9afe1..1505b7719b2a 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/includes/get-prop.js +++ b/JSTests/test262/test/built-ins/Array/prototype/includes/get-prop.js @@ -12,7 +12,7 @@ info: | a. Let elementK be the result of ? Get(O, ! ToString(k)). ... includes: [compareArray.js] -features: [Proxy] +features: [Proxy, Array.prototype.includes] ---*/ var calls; diff --git a/JSTests/test262/test/built-ins/Array/prototype/includes/length-boundaries.js b/JSTests/test262/test/built-ins/Array/prototype/includes/length-boundaries.js index 84ac9579c479..bffb3996419d 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/includes/length-boundaries.js +++ b/JSTests/test262/test/built-ins/Array/prototype/includes/length-boundaries.js @@ -17,6 +17,7 @@ info: | 2. If len ≤ +0, return +0. 3. If len is +∞, return 2**53-1. 4. Return min(len, 2**53-1). +features: [Array.prototype.includes] ---*/ var obj = { diff --git a/JSTests/test262/test/built-ins/Array/prototype/includes/length-zero-returns-false.js b/JSTests/test262/test/built-ins/Array/prototype/includes/length-zero-returns-false.js index 7e247c26c69b..098fe4547712 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/includes/length-zero-returns-false.js +++ b/JSTests/test262/test/built-ins/Array/prototype/includes/length-zero-returns-false.js @@ -11,6 +11,7 @@ info: | 2. Let len be ? ToLength(? Get(O, "length")). 3. If len is 0, return false. ... +features: [Array.prototype.includes] ---*/ var calls = 0; diff --git a/JSTests/test262/test/built-ins/Array/prototype/includes/length.js b/JSTests/test262/test/built-ins/Array/prototype/includes/length.js index 0abb6d35aef6..259555a2ef59 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/includes/length.js +++ b/JSTests/test262/test/built-ins/Array/prototype/includes/length.js @@ -20,6 +20,7 @@ info: | object has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. includes: [propertyHelper.js] +features: [Array.prototype.includes] ---*/ assert.sameValue(Array.prototype.includes.length, 1); diff --git a/JSTests/test262/test/built-ins/Array/prototype/includes/name.js b/JSTests/test262/test/built-ins/Array/prototype/includes/name.js index 4391eb02f575..daf171971812 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/includes/name.js +++ b/JSTests/test262/test/built-ins/Array/prototype/includes/name.js @@ -17,6 +17,7 @@ info: | object, if it exists, has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. includes: [propertyHelper.js] +features: [Array.prototype.includes] ---*/ assert.sameValue(Array.prototype.includes.name, "includes"); diff --git a/JSTests/test262/test/built-ins/Array/prototype/includes/no-arg.js b/JSTests/test262/test/built-ins/Array/prototype/includes/no-arg.js index 8c975a642fb6..0480fddddd1f 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/includes/no-arg.js +++ b/JSTests/test262/test/built-ins/Array/prototype/includes/no-arg.js @@ -13,6 +13,7 @@ info: | b. If SameValueZero(searchElement, elementK) is true, return true. c. Increase k by 1. ... +features: [Array.prototype.includes] ---*/ assert.sameValue([0].includes(), false, "[0].includes()"); diff --git a/JSTests/test262/test/built-ins/Array/prototype/includes/not-a-constructor.js b/JSTests/test262/test/built-ins/Array/prototype/includes/not-a-constructor.js index d5052d19fb47..81aca092d0ba 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/includes/not-a-constructor.js +++ b/JSTests/test262/test/built-ins/Array/prototype/includes/not-a-constructor.js @@ -18,7 +18,7 @@ info: | 7. If IsConstructor(constructor) is false, throw a TypeError exception. ... includes: [isConstructor.js] -features: [Reflect.construct, arrow-function] +features: [Reflect.construct, arrow-function, Array.prototype.includes] ---*/ assert.sameValue( diff --git a/JSTests/test262/test/built-ins/Array/prototype/includes/prop-desc.js b/JSTests/test262/test/built-ins/Array/prototype/includes/prop-desc.js index b48a8955fe11..0d76e1cabad9 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/includes/prop-desc.js +++ b/JSTests/test262/test/built-ins/Array/prototype/includes/prop-desc.js @@ -9,6 +9,7 @@ info: | and in Annex B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true } unless otherwise specified. includes: [propertyHelper.js] +features: [Array.prototype.includes] ---*/ verifyNotEnumerable(Array.prototype, "includes"); diff --git a/JSTests/test262/test/built-ins/Array/prototype/includes/return-abrupt-get-length.js b/JSTests/test262/test/built-ins/Array/prototype/includes/return-abrupt-get-length.js index 19ea655e2c72..ef05100af9c2 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/includes/return-abrupt-get-length.js +++ b/JSTests/test262/test/built-ins/Array/prototype/includes/return-abrupt-get-length.js @@ -10,6 +10,7 @@ info: | ... 2. Let len be ? ToLength(? Get(O, "length")). ... +features: [Array.prototype.includes] ---*/ var obj = {}; diff --git a/JSTests/test262/test/built-ins/Array/prototype/includes/return-abrupt-get-prop.js b/JSTests/test262/test/built-ins/Array/prototype/includes/return-abrupt-get-prop.js index 7f8e2b99da70..87480f1c94c3 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/includes/return-abrupt-get-prop.js +++ b/JSTests/test262/test/built-ins/Array/prototype/includes/return-abrupt-get-prop.js @@ -11,6 +11,7 @@ info: | 7. Repeat, while k < len a. Let elementK be the result of ? Get(O, ! ToString(k)). ... +features: [Array.prototype.includes] ---*/ var stopped = 0; diff --git a/JSTests/test262/test/built-ins/Array/prototype/includes/return-abrupt-tointeger-fromindex-symbol.js b/JSTests/test262/test/built-ins/Array/prototype/includes/return-abrupt-tointeger-fromindex-symbol.js index 9321f8ade52b..3e168d5391ab 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/includes/return-abrupt-tointeger-fromindex-symbol.js +++ b/JSTests/test262/test/built-ins/Array/prototype/includes/return-abrupt-tointeger-fromindex-symbol.js @@ -11,7 +11,7 @@ info: | 4. Let n be ? ToInteger(fromIndex). (If fromIndex is undefined, this step produces the value 0.) ... -features: [Symbol] +features: [Symbol, Array.prototype.includes] ---*/ var fromIndex = Symbol("1"); diff --git a/JSTests/test262/test/built-ins/Array/prototype/includes/return-abrupt-tointeger-fromindex.js b/JSTests/test262/test/built-ins/Array/prototype/includes/return-abrupt-tointeger-fromindex.js index 4ef4af359715..e79355f35e4b 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/includes/return-abrupt-tointeger-fromindex.js +++ b/JSTests/test262/test/built-ins/Array/prototype/includes/return-abrupt-tointeger-fromindex.js @@ -11,6 +11,7 @@ info: | 4. Let n be ? ToInteger(fromIndex). (If fromIndex is undefined, this step produces the value 0.) ... +features: [Array.prototype.includes] ---*/ var fromIndex = { diff --git a/JSTests/test262/test/built-ins/Array/prototype/includes/return-abrupt-tonumber-length-symbol.js b/JSTests/test262/test/built-ins/Array/prototype/includes/return-abrupt-tonumber-length-symbol.js index 2c412574069a..64c22ecc2a04 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/includes/return-abrupt-tonumber-length-symbol.js +++ b/JSTests/test262/test/built-ins/Array/prototype/includes/return-abrupt-tonumber-length-symbol.js @@ -10,7 +10,7 @@ info: | ... 2. Let len be ? ToLength(? Get(O, "length")). ... -features: [Symbol] +features: [Symbol, Array.prototype.includes] ---*/ var obj = { diff --git a/JSTests/test262/test/built-ins/Array/prototype/includes/return-abrupt-tonumber-length.js b/JSTests/test262/test/built-ins/Array/prototype/includes/return-abrupt-tonumber-length.js index dcd2d50b3529..f140713f6bb4 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/includes/return-abrupt-tonumber-length.js +++ b/JSTests/test262/test/built-ins/Array/prototype/includes/return-abrupt-tonumber-length.js @@ -10,6 +10,7 @@ info: | ... 2. Let len be ? ToLength(? Get(O, "length")). ... +features: [Array.prototype.includes] ---*/ var obj1 = { diff --git a/JSTests/test262/test/built-ins/Array/prototype/includes/samevaluezero.js b/JSTests/test262/test/built-ins/Array/prototype/includes/samevaluezero.js index 2481b651c0ed..557da5b7b1b8 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/includes/samevaluezero.js +++ b/JSTests/test262/test/built-ins/Array/prototype/includes/samevaluezero.js @@ -13,6 +13,7 @@ info: | b. If SameValueZero(searchElement, elementK) is true, return true. c. Increase k by 1. ... +features: [Array.prototype.includes] ---*/ var sample = [42, 0, 1, NaN]; diff --git a/JSTests/test262/test/built-ins/Array/prototype/includes/search-found-returns-true.js b/JSTests/test262/test/built-ins/Array/prototype/includes/search-found-returns-true.js index e23e92c46fec..8239b9076b5a 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/includes/search-found-returns-true.js +++ b/JSTests/test262/test/built-ins/Array/prototype/includes/search-found-returns-true.js @@ -18,7 +18,7 @@ info: | b. If SameValueZero(searchElement, elementK) is true, return true. c. Increase k by 1. ... -features: [Symbol] +features: [Symbol, Array.prototype.includes] ---*/ var symbol = Symbol("1"); diff --git a/JSTests/test262/test/built-ins/Array/prototype/includes/search-not-found-returns-false.js b/JSTests/test262/test/built-ins/Array/prototype/includes/search-not-found-returns-false.js index 7d98d2a68bc9..79c0ec0abe2a 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/includes/search-not-found-returns-false.js +++ b/JSTests/test262/test/built-ins/Array/prototype/includes/search-not-found-returns-false.js @@ -18,7 +18,7 @@ info: | b. If SameValueZero(searchElement, elementK) is true, return true. c. Increase k by 1. 8. Return false. -features: [Symbol] +features: [Symbol, Array.prototype.includes] ---*/ assert.sameValue([42].includes(43), false, "43"); diff --git a/JSTests/test262/test/built-ins/Array/prototype/includes/sparse.js b/JSTests/test262/test/built-ins/Array/prototype/includes/sparse.js index 751c2c928ed2..e50d8bcf1c1f 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/includes/sparse.js +++ b/JSTests/test262/test/built-ins/Array/prototype/includes/sparse.js @@ -18,6 +18,7 @@ info: | b. If SameValueZero(searchElement, elementK) is true, return true. c. Increase k by 1. ... +features: [Array.prototype.includes] ---*/ assert.sameValue( diff --git a/JSTests/test262/test/built-ins/Array/prototype/includes/this-is-not-object.js b/JSTests/test262/test/built-ins/Array/prototype/includes/this-is-not-object.js index 895e17c964fa..e073262d67d3 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/includes/this-is-not-object.js +++ b/JSTests/test262/test/built-ins/Array/prototype/includes/this-is-not-object.js @@ -9,6 +9,7 @@ info: | 1. Let O be ? ToObject(this value). ... +features: [Array.prototype.includes] ---*/ var includes = Array.prototype.includes; diff --git a/JSTests/test262/test/built-ins/Array/prototype/includes/tointeger-fromindex.js b/JSTests/test262/test/built-ins/Array/prototype/includes/tointeger-fromindex.js index d8d232296033..fb34d3280783 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/includes/tointeger-fromindex.js +++ b/JSTests/test262/test/built-ins/Array/prototype/includes/tointeger-fromindex.js @@ -18,6 +18,7 @@ info: | b. If SameValueZero(searchElement, elementK) is true, return true. c. Increase k by 1. 8. Return false. +features: [Array.prototype.includes] ---*/ var obj = { diff --git a/JSTests/test262/test/built-ins/Array/prototype/includes/tolength-length.js b/JSTests/test262/test/built-ins/Array/prototype/includes/tolength-length.js index c1e82b9da585..bbe9d4be51a2 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/includes/tolength-length.js +++ b/JSTests/test262/test/built-ins/Array/prototype/includes/tolength-length.js @@ -17,6 +17,7 @@ info: | 2. If len ≤ +0, return +0. 3. If len is +∞, return 253-1. 4. Return min(len, 253-1). +features: [Array.prototype.includes] ---*/ var obj = { diff --git a/JSTests/test262/test/built-ins/Array/prototype/includes/using-fromindex.js b/JSTests/test262/test/built-ins/Array/prototype/includes/using-fromindex.js index c6e3f1a6464e..472ab2ccc892 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/includes/using-fromindex.js +++ b/JSTests/test262/test/built-ins/Array/prototype/includes/using-fromindex.js @@ -18,6 +18,7 @@ info: | b. If SameValueZero(searchElement, elementK) is true, return true. c. Increase k by 1. ... +features: [Array.prototype.includes] ---*/ var sample = ["a", "b", "c"]; diff --git a/JSTests/test262/test/built-ins/Array/prototype/includes/values-are-not-cached.js b/JSTests/test262/test/built-ins/Array/prototype/includes/values-are-not-cached.js index a44f374f0cad..1f039ddb7d1d 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/includes/values-are-not-cached.js +++ b/JSTests/test262/test/built-ins/Array/prototype/includes/values-are-not-cached.js @@ -11,6 +11,7 @@ info: | 7. Repeat, while k < len a. Let elementK be the result of ? Get(O, ! ToString(k)). ... +features: [Array.prototype.includes] ---*/ function getCleanObj() { diff --git a/JSTests/test262/test/built-ins/Array/prototype/methods-called-as-functions.js b/JSTests/test262/test/built-ins/Array/prototype/methods-called-as-functions.js index 6d04e33905a9..2b4e4c854a59 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/methods-called-as-functions.js +++ b/JSTests/test262/test/built-ins/Array/prototype/methods-called-as-functions.js @@ -15,7 +15,7 @@ info: | Argument Type: Undefined Result: Throw a TypeError exception. -features: [Symbol, Symbol.isConcatSpreadable, Symbol.iterator, Symbol.species, Array.prototype.flat, Array.prototype.flatMap] +features: [Symbol, Symbol.isConcatSpreadable, Symbol.iterator, Symbol.species, Array.prototype.flat, Array.prototype.flatMap, Array.prototype.includes] ---*/ ["constructor", "length", "0", Symbol.isConcatSpreadable, Symbol.species].forEach(function(key) { diff --git a/JSTests/test262/test/built-ins/Array/prototype/pop/clamps-to-integer-limit.js b/JSTests/test262/test/built-ins/Array/prototype/pop/clamps-to-integer-limit.js index 0c5899a55eb4..2fd7e4321a44 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/pop/clamps-to-integer-limit.js +++ b/JSTests/test262/test/built-ins/Array/prototype/pop/clamps-to-integer-limit.js @@ -14,6 +14,7 @@ info: | ... e. Perform ? Set(O, "length", newLen, true). ... +features: [exponentiation] ---*/ var arrayLike = {}; diff --git a/JSTests/test262/test/built-ins/Array/prototype/pop/length-near-integer-limit.js b/JSTests/test262/test/built-ins/Array/prototype/pop/length-near-integer-limit.js index a480b9c6c87b..9d0c7a7e48c0 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/pop/length-near-integer-limit.js +++ b/JSTests/test262/test/built-ins/Array/prototype/pop/length-near-integer-limit.js @@ -15,7 +15,8 @@ info: | c. Let element be ? Get(O, index). d. Perform ? DeletePropertyOrThrow(O, index). e. Perform ? Set(O, "length", newLen, true). - f. Return element. + f. Return element. +features: [exponentiation] ---*/ var arrayLike = { diff --git a/JSTests/test262/test/built-ins/Array/prototype/push/clamps-to-integer-limit.js b/JSTests/test262/test/built-ins/Array/prototype/push/clamps-to-integer-limit.js index 9cfc323fc301..6a29bf2aa9d3 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/push/clamps-to-integer-limit.js +++ b/JSTests/test262/test/built-ins/Array/prototype/push/clamps-to-integer-limit.js @@ -14,6 +14,7 @@ info: | ... 7. Perform ? Set(O, "length", len, true). ... +features: [exponentiation] ---*/ var arrayLike = {}; diff --git a/JSTests/test262/test/built-ins/Array/prototype/push/length-near-integer-limit.js b/JSTests/test262/test/built-ins/Array/prototype/push/length-near-integer-limit.js index 4c94e29873a0..5b16f8706657 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/push/length-near-integer-limit.js +++ b/JSTests/test262/test/built-ins/Array/prototype/push/length-near-integer-limit.js @@ -15,6 +15,7 @@ info: | ... 7. Perform ? Set(O, "length", len, true). ... +features: [exponentiation] ---*/ var arrayLike = { diff --git a/JSTests/test262/test/built-ins/Array/prototype/push/throws-if-integer-limit-exceeded.js b/JSTests/test262/test/built-ins/Array/prototype/push/throws-if-integer-limit-exceeded.js index ae71cd417aec..76b64fcbe10f 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/push/throws-if-integer-limit-exceeded.js +++ b/JSTests/test262/test/built-ins/Array/prototype/push/throws-if-integer-limit-exceeded.js @@ -13,6 +13,7 @@ info: | 4. Let argCount be the number of elements in items. 5. If len + argCount > 2^53-1, throw a TypeError exception. ... +features: [exponentiation] ---*/ var arrayLike = {}; diff --git a/JSTests/test262/test/built-ins/Array/prototype/reverse/length-exceeding-integer-limit-with-object.js b/JSTests/test262/test/built-ins/Array/prototype/reverse/length-exceeding-integer-limit-with-object.js index dcfdb869b41c..1351e92883fc 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/reverse/length-exceeding-integer-limit-with-object.js +++ b/JSTests/test262/test/built-ins/Array/prototype/reverse/length-exceeding-integer-limit-with-object.js @@ -9,6 +9,7 @@ info: | ... 2. Let len be ? ToLength(? Get(O, "length")). ... +features: [exponentiation] ---*/ function StopReverse() {} diff --git a/JSTests/test262/test/built-ins/Array/prototype/reverse/length-exceeding-integer-limit-with-proxy.js b/JSTests/test262/test/built-ins/Array/prototype/reverse/length-exceeding-integer-limit-with-proxy.js index f827f9f162c4..e16b61fa57d0 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/reverse/length-exceeding-integer-limit-with-proxy.js +++ b/JSTests/test262/test/built-ins/Array/prototype/reverse/length-exceeding-integer-limit-with-proxy.js @@ -6,6 +6,7 @@ esid: sec-array.prototype.reverse description: > Ensure correct MOP operations are called when length exceeds 2^53-1. includes: [compareArray.js, proxyTrapsHelper.js] +features: [exponentiation] ---*/ function StopReverse() {} diff --git a/JSTests/test262/test/built-ins/Array/prototype/slice/length-exceeding-integer-limit-proxied-array.js b/JSTests/test262/test/built-ins/Array/prototype/slice/length-exceeding-integer-limit-proxied-array.js index 79ca743e08e3..ed771464b4bf 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/slice/length-exceeding-integer-limit-proxied-array.js +++ b/JSTests/test262/test/built-ins/Array/prototype/slice/length-exceeding-integer-limit-proxied-array.js @@ -17,6 +17,7 @@ info: | else let final be min(relativeEnd, len). ... includes: [compareArray.js] +features: [exponentiation] ---*/ var array = []; diff --git a/JSTests/test262/test/built-ins/Array/prototype/slice/length-exceeding-integer-limit.js b/JSTests/test262/test/built-ins/Array/prototype/slice/length-exceeding-integer-limit.js index 7adf639c7b01..619c0b95a75b 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/slice/length-exceeding-integer-limit.js +++ b/JSTests/test262/test/built-ins/Array/prototype/slice/length-exceeding-integer-limit.js @@ -16,6 +16,7 @@ info: | else let final be min(relativeEnd, len). ... includes: [compareArray.js] +features: [exponentiation] ---*/ var arrayLike = { diff --git a/JSTests/test262/test/built-ins/Array/prototype/splice/clamps-length-to-integer-limit.js b/JSTests/test262/test/built-ins/Array/prototype/splice/clamps-length-to-integer-limit.js index 24584ba48a78..b72cc3e51e73 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/splice/clamps-length-to-integer-limit.js +++ b/JSTests/test262/test/built-ins/Array/prototype/splice/clamps-length-to-integer-limit.js @@ -15,6 +15,7 @@ info: | ... 19. Perform ? Set(O, "length", len - actualDeleteCount + itemCount, true). ... +features: [exponentiation] ---*/ var arrayLike = {}; diff --git a/JSTests/test262/test/built-ins/Array/prototype/splice/create-species-length-exceeding-integer-limit.js b/JSTests/test262/test/built-ins/Array/prototype/splice/create-species-length-exceeding-integer-limit.js index 2efecc76b72c..6b829ec646ce 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/splice/create-species-length-exceeding-integer-limit.js +++ b/JSTests/test262/test/built-ins/Array/prototype/splice/create-species-length-exceeding-integer-limit.js @@ -20,7 +20,7 @@ info: | 12. Perform ? Set(A, "length", actualDeleteCount, true). ... includes: [compareArray.js, proxyTrapsHelper.js] -features: [Symbol.species] +features: [Symbol.species, exponentiation] ---*/ function StopSplice() {} diff --git a/JSTests/test262/test/built-ins/Array/prototype/splice/length-and-deleteCount-exceeding-integer-limit.js b/JSTests/test262/test/built-ins/Array/prototype/splice/length-and-deleteCount-exceeding-integer-limit.js index 3c6867123794..ebe9aea397dd 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/splice/length-and-deleteCount-exceeding-integer-limit.js +++ b/JSTests/test262/test/built-ins/Array/prototype/splice/length-and-deleteCount-exceeding-integer-limit.js @@ -23,6 +23,7 @@ info: | d. Increment k by 1. ... includes: [compareArray.js] +features: [exponentiation] ---*/ var arrayLike = { diff --git a/JSTests/test262/test/built-ins/Array/prototype/splice/length-exceeding-integer-limit-shrink-array.js b/JSTests/test262/test/built-ins/Array/prototype/splice/length-exceeding-integer-limit-shrink-array.js index 46a59a25f2a7..436123d9609b 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/splice/length-exceeding-integer-limit-shrink-array.js +++ b/JSTests/test262/test/built-ins/Array/prototype/splice/length-exceeding-integer-limit-shrink-array.js @@ -25,6 +25,7 @@ info: | ii. Decrease k by 1. ... includes: [compareArray.js] +features: [exponentiation] ---*/ var arrayLike = { diff --git a/JSTests/test262/test/built-ins/Array/prototype/splice/length-near-integer-limit-grow-array.js b/JSTests/test262/test/built-ins/Array/prototype/splice/length-near-integer-limit-grow-array.js index a36b385a61bd..ac3c0c975b61 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/splice/length-near-integer-limit-grow-array.js +++ b/JSTests/test262/test/built-ins/Array/prototype/splice/length-near-integer-limit-grow-array.js @@ -21,6 +21,7 @@ info: | vi. Decrease k by 1. ... includes: [compareArray.js] +features: [exponentiation] ---*/ var arrayLike = { diff --git a/JSTests/test262/test/built-ins/Array/prototype/splice/throws-if-integer-limit-exceeded.js b/JSTests/test262/test/built-ins/Array/prototype/splice/throws-if-integer-limit-exceeded.js index 447eb4d0a5b2..e2b1e921d548 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/splice/throws-if-integer-limit-exceeded.js +++ b/JSTests/test262/test/built-ins/Array/prototype/splice/throws-if-integer-limit-exceeded.js @@ -15,6 +15,7 @@ info: | c. Let actualDeleteCount be min(max(dc, 0), len - actualStart). 8. If len+insertCount-actualDeleteCount > 2^53-1, throw a TypeError exception. ... +features: [exponentiation] ---*/ var arrayLike = {}; diff --git a/JSTests/test262/test/built-ins/Array/prototype/toReversed/length-exceeding-array-length-limit.js b/JSTests/test262/test/built-ins/Array/prototype/toReversed/length-exceeding-array-length-limit.js index e3a212a078f8..3aa3bdb28024 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/toReversed/length-exceeding-array-length-limit.js +++ b/JSTests/test262/test/built-ins/Array/prototype/toReversed/length-exceeding-array-length-limit.js @@ -16,7 +16,7 @@ info: | ArrayCreate ( length [, proto ] ) 1. If length > 2 ** 32 - 1, throw a RangeError exception. -features: [change-array-by-copy] +features: [change-array-by-copy, exponentiation] ---*/ // Object with large "length" property diff --git a/JSTests/test262/test/built-ins/Array/prototype/toSorted/length-exceeding-array-length-limit.js b/JSTests/test262/test/built-ins/Array/prototype/toSorted/length-exceeding-array-length-limit.js index 72ae5353a54e..535ace463b94 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/toSorted/length-exceeding-array-length-limit.js +++ b/JSTests/test262/test/built-ins/Array/prototype/toSorted/length-exceeding-array-length-limit.js @@ -17,7 +17,7 @@ info: | ArrayCreate ( length [, proto ] ) 1. If length > 2 ** 32 - 1, throw a RangeError exception. -features: [change-array-by-copy] +features: [change-array-by-copy, exponentiation] ---*/ // Object with large "length" property diff --git a/JSTests/test262/test/built-ins/Array/prototype/toSpliced/length-clamped-to-2pow53minus1.js b/JSTests/test262/test/built-ins/Array/prototype/toSpliced/length-clamped-to-2pow53minus1.js index 5938e729be15..a3bad9f9690c 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/toSpliced/length-clamped-to-2pow53minus1.js +++ b/JSTests/test262/test/built-ins/Array/prototype/toSpliced/length-clamped-to-2pow53minus1.js @@ -15,7 +15,7 @@ info: | 1. Let len be ? ToIntegerOrInfinity(argument). 2. If len ≤ 0, return +0𝔽. 3. Return 𝔽(min(len, 2^53 - 1)) -features: [change-array-by-copy] +features: [change-array-by-copy, exponentiation] includes: [compareArray.js] ---*/ diff --git a/JSTests/test262/test/built-ins/Array/prototype/toSpliced/length-exceeding-array-length-limit.js b/JSTests/test262/test/built-ins/Array/prototype/toSpliced/length-exceeding-array-length-limit.js index ddd2a4dce25c..65b1bb122f2a 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/toSpliced/length-exceeding-array-length-limit.js +++ b/JSTests/test262/test/built-ins/Array/prototype/toSpliced/length-exceeding-array-length-limit.js @@ -19,7 +19,7 @@ info: | ArrayCreate ( length [, proto ] ) 1. If length > 2 ** 32 - 1, throw a RangeError exception. -features: [change-array-by-copy] +features: [change-array-by-copy, exponentiation] ---*/ // Object with large "length" property diff --git a/JSTests/test262/test/built-ins/Array/prototype/unshift/clamps-to-integer-limit.js b/JSTests/test262/test/built-ins/Array/prototype/unshift/clamps-to-integer-limit.js index 9f2e14184594..1c19a96eae6e 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/unshift/clamps-to-integer-limit.js +++ b/JSTests/test262/test/built-ins/Array/prototype/unshift/clamps-to-integer-limit.js @@ -11,6 +11,7 @@ info: | 3. Let argCount be the number of actual arguments. 4. If argCount > 0, then ... 5. Perform ? Set(O, "length", len+argCount, true). +features: [exponentiation] ---*/ var arrayLike = {}; diff --git a/JSTests/test262/test/built-ins/Array/prototype/unshift/length-near-integer-limit.js b/JSTests/test262/test/built-ins/Array/prototype/unshift/length-near-integer-limit.js index 5dff513e4062..f4ff8320a08f 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/unshift/length-near-integer-limit.js +++ b/JSTests/test262/test/built-ins/Array/prototype/unshift/length-near-integer-limit.js @@ -21,6 +21,7 @@ info: | v. Else fromPresent is false, 1. Perform ? DeletePropertyOrThrow(O, to). vi. Decrease k by 1. +features: [exponentiation] ---*/ function StopUnshift() {} diff --git a/JSTests/test262/test/built-ins/Array/prototype/unshift/throws-if-integer-limit-exceeded.js b/JSTests/test262/test/built-ins/Array/prototype/unshift/throws-if-integer-limit-exceeded.js index 9ad723eca5bd..14c2a6bc495b 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/unshift/throws-if-integer-limit-exceeded.js +++ b/JSTests/test262/test/built-ins/Array/prototype/unshift/throws-if-integer-limit-exceeded.js @@ -12,6 +12,7 @@ info: | 4. If argCount > 0, then a. If len+argCount > 2^53-1, throw a TypeError exception. b. ... +features: [exponentiation] ---*/ var arrayLike = {}; diff --git a/JSTests/test262/test/built-ins/Array/prototype/with/index-bigger-or-eq-than-length.js b/JSTests/test262/test/built-ins/Array/prototype/with/index-bigger-or-eq-than-length.js index 932f0861b6b6..5b05d12b205e 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/with/index-bigger-or-eq-than-length.js +++ b/JSTests/test262/test/built-ins/Array/prototype/with/index-bigger-or-eq-than-length.js @@ -15,7 +15,7 @@ info: | 5. Else, let actualIndex be len + relativeIndex. 6. If actualIndex >= len or actualIndex < 0, throw a *RangeError* exception. ... -features: [change-array-by-copy] +features: [change-array-by-copy, exponentiation] ---*/ assert.throws(RangeError, function() { diff --git a/JSTests/test262/test/built-ins/Array/prototype/with/index-smaller-than-minus-length.js b/JSTests/test262/test/built-ins/Array/prototype/with/index-smaller-than-minus-length.js index 644718f66b11..a24a36fa0e3a 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/with/index-smaller-than-minus-length.js +++ b/JSTests/test262/test/built-ins/Array/prototype/with/index-smaller-than-minus-length.js @@ -15,7 +15,7 @@ info: | 5. Else, let actualIndex be len + relativeIndex. 6. If actualIndex >= len or actualIndex < 0, throw a *RangeError* exception. ... -features: [change-array-by-copy] +features: [change-array-by-copy, exponentiation] ---*/ [0, 1, 2].with(-3, 7); diff --git a/JSTests/test262/test/built-ins/Array/prototype/with/length-exceeding-array-length-limit.js b/JSTests/test262/test/built-ins/Array/prototype/with/length-exceeding-array-length-limit.js index f6f2d7de4934..8e348cdd3594 100644 --- a/JSTests/test262/test/built-ins/Array/prototype/with/length-exceeding-array-length-limit.js +++ b/JSTests/test262/test/built-ins/Array/prototype/with/length-exceeding-array-length-limit.js @@ -17,7 +17,7 @@ info: | ArrayCreate ( length [, proto ] ) 1. If length > 2 ** 32 - 1, throw a RangeError exception. -features: [change-array-by-copy] +features: [change-array-by-copy, exponentiation] ---*/ // Object with large "length" property diff --git a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/detached/this-is-sharedarraybuffer-resizable.js b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/detached/this-is-sharedarraybuffer-resizable.js index a332fb36fc0c..995a92cc324b 100644 --- a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/detached/this-is-sharedarraybuffer-resizable.js +++ b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/detached/this-is-sharedarraybuffer-resizable.js @@ -10,7 +10,7 @@ info: | 2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]). 3. If IsSharedArrayBuffer(O) is true, throw a TypeError exception. [...] -features: [SharedArrayBuffer, resizable-arraybuffer, ArrayBuffer, arraybuffer-transfer] +features: [SharedArrayBuffer, ArrayBuffer, arraybuffer-transfer] ---*/ var detached = Object.getOwnPropertyDescriptor( diff --git a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/descriptor.js b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/descriptor.js index 0d0f301815b2..8ffd0e814ff5 100644 --- a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/descriptor.js +++ b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/descriptor.js @@ -12,7 +12,7 @@ info: | Annex B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true } unless otherwise specified. includes: [propertyHelper.js] -features: [resizable-arraybuffer, arraybuffer-transfer] +features: [arraybuffer-transfer] ---*/ verifyProperty(ArrayBuffer.prototype, 'transfer', { diff --git a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/extensible.js b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/extensible.js index f47fe252ef58..8db928ccb839 100644 --- a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/extensible.js +++ b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/extensible.js @@ -9,7 +9,7 @@ info: | 17 ECMAScript Standard Built-in Objects: Unless specified otherwise, the [[Extensible]] internal slot of a built-in object initially has the value true. -features: [resizable-arraybuffer, arraybuffer-transfer] +features: [arraybuffer-transfer] ---*/ assert(Object.isExtensible(ArrayBuffer.prototype.transfer)); diff --git a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/from-fixed-to-larger-no-resizable.js b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/from-fixed-to-larger-no-resizable.js new file mode 100644 index 000000000000..926e60d18886 --- /dev/null +++ b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/from-fixed-to-larger-no-resizable.js @@ -0,0 +1,57 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-arraybuffer.prototype.transfer +description: Transfering from a fixed-size ArrayBuffer into a larger ArrayBuffer +info: | + ArrayBuffer.prototype.transfer ( [ newLength ] ) + + 1. Let O be the this value. + 2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]). + 3. If IsSharedArrayBuffer(O) is true, throw a TypeError exception. + 4. If IsDetachedBuffer(O) is true, throw a TypeError exception. + 5. If newLength is undefined, let newByteLength be + O.[[ArrayBufferByteLength]]. + 6. Else, let newByteLength be ? ToIntegerOrInfinity(newLength). + 7. Let new be ? Construct(%ArrayBuffer%, « 𝔽(newByteLength) »). + 8. NOTE: This method returns a fixed-length ArrayBuffer. + 9. Let copyLength be min(newByteLength, O.[[ArrayBufferByteLength]]). + 10. Let fromBlock be O.[[ArrayBufferData]]. + 11. Let toBlock be new.[[ArrayBufferData]]. + 12. Perform CopyDataBlockBytes(toBlock, 0, fromBlock, 0, copyLength). + 13. NOTE: Neither creation of the new Data Block nor copying from the old + Data Block are observable. Implementations reserve the right to implement + this method as a zero-copy move or a realloc. + 14. Perform ! DetachArrayBuffer(O). + 15. Return new. +features: [arraybuffer-transfer] +---*/ + +// NOTE: This file is a copy of "from-fixed-to-larger.js" with the resizable +// ArrayBuffer parts removed, so it can run in implementations which don't yet +// support the "resizable-arraybuffer" feature. + +var source = new ArrayBuffer(4); + +var sourceArray = new Uint8Array(source); +sourceArray[0] = 1; +sourceArray[1] = 2; +sourceArray[2] = 3; +sourceArray[3] = 4; + +var dest = source.transfer(5); + +assert.sameValue(source.byteLength, 0, 'source.byteLength'); +assert.throws(TypeError, function() { + source.slice(); +}); + +assert.sameValue(dest.byteLength, 5, 'dest.byteLength'); + +var destArray = new Uint8Array(dest); + +assert.sameValue(destArray[0], 1, 'destArray[0]'); +assert.sameValue(destArray[1], 2, 'destArray[1]'); +assert.sameValue(destArray[2], 3, 'destArray[2]'); +assert.sameValue(destArray[3], 4, 'destArray[3]'); +assert.sameValue(destArray[4], 0, 'destArray[4]'); diff --git a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/from-fixed-to-same-no-resizable.js b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/from-fixed-to-same-no-resizable.js new file mode 100644 index 000000000000..052078a64799 --- /dev/null +++ b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/from-fixed-to-same-no-resizable.js @@ -0,0 +1,58 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-arraybuffer.prototype.transfer +description: | + Transfering from a fixed-size ArrayBuffer into an ArrayBuffer with the same + byte length +info: | + ArrayBuffer.prototype.transfer ( [ newLength ] ) + + 1. Let O be the this value. + 2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]). + 3. If IsSharedArrayBuffer(O) is true, throw a TypeError exception. + 4. If IsDetachedBuffer(O) is true, throw a TypeError exception. + 5. If newLength is undefined, let newByteLength be + O.[[ArrayBufferByteLength]]. + 6. Else, let newByteLength be ? ToIntegerOrInfinity(newLength). + 7. Let new be ? Construct(%ArrayBuffer%, « 𝔽(newByteLength) »). + 8. NOTE: This method returns a fixed-length ArrayBuffer. + 9. Let copyLength be min(newByteLength, O.[[ArrayBufferByteLength]]). + 10. Let fromBlock be O.[[ArrayBufferData]]. + 11. Let toBlock be new.[[ArrayBufferData]]. + 12. Perform CopyDataBlockBytes(toBlock, 0, fromBlock, 0, copyLength). + 13. NOTE: Neither creation of the new Data Block nor copying from the old + Data Block are observable. Implementations reserve the right to implement + this method as a zero-copy move or a realloc. + 14. Perform ! DetachArrayBuffer(O). + 15. Return new. +features: [arraybuffer-transfer] +---*/ + +// NOTE: This file is a copy of "from-fixed-to-same.js" with the resizable +// ArrayBuffer parts removed, so it can run in implementations which don't yet +// support the "resizable-arraybuffer" feature. + +var source = new ArrayBuffer(4); + +var sourceArray = new Uint8Array(source); +sourceArray[0] = 1; +sourceArray[1] = 2; +sourceArray[2] = 3; +sourceArray[3] = 4; + +var dest = source.transfer(); + +assert.sameValue(source.byteLength, 0, 'source.byteLength'); +assert.throws(TypeError, function() { + source.slice(); +}); + +assert.sameValue(dest.byteLength, 4, 'dest.byteLength'); + +var destArray = new Uint8Array(dest); + +assert.sameValue(destArray[0], 1, 'destArray[0]'); +assert.sameValue(destArray[1], 2, 'destArray[1]'); +assert.sameValue(destArray[2], 3, 'destArray[2]'); +assert.sameValue(destArray[3], 4, 'destArray[3]'); diff --git a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/from-fixed-to-smaller-no-resizable.js b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/from-fixed-to-smaller-no-resizable.js new file mode 100644 index 000000000000..507692c4b7f8 --- /dev/null +++ b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/from-fixed-to-smaller-no-resizable.js @@ -0,0 +1,55 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-arraybuffer.prototype.transfer +description: Transfering from a fixed-size ArrayBuffer into a smaller ArrayBuffer +info: | + ArrayBuffer.prototype.transfer ( [ newLength ] ) + + 1. Let O be the this value. + 2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]). + 3. If IsSharedArrayBuffer(O) is true, throw a TypeError exception. + 4. If IsDetachedBuffer(O) is true, throw a TypeError exception. + 5. If newLength is undefined, let newByteLength be + O.[[ArrayBufferByteLength]]. + 6. Else, let newByteLength be ? ToIntegerOrInfinity(newLength). + 7. Let new be ? Construct(%ArrayBuffer%, « 𝔽(newByteLength) »). + 8. NOTE: This method returns a fixed-length ArrayBuffer. + 9. Let copyLength be min(newByteLength, O.[[ArrayBufferByteLength]]). + 10. Let fromBlock be O.[[ArrayBufferData]]. + 11. Let toBlock be new.[[ArrayBufferData]]. + 12. Perform CopyDataBlockBytes(toBlock, 0, fromBlock, 0, copyLength). + 13. NOTE: Neither creation of the new Data Block nor copying from the old + Data Block are observable. Implementations reserve the right to implement + this method as a zero-copy move or a realloc. + 14. Perform ! DetachArrayBuffer(O). + 15. Return new. +features: [arraybuffer-transfer] +---*/ + +// NOTE: This file is a copy of "from-fixed-to-smaller.js" with the resizable +// ArrayBuffer parts removed, so it can run in implementations which don't yet +// support the "resizable-arraybuffer" feature. + +var source = new ArrayBuffer(4); + +var sourceArray = new Uint8Array(source); +sourceArray[0] = 1; +sourceArray[1] = 2; +sourceArray[2] = 3; +sourceArray[3] = 4; + +var dest = source.transfer(3); + +assert.sameValue(source.byteLength, 0, 'source.byteLength'); +assert.throws(TypeError, function() { + source.slice(); +}); + +assert.sameValue(dest.byteLength, 3, 'dest.byteLength'); + +var destArray = new Uint8Array(dest); + +assert.sameValue(destArray[0], 1, 'destArray[0]'); +assert.sameValue(destArray[1], 2, 'destArray[1]'); +assert.sameValue(destArray[2], 3, 'destArray[2]'); diff --git a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/from-fixed-to-zero-no-resizable.js b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/from-fixed-to-zero-no-resizable.js new file mode 100644 index 000000000000..ba8ed4553724 --- /dev/null +++ b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/from-fixed-to-zero-no-resizable.js @@ -0,0 +1,49 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-arraybuffer.prototype.transfer +description: Transfering from a fixed-size ArrayBuffer into a zero-length ArrayBuffer +info: | + ArrayBuffer.prototype.transfer ( [ newLength ] ) + + 1. Let O be the this value. + 2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]). + 3. If IsSharedArrayBuffer(O) is true, throw a TypeError exception. + 4. If IsDetachedBuffer(O) is true, throw a TypeError exception. + 5. If newLength is undefined, let newByteLength be + O.[[ArrayBufferByteLength]]. + 6. Else, let newByteLength be ? ToIntegerOrInfinity(newLength). + 7. Let new be ? Construct(%ArrayBuffer%, « 𝔽(newByteLength) »). + 8. NOTE: This method returns a fixed-length ArrayBuffer. + 9. Let copyLength be min(newByteLength, O.[[ArrayBufferByteLength]]). + 10. Let fromBlock be O.[[ArrayBufferData]]. + 11. Let toBlock be new.[[ArrayBufferData]]. + 12. Perform CopyDataBlockBytes(toBlock, 0, fromBlock, 0, copyLength). + 13. NOTE: Neither creation of the new Data Block nor copying from the old + Data Block are observable. Implementations reserve the right to implement + this method as a zero-copy move or a realloc. + 14. Perform ! DetachArrayBuffer(O). + 15. Return new. +features: [arraybuffer-transfer] +---*/ + +// NOTE: This file is a copy of "from-fixed-to-zero.js" with the resizable +// ArrayBuffer parts removed, so it can run in implementations which don't yet +// support the "resizable-arraybuffer" feature. + +var source = new ArrayBuffer(4); + +var sourceArray = new Uint8Array(source); +sourceArray[0] = 1; +sourceArray[1] = 2; +sourceArray[2] = 3; +sourceArray[3] = 4; + +var dest = source.transfer(0); + +assert.sameValue(source.byteLength, 0, 'source.byteLength'); +assert.throws(TypeError, function() { + source.slice(); +}); + +assert.sameValue(dest.byteLength, 0, 'dest.byteLength'); diff --git a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/length.js b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/length.js index febb6bc8da04..bdb7ab526bdc 100644 --- a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/length.js +++ b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/length.js @@ -19,7 +19,7 @@ info: | object has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. includes: [propertyHelper.js] -features: [resizable-arraybuffer, arraybuffer-transfer] +features: [arraybuffer-transfer] ---*/ verifyProperty(ArrayBuffer.prototype.transfer, 'length', { diff --git a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/name.js b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/name.js index eef01e890a85..2888f3be22cd 100644 --- a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/name.js +++ b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/name.js @@ -15,7 +15,7 @@ info: | Unless otherwise specified, the name property of a built-in Function object, if it exists, has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. -features: [resizable-arraybuffer, arraybuffer-transfer] +features: [arraybuffer-transfer] includes: [propertyHelper.js] ---*/ diff --git a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/new-length-excessive.js b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/new-length-excessive.js index 6c0aa32896c8..6ce117f8bd1f 100644 --- a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/new-length-excessive.js +++ b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/new-length-excessive.js @@ -3,21 +3,9 @@ /*--- esid: sec-arraybuffer.prototype.transfer description: > - Throws a RangeError the newLength value is too large to create a new - ArrayBuffer. -info: | - ArrayBuffer.prototype.transfer ( [ newLength ] ) - - 1. Let O be the this value. - 2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]). - 3. If IsSharedArrayBuffer(O) is true, throw a TypeError exception. - 4. If IsDetachedBuffer(O) is true, throw a TypeError exception. - 5. If newLength is undefined, let newByteLength be - O.[[ArrayBufferByteLength]]. - 6. Else, let newByteLength be ? ToIntegerOrInfinity(newLength). - 7. Let new be ? Construct(%ArrayBuffer%, « 𝔽(newByteLength) »). - [...] -features: [resizable-arraybuffer, arraybuffer-transfer] + Throws a RangeError if the newLength is larger than 2^53 - 1 due to clamping + in ToIndex. +features: [arraybuffer-transfer] ---*/ var ab = new ArrayBuffer(0); diff --git a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/new-length-non-number.js b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/new-length-non-number.js index 14f345d1e526..a6d5753d4f3e 100644 --- a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/new-length-non-number.js +++ b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/new-length-non-number.js @@ -14,7 +14,7 @@ info: | O.[[ArrayBufferByteLength]]. 6. Else, let newByteLength be ? ToIntegerOrInfinity(newLength). [...] -features: [resizable-arraybuffer, arraybuffer-transfer] +features: [arraybuffer-transfer] ---*/ var log = []; diff --git a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/nonconstructor.js b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/nonconstructor.js index b9632c6086f9..b50f061ab561 100644 --- a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/nonconstructor.js +++ b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/nonconstructor.js @@ -11,7 +11,7 @@ info: | Built-in function objects that are not identified as constructors do not implement the [[Construct]] internal method unless otherwise specified in the description of a particular function. -features: [resizable-arraybuffer, arraybuffer-transfer] +features: [arraybuffer-transfer] ---*/ assert.sameValue( diff --git a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/this-is-detached.js b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/this-is-detached.js index 2f107cf6fa1f..db79d1b85ed7 100644 --- a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/this-is-detached.js +++ b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/this-is-detached.js @@ -13,7 +13,7 @@ info: | 4. If IsDetachedBuffer(O) is true, throw a TypeError exception. [...] includes: [detachArrayBuffer.js] -features: [resizable-arraybuffer, arraybuffer-transfer] +features: [arraybuffer-transfer] ---*/ assert.sameValue(typeof ArrayBuffer.prototype.transfer, 'function'); diff --git a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/this-is-not-arraybuffer-object.js b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/this-is-not-arraybuffer-object.js index fa7b672c387c..27a58d7e9e51 100644 --- a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/this-is-not-arraybuffer-object.js +++ b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/this-is-not-arraybuffer-object.js @@ -10,7 +10,7 @@ info: | 1. Let O be the this value. 2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]). [...] -features: [resizable-arraybuffer, arraybuffer-transfer] +features: [arraybuffer-transfer] ---*/ assert.sameValue(typeof ArrayBuffer.prototype.transfer, 'function'); diff --git a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/this-is-not-object.js b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/this-is-not-object.js index cc5401f3f79c..b2c9f18cab1a 100644 --- a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/this-is-not-object.js +++ b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/this-is-not-object.js @@ -9,7 +9,7 @@ info: | 1. Let O be the this value. 2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]). [...] -features: [resizable-arraybuffer, Symbol, BigInt] +features: [arraybuffer-transfer, Symbol, BigInt] ---*/ assert.sameValue(typeof ArrayBuffer.prototype.transfer, "function"); diff --git a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/this-is-sharedarraybuffer.js b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/this-is-sharedarraybuffer.js index 81e1b144406b..19c81888a5ac 100644 --- a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/this-is-sharedarraybuffer.js +++ b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transfer/this-is-sharedarraybuffer.js @@ -10,7 +10,7 @@ info: | 2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]). 3. If IsSharedArrayBuffer(O) is true, throw a TypeError exception. [...] -features: [SharedArrayBuffer, resizable-arraybuffer] +features: [SharedArrayBuffer, arraybuffer-transfer] ---*/ var sab = new SharedArrayBuffer(0); diff --git a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/descriptor.js b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/descriptor.js new file mode 100644 index 000000000000..65583ba41f0b --- /dev/null +++ b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/descriptor.js @@ -0,0 +1,23 @@ +// Copyright (C) 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-arraybuffer.prototype.transfertofixedlength +description: > + ArrayBuffer.prototype.transferToFixedLength has default data property + attributes. +info: | + ArrayBuffer.prototype.transferToFixedLength ( [ newLength ] ) + + 17 ECMAScript Standard Built-in Objects: + Every other data property described in clauses 18 through 26 and in + Annex B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +includes: [propertyHelper.js] +features: [arraybuffer-transfer] +---*/ + +verifyProperty(ArrayBuffer.prototype, 'transferToFixedLength', { + enumerable: false, + writable: true, + configurable: true +}); diff --git a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/extensible.js b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/extensible.js new file mode 100644 index 000000000000..e11d763ed82a --- /dev/null +++ b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/extensible.js @@ -0,0 +1,15 @@ +// Copyright (C) 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-arraybuffer.prototype.transfertofixedlength +description: ArrayBuffer.prototype.transferToFixedLength is extensible. +info: | + ArrayBuffer.prototype.transferToFixedLength ( [ newLength ] ) + + 17 ECMAScript Standard Built-in Objects: + Unless specified otherwise, the [[Extensible]] internal slot + of a built-in object initially has the value true. +features: [arraybuffer-transfer] +---*/ + +assert(Object.isExtensible(ArrayBuffer.prototype.transferToFixedLength)); diff --git a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-larger-no-resizable.js b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-larger-no-resizable.js new file mode 100644 index 000000000000..67af2088ac37 --- /dev/null +++ b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-larger-no-resizable.js @@ -0,0 +1,36 @@ +// Copyright (C) 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-arraybuffer.prototype.transfertofixedlength +description: Transfering from a fixed-size ArrayBuffer into a larger ArrayBuffer +features: [arraybuffer-transfer] +---*/ + +// NOTE: This file is a copy of "from-fixed-to-larger.js" with the resizable +// ArrayBuffer parts removed, so it can run in implementations which don't yet +// support the "resizable-arraybuffer" feature. + +var source = new ArrayBuffer(4); + +var sourceArray = new Uint8Array(source); +sourceArray[0] = 1; +sourceArray[1] = 2; +sourceArray[2] = 3; +sourceArray[3] = 4; + +var dest = source.transferToFixedLength(5); + +assert.sameValue(source.byteLength, 0, 'source.byteLength'); +assert.throws(TypeError, function() { + source.slice(); +}); + +assert.sameValue(dest.byteLength, 5, 'dest.byteLength'); + +var destArray = new Uint8Array(dest); + +assert.sameValue(destArray[0], 1, 'destArray[0]'); +assert.sameValue(destArray[1], 2, 'destArray[1]'); +assert.sameValue(destArray[2], 3, 'destArray[2]'); +assert.sameValue(destArray[3], 4, 'destArray[3]'); +assert.sameValue(destArray[4], 0, 'destArray[4]'); diff --git a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-larger.js b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-larger.js new file mode 100644 index 000000000000..ceee25fe1142 --- /dev/null +++ b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-larger.js @@ -0,0 +1,34 @@ +// Copyright (C) 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-arraybuffer.prototype.transfertofixedlength +description: Transfering from a fixed-size ArrayBuffer into a larger ArrayBuffer +features: [resizable-arraybuffer, arraybuffer-transfer] +---*/ + +var source = new ArrayBuffer(4); + +var sourceArray = new Uint8Array(source); +sourceArray[0] = 1; +sourceArray[1] = 2; +sourceArray[2] = 3; +sourceArray[3] = 4; + +var dest = source.transferToFixedLength(5); + +assert.sameValue(source.byteLength, 0, 'source.byteLength'); +assert.throws(TypeError, function() { + source.slice(); +}); + +assert.sameValue(dest.resizable, false, 'dest.resizable'); +assert.sameValue(dest.byteLength, 5, 'dest.byteLength'); +assert.sameValue(dest.maxByteLength, 5, 'dest.maxByteLength'); + +var destArray = new Uint8Array(dest); + +assert.sameValue(destArray[0], 1, 'destArray[0]'); +assert.sameValue(destArray[1], 2, 'destArray[1]'); +assert.sameValue(destArray[2], 3, 'destArray[2]'); +assert.sameValue(destArray[3], 4, 'destArray[3]'); +assert.sameValue(destArray[4], 0, 'destArray[4]'); diff --git a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-same-no-resizable.js b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-same-no-resizable.js new file mode 100644 index 000000000000..0fb79b4f64c6 --- /dev/null +++ b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-same-no-resizable.js @@ -0,0 +1,37 @@ +// Copyright (C) 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-arraybuffer.prototype.transfertofixedlength +description: | + Transfering from a fixed-size ArrayBuffer into an ArrayBuffer with the same + byte length +features: [arraybuffer-transfer] +---*/ + +// NOTE: This file is a copy of "from-fixed-to-same.js" with the resizable +// ArrayBuffer parts removed, so it can run in implementations which don't yet +// support the "resizable-arraybuffer" feature. + +var source = new ArrayBuffer(4); + +var sourceArray = new Uint8Array(source); +sourceArray[0] = 1; +sourceArray[1] = 2; +sourceArray[2] = 3; +sourceArray[3] = 4; + +var dest = source.transferToFixedLength(); + +assert.sameValue(source.byteLength, 0, 'source.byteLength'); +assert.throws(TypeError, function() { + source.slice(); +}); + +assert.sameValue(dest.byteLength, 4, 'dest.byteLength'); + +var destArray = new Uint8Array(dest); + +assert.sameValue(destArray[0], 1, 'destArray[0]'); +assert.sameValue(destArray[1], 2, 'destArray[1]'); +assert.sameValue(destArray[2], 3, 'destArray[2]'); +assert.sameValue(destArray[3], 4, 'destArray[3]'); diff --git a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-same.js b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-same.js new file mode 100644 index 000000000000..f1dae842b353 --- /dev/null +++ b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-same.js @@ -0,0 +1,35 @@ +// Copyright (C) 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-arraybuffer.prototype.transfertofixedlength +description: | + Transfering from a fixed-size ArrayBuffer into an ArrayBuffer with the same + byte length +features: [resizable-arraybuffer, arraybuffer-transfer] +---*/ + +var source = new ArrayBuffer(4); + +var sourceArray = new Uint8Array(source); +sourceArray[0] = 1; +sourceArray[1] = 2; +sourceArray[2] = 3; +sourceArray[3] = 4; + +var dest = source.transferToFixedLength(); + +assert.sameValue(source.byteLength, 0, 'source.byteLength'); +assert.throws(TypeError, function() { + source.slice(); +}); + +assert.sameValue(dest.resizable, false, 'dest.resizable'); +assert.sameValue(dest.byteLength, 4, 'dest.byteLength'); +assert.sameValue(dest.maxByteLength, 4, 'dest.maxByteLength'); + +var destArray = new Uint8Array(dest); + +assert.sameValue(destArray[0], 1, 'destArray[0]'); +assert.sameValue(destArray[1], 2, 'destArray[1]'); +assert.sameValue(destArray[2], 3, 'destArray[2]'); +assert.sameValue(destArray[3], 4, 'destArray[3]'); diff --git a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-smaller-no-resizable.js b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-smaller-no-resizable.js new file mode 100644 index 000000000000..32a2aa203d96 --- /dev/null +++ b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-smaller-no-resizable.js @@ -0,0 +1,34 @@ +// Copyright (C) 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-arraybuffer.prototype.transfertofixedlength +description: Transfering from a fixed-size ArrayBuffer into a smaller ArrayBuffer +features: [arraybuffer-transfer] +---*/ + +// NOTE: This file is a copy of "from-fixed-to-samller.js" with the resizable +// ArrayBuffer parts removed, so it can run in implementations which don't yet +// support the "resizable-arraybuffer" feature. + +var source = new ArrayBuffer(4); + +var sourceArray = new Uint8Array(source); +sourceArray[0] = 1; +sourceArray[1] = 2; +sourceArray[2] = 3; +sourceArray[3] = 4; + +var dest = source.transferToFixedLength(3); + +assert.sameValue(source.byteLength, 0, 'source.byteLength'); +assert.throws(TypeError, function() { + source.slice(); +}); + +assert.sameValue(dest.byteLength, 3, 'dest.byteLength'); + +var destArray = new Uint8Array(dest); + +assert.sameValue(destArray[0], 1, 'destArray[0]'); +assert.sameValue(destArray[1], 2, 'destArray[1]'); +assert.sameValue(destArray[2], 3, 'destArray[2]'); diff --git a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-smaller.js b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-smaller.js new file mode 100644 index 000000000000..b31e95f05929 --- /dev/null +++ b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-smaller.js @@ -0,0 +1,32 @@ +// Copyright (C) 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-arraybuffer.prototype.transfertofixedlength +description: Transfering from a fixed-size ArrayBuffer into a smaller ArrayBuffer +features: [resizable-arraybuffer, arraybuffer-transfer] +---*/ + +var source = new ArrayBuffer(4); + +var sourceArray = new Uint8Array(source); +sourceArray[0] = 1; +sourceArray[1] = 2; +sourceArray[2] = 3; +sourceArray[3] = 4; + +var dest = source.transferToFixedLength(3); + +assert.sameValue(source.byteLength, 0, 'source.byteLength'); +assert.throws(TypeError, function() { + source.slice(); +}); + +assert.sameValue(dest.resizable, false, 'dest.resizable'); +assert.sameValue(dest.byteLength, 3, 'dest.byteLength'); +assert.sameValue(dest.maxByteLength, 3, 'dest.maxByteLength'); + +var destArray = new Uint8Array(dest); + +assert.sameValue(destArray[0], 1, 'destArray[0]'); +assert.sameValue(destArray[1], 2, 'destArray[1]'); +assert.sameValue(destArray[2], 3, 'destArray[2]'); diff --git a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-zero-no-resizable.js b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-zero-no-resizable.js new file mode 100644 index 000000000000..3741672edddb --- /dev/null +++ b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-zero-no-resizable.js @@ -0,0 +1,28 @@ +// Copyright (C) 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-arraybuffer.prototype.transfertofixedlength +description: Transfering from a fixed-size ArrayBuffer into a zero-length ArrayBuffer +features: [arraybuffer-transfer] +---*/ + +// NOTE: This file is a copy of "from-fixed-to-zero.js" with the resizable +// ArrayBuffer parts removed, so it can run in implementations which don't yet +// support the "resizable-arraybuffer" feature. + +var source = new ArrayBuffer(4); + +var sourceArray = new Uint8Array(source); +sourceArray[0] = 1; +sourceArray[1] = 2; +sourceArray[2] = 3; +sourceArray[3] = 4; + +var dest = source.transferToFixedLength(0); + +assert.sameValue(source.byteLength, 0, 'source.byteLength'); +assert.throws(TypeError, function() { + source.slice(); +}); + +assert.sameValue(dest.byteLength, 0, 'dest.byteLength'); diff --git a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-zero.js b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-zero.js new file mode 100644 index 000000000000..3840da776ba7 --- /dev/null +++ b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-fixed-to-zero.js @@ -0,0 +1,26 @@ +// Copyright (C) 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-arraybuffer.prototype.transfertofixedlength +description: Transfering from a fixed-size ArrayBuffer into a zero-length ArrayBuffer +features: [resizable-arraybuffer, arraybuffer-transfer] +---*/ + +var source = new ArrayBuffer(4); + +var sourceArray = new Uint8Array(source); +sourceArray[0] = 1; +sourceArray[1] = 2; +sourceArray[2] = 3; +sourceArray[3] = 4; + +var dest = source.transferToFixedLength(0); + +assert.sameValue(source.byteLength, 0, 'source.byteLength'); +assert.throws(TypeError, function() { + source.slice(); +}); + +assert.sameValue(dest.resizable, false, 'dest.resizable'); +assert.sameValue(dest.byteLength, 0, 'dest.byteLength'); +assert.sameValue(dest.maxByteLength, 0, 'dest.maxByteLength'); diff --git a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-resizable-to-larger.js b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-resizable-to-larger.js new file mode 100644 index 000000000000..4d485c554669 --- /dev/null +++ b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-resizable-to-larger.js @@ -0,0 +1,34 @@ +// Copyright (C) 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-arraybuffer.prototype.transfertofixedlength +description: Transfering from a resizable ArrayBuffer into a larger ArrayBuffer +features: [resizable-arraybuffer, arraybuffer-transfer] +---*/ + +var source = new ArrayBuffer(4, { maxByteLength: 8 }); + +var sourceArray = new Uint8Array(source); +sourceArray[0] = 1; +sourceArray[1] = 2; +sourceArray[2] = 3; +sourceArray[3] = 4; + +var dest = source.transferToFixedLength(5); + +assert.sameValue(source.byteLength, 0, 'source.byteLength'); +assert.throws(TypeError, function() { + source.slice(); +}); + +assert.sameValue(dest.resizable, false, 'dest.resizable'); +assert.sameValue(dest.byteLength, 5, 'dest.byteLength'); +assert.sameValue(dest.maxByteLength, 5, 'dest.maxByteLength'); + +var destArray = new Uint8Array(dest); + +assert.sameValue(destArray[0], 1, 'destArray[0]'); +assert.sameValue(destArray[1], 2, 'destArray[1]'); +assert.sameValue(destArray[2], 3, 'destArray[2]'); +assert.sameValue(destArray[3], 4, 'destArray[3]'); +assert.sameValue(destArray[4], 0, 'destArray[4]'); diff --git a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-resizable-to-same.js b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-resizable-to-same.js new file mode 100644 index 000000000000..a484d6c64b7c --- /dev/null +++ b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-resizable-to-same.js @@ -0,0 +1,35 @@ +// Copyright (C) 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-arraybuffer.prototype.transfertofixedlength +description: | + Transfering from a resizable ArrayBuffer into an ArrayBuffer with the same + byte length +features: [resizable-arraybuffer, arraybuffer-transfer] +---*/ + +var source = new ArrayBuffer(4, { maxByteLength: 8 }); + +var sourceArray = new Uint8Array(source); +sourceArray[0] = 1; +sourceArray[1] = 2; +sourceArray[2] = 3; +sourceArray[3] = 4; + +var dest = source.transferToFixedLength(); + +assert.sameValue(source.byteLength, 0, 'source.byteLength'); +assert.throws(TypeError, function() { + source.slice(); +}); + +assert.sameValue(dest.resizable, false, 'dest.resizable'); +assert.sameValue(dest.byteLength, 4, 'dest.byteLength'); +assert.sameValue(dest.maxByteLength, 4, 'dest.maxByteLength'); + +var destArray = new Uint8Array(dest); + +assert.sameValue(destArray[0], 1, 'destArray[0]'); +assert.sameValue(destArray[1], 2, 'destArray[1]'); +assert.sameValue(destArray[2], 3, 'destArray[2]'); +assert.sameValue(destArray[3], 4, 'destArray[3]'); diff --git a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-resizable-to-smaller.js b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-resizable-to-smaller.js new file mode 100644 index 000000000000..2e03667f2078 --- /dev/null +++ b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-resizable-to-smaller.js @@ -0,0 +1,32 @@ +// Copyright (C) 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-arraybuffer.prototype.transfertofixedlength +description: Transfering from a resizable ArrayBuffer into a smaller ArrayBuffer +features: [resizable-arraybuffer, arraybuffer-transfer] +---*/ + +var source = new ArrayBuffer(4, { maxByteLength: 8 }); + +var sourceArray = new Uint8Array(source); +sourceArray[0] = 1; +sourceArray[1] = 2; +sourceArray[2] = 3; +sourceArray[3] = 4; + +var dest = source.transferToFixedLength(3); + +assert.sameValue(source.byteLength, 0, 'source.byteLength'); +assert.throws(TypeError, function() { + source.slice(); +}); + +assert.sameValue(dest.resizable, false, 'dest.resizable'); +assert.sameValue(dest.byteLength, 3, 'dest.byteLength'); +assert.sameValue(dest.maxByteLength, 3, 'dest.maxByteLength'); + +var destArray = new Uint8Array(dest); + +assert.sameValue(destArray[0], 1, 'destArray[0]'); +assert.sameValue(destArray[1], 2, 'destArray[1]'); +assert.sameValue(destArray[2], 3, 'destArray[2]'); diff --git a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-resizable-to-zero.js b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-resizable-to-zero.js new file mode 100644 index 000000000000..94a19ad2d77e --- /dev/null +++ b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/from-resizable-to-zero.js @@ -0,0 +1,26 @@ +// Copyright (C) 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-arraybuffer.prototype.transfertofixedlength +description: Transfering from a resizable ArrayBuffer into a zero-length ArrayBuffer +features: [resizable-arraybuffer, arraybuffer-transfer] +---*/ + +var source = new ArrayBuffer(4, { maxByteLength: 8 }); + +var sourceArray = new Uint8Array(source); +sourceArray[0] = 1; +sourceArray[1] = 2; +sourceArray[2] = 3; +sourceArray[3] = 4; + +var dest = source.transferToFixedLength(0); + +assert.sameValue(source.byteLength, 0, 'source.byteLength'); +assert.throws(TypeError, function() { + source.slice(); +}); + +assert.sameValue(dest.resizable, false, 'dest.resizable'); +assert.sameValue(dest.byteLength, 0, 'dest.byteLength'); +assert.sameValue(dest.maxByteLength, 0, 'dest.maxByteLength'); diff --git a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/length.js b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/length.js new file mode 100644 index 000000000000..84ec5c929517 --- /dev/null +++ b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/length.js @@ -0,0 +1,30 @@ +// Copyright (C) 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-arraybuffer.prototype.transfertofixedlength +description: > + ArrayBuffer.prototype.transferToFixedLength.length is 0. +info: | + ArrayBuffer.prototype.transferToFixedLength ( [ newLength ] ) + + 17 ECMAScript Standard Built-in Objects: + Every built-in Function object, including constructors, has a length + property whose value is an integer. Unless otherwise specified, this + value is equal to the largest number of named arguments shown in the + subclause headings for the function description, including optional + parameters. However, rest parameters shown using the form “...name” + are not included in the default argument count. + + Unless otherwise specified, the length property of a built-in Function + object has the attributes { [[Writable]]: false, [[Enumerable]]: false, + [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [arraybuffer-transfer] +---*/ + +verifyProperty(ArrayBuffer.prototype.transferToFixedLength, 'length', { + value: 0, + enumerable: false, + writable: false, + configurable: true +}); diff --git a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/name.js b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/name.js new file mode 100644 index 000000000000..159c80d18e17 --- /dev/null +++ b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/name.js @@ -0,0 +1,27 @@ +// Copyright (C) 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-arraybuffer.prototype.transfertofixedlength +description: > + ArrayBuffer.prototype.transferToFixedLength.name is "transfer". +info: | + ArrayBuffer.prototype.transferToFixedLength ( [ newLength ] ) + + 17 ECMAScript Standard Built-in Objects: + Every built-in Function object, including constructors, that is not + identified as an anonymous function has a name property whose value + is a String. + + Unless otherwise specified, the name property of a built-in Function + object, if it exists, has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +features: [arraybuffer-transfer] +includes: [propertyHelper.js] +---*/ + +verifyProperty(ArrayBuffer.prototype.transferToFixedLength, 'name', { + value: 'transferToFixedLength', + enumerable: false, + wrtiable: false, + configurable: true +}); diff --git a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/new-length-excessive.js b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/new-length-excessive.js new file mode 100644 index 000000000000..e8b0cc343752 --- /dev/null +++ b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/new-length-excessive.js @@ -0,0 +1,16 @@ +// Copyright (C) 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-arraybuffer.prototype.transfertofixedlength +description: > + Throws a RangeError if the newLength is larger than 2^53 - 1 due to clamping + in ToIndex. +features: [arraybuffer-transfer] +---*/ + +var ab = new ArrayBuffer(0); + +assert.throws(RangeError, function() { + // Math.pow(2, 53) = 9007199254740992 + ab.transferToFixedLength(9007199254740992); +}); diff --git a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/new-length-non-number.js b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/new-length-non-number.js new file mode 100644 index 000000000000..de53b122b937 --- /dev/null +++ b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/new-length-non-number.js @@ -0,0 +1,39 @@ +// Copyright (C) 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-arraybuffer.prototype.transfertofixedlength +description: Throws a TypeError if provided length cannot be coerced to a number +info: | + ArrayBuffer.prototype.transferToFixedLength ( [ newLength ] ) + + 1. Let O be the this value. + 2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]). + 3. If IsSharedArrayBuffer(O) is true, throw a TypeError exception. + 4. If IsDetachedBuffer(O) is true, throw a TypeError exception. + 5. If newLength is undefined, let newByteLength be + O.[[ArrayBufferByteLength]]. + 6. Else, let newByteLength be ? ToIntegerOrInfinity(newLength). + [...] +features: [arraybuffer-transfer] +---*/ + +var log = []; +var newLength = { + toString: function() { + log.push('toString'); + return {}; + }, + valueOf: function() { + log.push('valueOf'); + return {}; + } +}; +var ab = new ArrayBuffer(0); + +assert.throws(TypeError, function() { + ab.transferToFixedLength(newLength); +}); + +assert.sameValue(log.length, 2); +assert.sameValue(log[0], 'valueOf'); +assert.sameValue(log[1], 'toString'); diff --git a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/nonconstructor.js b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/nonconstructor.js new file mode 100644 index 000000000000..7e3fda3a4d30 --- /dev/null +++ b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/nonconstructor.js @@ -0,0 +1,25 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-arraybuffer.prototype.transfertofixedlength +description: > + ArrayBuffer.prototype.transferToFixedLength is not a constructor function. +info: | + ArrayBuffer.prototype.transferToFixedLength ( [ newLength ] ) + + 17 ECMAScript Standard Built-in Objects: + Built-in function objects that are not identified as constructors do not + implement the [[Construct]] internal method unless otherwise specified + in the description of a particular function. +features: [arraybuffer-transfer] +---*/ + +assert.sameValue( + Object.prototype.hasOwnProperty.call(ArrayBuffer.prototype.transferToFixedLength, 'prototype'), + false +); + +var arrayBuffer = new ArrayBuffer(8); +assert.throws(TypeError, function() { + new arrayBuffer.transfer(); +}); diff --git a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/this-is-detached.js b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/this-is-detached.js new file mode 100644 index 000000000000..8aa938c1db7c --- /dev/null +++ b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/this-is-detached.js @@ -0,0 +1,27 @@ +// Copyright (C) 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-arraybuffer.prototype.transfertofixedlength +description: > + Throws a TypeError if `this` does not have an [[ArrayBufferData]] internal slot. +info: | + ArrayBuffer.prototype.transferToFixedLength ( [ newLength ] ) + + 1. Let O be the this value. + 2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]). + 3. If IsSharedArrayBuffer(O) is true, throw a TypeError exception. + 4. If IsDetachedBuffer(O) is true, throw a TypeError exception. + [...] +includes: [detachArrayBuffer.js] +features: [arraybuffer-transfer] +---*/ + +assert.sameValue(typeof ArrayBuffer.prototype.transferToFixedLength, 'function'); + +var ab = new ArrayBuffer(1); + +$DETACHBUFFER(ab); + +assert.throws(TypeError, function() { + ab.transferToFixedLength(); +}); diff --git a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/this-is-not-arraybuffer-object.js b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/this-is-not-arraybuffer-object.js new file mode 100644 index 000000000000..5bbe06b4e577 --- /dev/null +++ b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/this-is-not-arraybuffer-object.js @@ -0,0 +1,28 @@ +// Copyright (C) 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-arraybuffer.prototype.transfertofixedlength +description: > + Throws a TypeError if `this` does not have an [[ArrayBufferData]] internal slot. +info: | + ArrayBuffer.prototype.transferToFixedLength ( [ newLength ] ) + + 1. Let O be the this value. + 2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]). + [...] +features: [arraybuffer-transfer] +---*/ + +assert.sameValue(typeof ArrayBuffer.prototype.transferToFixedLength, 'function'); + +assert.throws(TypeError, function() { + ArrayBuffer.prototype.transferToFixedLength(); +}, '`this` value is the ArrayBuffer prototype'); + +assert.throws(TypeError, function() { + ArrayBuffer.prototype.transferToFixedLength.call({}); +}, '`this` value is an object'); + +assert.throws(TypeError, function() { + ArrayBuffer.prototype.transferToFixedLength.call([]); +}, '`this` value is an array'); diff --git a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/this-is-not-object.js b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/this-is-not-object.js new file mode 100644 index 000000000000..394c6ea72fc2 --- /dev/null +++ b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/this-is-not-object.js @@ -0,0 +1,44 @@ +// Copyright (C) 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-arraybuffer.prototype.transfertofixedlength +description: Throws a TypeError if `this` valueis not an object. +info: | + ArrayBuffer.prototype.transferToFixedLength ( [ newLength ] ) + + 1. Let O be the this value. + 2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]). + [...] +features: [arraybuffer-transfer, Symbol, BigInt] +---*/ + +assert.sameValue(typeof ArrayBuffer.prototype.transferToFixedLength, "function"); + +assert.throws(TypeError, function() { + ArrayBuffer.prototype.transferToFixedLength.call(undefined); +}, "`this` value is undefined"); + +assert.throws(TypeError, function() { + ArrayBuffer.prototype.transferToFixedLength.call(null); +}, "`this` value is null"); + +assert.throws(TypeError, function() { + ArrayBuffer.prototype.transferToFixedLength.call(true); +}, "`this` value is Boolean"); + +assert.throws(TypeError, function() { + ArrayBuffer.prototype.transferToFixedLength.call(""); +}, "`this` value is String"); + +var symbol = Symbol(); +assert.throws(TypeError, function() { + ArrayBuffer.prototype.transferToFixedLength.call(symbol); +}, "`this` value is Symbol"); + +assert.throws(TypeError, function() { + ArrayBuffer.prototype.transferToFixedLength.call(1); +}, "`this` value is Number"); + +assert.throws(TypeError, function() { + ArrayBuffer.prototype.transferToFixedLength.call(1n); +}, "`this` value is bigint"); diff --git a/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/this-is-sharedarraybuffer.js b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/this-is-sharedarraybuffer.js new file mode 100644 index 000000000000..77dcb90d379f --- /dev/null +++ b/JSTests/test262/test/built-ins/ArrayBuffer/prototype/transferToFixedLength/this-is-sharedarraybuffer.js @@ -0,0 +1,20 @@ +// Copyright (C) 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-arraybuffer.prototype.transfertofixedlength +description: Throws a TypeError if `this` value is a SharedArrayBuffer +info: | + ArrayBuffer.prototype.transferToFixedLength ( [ newLength ] ) + + 1. Let O be the this value. + 2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]). + 3. If IsSharedArrayBuffer(O) is true, throw a TypeError exception. + [...] +features: [SharedArrayBuffer, arraybuffer-transfer] +---*/ + +var sab = new SharedArrayBuffer(0); + +assert.throws(TypeError, function() { + ArrayBuffer.prototype.transferToFixedLength.call(sab); +}, '`this` value cannot be a SharedArrayBuffer'); diff --git a/JSTests/test262/test/built-ins/Atomics/isLockFree/expected-return-value.js b/JSTests/test262/test/built-ins/Atomics/isLockFree/expected-return-value.js index 969782d793ca..fa380fc666f1 100644 --- a/JSTests/test262/test/built-ins/Atomics/isLockFree/expected-return-value.js +++ b/JSTests/test262/test/built-ins/Atomics/isLockFree/expected-return-value.js @@ -12,7 +12,7 @@ description: > If n equals 4, return true. If n equals 8, return AR.[[IsLockFree8]]. Return false. -features: [Atomics] +features: [Atomics, Array.prototype.includes] ---*/ // These are the only counts that we care about tracking. diff --git a/JSTests/test262/test/built-ins/Function/prototype/toString/built-in-function-object.js b/JSTests/test262/test/built-ins/Function/prototype/toString/built-in-function-object.js index c7310c5c375f..a64302c1d6df 100644 --- a/JSTests/test262/test/built-ins/Function/prototype/toString/built-in-function-object.js +++ b/JSTests/test262/test/built-ins/Function/prototype/toString/built-in-function-object.js @@ -17,7 +17,7 @@ info: | set includes: [nativeFunctionMatcher.js, wellKnownIntrinsicObjects.js] -features: [arrow-function, Reflect] +features: [arrow-function, Reflect, Array.prototype.includes] ---*/ const visited = []; diff --git a/JSTests/test262/test/built-ins/Iterator/constructor.js b/JSTests/test262/test/built-ins/Iterator/constructor.js new file mode 100644 index 000000000000..9c06d9a9642b --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/constructor.js @@ -0,0 +1,11 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-iterator-constructor +description: > + The Iterator constructor is a built-in function +features: [iterator-helpers] +---*/ + +assert.sameValue(typeof Iterator, 'function', 'The value of `typeof Iterator` is "function"'); diff --git a/JSTests/test262/test/built-ins/Iterator/from/callable.js b/JSTests/test262/test/built-ins/Iterator/from/callable.js new file mode 100644 index 000000000000..738257dc0c0d --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/from/callable.js @@ -0,0 +1,12 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iterator.from +description: > + Iterator.from is callable +features: [iterator-helpers] +---*/ +function* g() {} + +Iterator.from(g()); +Iterator.from.call(null, g()); diff --git a/JSTests/test262/test/built-ins/Iterator/from/get-next-method-only-once.js b/JSTests/test262/test/built-ins/Iterator/from/get-next-method-only-once.js new file mode 100644 index 000000000000..1c75257f58be --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/from/get-next-method-only-once.js @@ -0,0 +1,46 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iterator.from +description: > + Gets the next method from the underlying iterator only once +info: | + Iterator.from ( O ) + + 2. Let iteratorRecord be ? GetIteratorFlattenable(O). + +features: [iterator-helpers] +flags: [] +---*/ +let nextGets = 0; +let nextCalls = 0; + +class CountingIterator { + get next() { + ++nextGets; + let iter = (function* () { + for (let i = 1; i < 5; ++i) { + yield i; + } + })(); + return function () { + ++nextCalls; + return iter.next(); + }; + } +} + +let iterator = new CountingIterator(); + +assert.sameValue(nextGets, 0, 'The value of `nextGets` is 0'); +assert.sameValue(nextCalls, 0, 'The value of `nextCalls` is 0'); + +iterator = Iterator.from(iterator); + +assert.sameValue(nextGets, 1, 'The value of `nextGets` is 1'); +assert.sameValue(nextCalls, 0, 'The value of `nextCalls` is 0'); + +iterator.toArray(); + +assert.sameValue(nextGets, 1, 'The value of `nextGets` is 1'); +assert.sameValue(nextCalls, 5, 'The value of `nextCalls` is 5'); diff --git a/JSTests/test262/test/built-ins/Iterator/from/get-next-method-throws.js b/JSTests/test262/test/built-ins/Iterator/from/get-next-method-throws.js new file mode 100644 index 000000000000..1b1083f2b240 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/from/get-next-method-throws.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iterator.from +description: > + Underlying iterator has throwing next getter +info: | + Iterator.from ( O ) + + 4. Let iterated be ? GetIteratorDirect(O). + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator { + get next() { + throw new Test262Error(); + } +} + +let iterator = new ThrowingIterator(); + +assert.throws(Test262Error, function () { + Iterator.from(iterator); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/from/is-function.js b/JSTests/test262/test/built-ins/Iterator/from/is-function.js new file mode 100644 index 000000000000..dc8eff9fd5de --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/from/is-function.js @@ -0,0 +1,10 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iterator.from +description: > + Iterator.from is a built-in function +features: [iterator-helpers] +---*/ + +assert.sameValue(typeof Iterator.from, 'function', 'The value of `typeof Iterator.from` is "function"'); diff --git a/JSTests/test262/test/built-ins/Iterator/from/iterable-primitives.js b/JSTests/test262/test/built-ins/Iterator/from/iterable-primitives.js new file mode 100644 index 000000000000..f162ee1cc0e4 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/from/iterable-primitives.js @@ -0,0 +1,39 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iterator.from +description: > + Iterator.from does not respect the iterability of any primitive except Strings +info: | + Iterator.from ( O ) + + 1. If O is a String, set O to ! ToObject(O). + 2. Let iteratorRecord be ? GetIteratorFlattenable(O). + +includes: [compareArray.js] +features: [iterator-helpers] +flags: [] +---*/ + +function* g() { + yield 0; +} + +Number.prototype[Symbol.iterator] = function* () { + let i = 0; + let target = this >>> 0; + while (i < target) { + yield i; + ++i; + } +}; + +assert.compareArray(Array.from(5), [0, 1, 2, 3, 4]); + +assert.throws(TypeError, function () { + Iterator.from(5); +}); + +assert.compareArray(Array.from(Iterator.from(new Number(5))), [0, 1, 2, 3, 4]); + +assert.compareArray(Array.from(Iterator.from('string')), ['s', 't', 'r', 'i', 'n', 'g']); diff --git a/JSTests/test262/test/built-ins/Iterator/from/iterable-to-iterator-fallback.js b/JSTests/test262/test/built-ins/Iterator/from/iterable-to-iterator-fallback.js new file mode 100644 index 000000000000..3228cb47f78b --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/from/iterable-to-iterator-fallback.js @@ -0,0 +1,51 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iterator.from +description: > + Iterator.from falls back to treating its parameter as an iterator if the Symbol.iterator property is null/undefined +info: | + Iterator.from ( O ) + +includes: [compareArray.js] +features: [iterator-helpers] +flags: [] +---*/ + +function* g() { + yield 0; + yield 1; + yield 2; +} + +let iter = (function () { + let n = g(); + return { + [Symbol.iterator]: 0, + next: () => n.next(), + }; +})(); + +assert.throws(TypeError, function () { + Iterator.from(iter); +}); + +iter = (function () { + let n = g(); + return { + [Symbol.iterator]: null, + next: () => n.next(), + }; +})(); + +assert.compareArray(Array.from(Iterator.from(iter)), [0, 1, 2]); + +iter = (function () { + let n = g(); + return { + [Symbol.iterator]: undefined, + next: () => n.next(), + }; +})(); + +assert.compareArray(Array.from(Iterator.from(iter)), [0, 1, 2]); diff --git a/JSTests/test262/test/built-ins/Iterator/from/length.js b/JSTests/test262/test/built-ins/Iterator/from/length.js new file mode 100644 index 000000000000..05df92269cab --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/from/length.js @@ -0,0 +1,22 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iterator.from +description: > + Iterator.from has a "length" property whose value is 1. +info: | + ECMAScript Standard Built-in Objects + + Unless otherwise specified, the length property of a built-in + Function object has the attributes { [[Writable]]: false, [[Enumerable]]: + false, [[Configurable]]: true }. +features: [iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Iterator.from, 'length', { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/from/name.js b/JSTests/test262/test/built-ins/Iterator/from/name.js new file mode 100644 index 000000000000..cff643bd1f8c --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/from/name.js @@ -0,0 +1,29 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iterator.from +description: > + The "name" property of Iterator.from +info: | + 17 ECMAScript Standard Built-in Objects + + Every built-in Function object, including constructors, that is not + identified as an anonymous function has a name property whose value is a + String. Unless otherwise specified, this value is the name that is given to + the function in this specification. + + ... + + Unless otherwise specified, the name property of a built-in Function + object, if it exists, has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +features: [iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Iterator.from, 'name', { + value: 'from', + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/from/non-constructible.js b/JSTests/test262/test/built-ins/Iterator/from/non-constructible.js new file mode 100644 index 000000000000..02eae9a5100a --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/from/non-constructible.js @@ -0,0 +1,23 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iterator.from +description: > + Iterator.from is not constructible. + + Built-in function objects that are not identified as constructors do not implement the [[Construct]] internal method unless otherwise specified in the description of a particular function. +features: [iterator-helpers] +---*/ +function* g() {} + +assert.throws(TypeError, () => { + new Iterator.from(); +}); + +assert.throws(TypeError, () => { + new Iterator.from(g()); +}); + +assert.throws(TypeError, () => { + new class extends Iterator {}.from(g()); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/from/primitives.js b/JSTests/test262/test/built-ins/Iterator/from/primitives.js new file mode 100644 index 000000000000..4c016765c817 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/from/primitives.js @@ -0,0 +1,38 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iterator.from +description: > + Iterator.from throws on primitives (except Strings) +info: | + Iterator.from ( O ) + +features: [iterator-helpers] +flags: [] +---*/ + +assert.throws(TypeError, function () { + Iterator.from(null); +}); + +assert.throws(TypeError, function () { + Iterator.from(undefined); +}); + +assert.throws(TypeError, function () { + Iterator.from(0); +}); + +assert.throws(TypeError, function () { + Iterator.from(0n); +}); + +assert.throws(TypeError, function () { + Iterator.from(true); +}); + +assert.throws(TypeError, function () { + Iterator.from(Symbol()); +}); + +Iterator.from('string'); diff --git a/JSTests/test262/test/built-ins/Iterator/from/prop-desc.js b/JSTests/test262/test/built-ins/Iterator/from/prop-desc.js new file mode 100644 index 000000000000..92fbc257619d --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/from/prop-desc.js @@ -0,0 +1,26 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iterator.from +description: > + Property descriptor of Iterator.from +info: | + Iterator.from + + * is the initial value of the Iterator.from property of the global object. + + 17 ECMAScript Standard Built-in Objects + + Every other data property described in clauses 18 through 26 and in Annex B.2 + has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +features: [globalThis, iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Iterator, 'from', { + value: Iterator.from, + writable: true, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/from/proto.js b/JSTests/test262/test/built-ins/Iterator/from/proto.js new file mode 100644 index 000000000000..b99e04fad2ab --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/from/proto.js @@ -0,0 +1,15 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iterator.from +description: > + The value of the [[Prototype]] internal slot of Iterator.from is the + intrinsic object %FunctionPrototype%. +features: [iterator-helpers] +---*/ + +assert.sameValue( + Object.getPrototypeOf(Iterator.from), + Function.prototype, + 'Object.getPrototypeOf(Iterator.from) must return the value of Function.prototype' +); diff --git a/JSTests/test262/test/built-ins/Iterator/from/result-proto.js b/JSTests/test262/test/built-ins/Iterator/from/result-proto.js new file mode 100644 index 000000000000..0888791d7bd6 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/from/result-proto.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iterator.from +description: > + The value of the [[Prototype]] internal slot of the return value of Iterator.from is the + intrinsic object %WrapForValidIteratorPrototype%, whose [[Prototype]] is %IteratorHelperPrototype%. +features: [iterator-helpers] +---*/ +let iter = { + next() { + return { + done: true, + value: undefined, + }; + }, +}; + +const WrapForValidIteratorPrototype = Object.getPrototypeOf(Iterator.from(iter)); + +assert.sameValue(Object.getPrototypeOf(WrapForValidIteratorPrototype), Iterator.prototype); + +class SubIterator extends Iterator {} +assert.sameValue(Object.getPrototypeOf(SubIterator.from(iter)), WrapForValidIteratorPrototype); + +function* g() {} +const GeneratorPrototype = Object.getPrototypeOf(g()); + +assert.sameValue(Object.getPrototypeOf(Iterator.from(g())), GeneratorPrototype); diff --git a/JSTests/test262/test/built-ins/Iterator/from/supports-iterable.js b/JSTests/test262/test/built-ins/Iterator/from/supports-iterable.js new file mode 100644 index 000000000000..03e26258cb5e --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/from/supports-iterable.js @@ -0,0 +1,14 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iterator.from +description: > + Iterator.from supports iterables +info: | + Iterator.from ( O ) + +includes: [compareArray.js] +features: [iterator-helpers] +flags: [] +---*/ +assert.compareArray(Array.from(Iterator.from([0, 1, 2, 3])), [0, 1, 2, 3]); diff --git a/JSTests/test262/test/built-ins/Iterator/from/supports-iterator.js b/JSTests/test262/test/built-ins/Iterator/from/supports-iterator.js new file mode 100644 index 000000000000..888d8dc91660 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/from/supports-iterator.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iterator.from +description: > + Iterator.from supports non-iterable iterators +info: | + Iterator.from ( O ) + +includes: [compareArray.js] +features: [iterator-helpers] +flags: [] +---*/ + +function* g() { + yield 0; + yield 1; + yield 2; + yield 3; +} + +let n = g(); +let iter = { + next() { + return n.next(); + }, +}; + +assert.compareArray(Array.from(Iterator.from(iter)), [0, 1, 2, 3]); diff --git a/JSTests/test262/test/built-ins/Iterator/length.js b/JSTests/test262/test/built-ins/Iterator/length.js new file mode 100644 index 000000000000..78d596a3eb4a --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/length.js @@ -0,0 +1,26 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-iterator-constructor +description: > + Iterator has a "length" property whose value is 0. +info: | + The Iterator Constructor + + The length property of the Iterator constructor function is 0. + ... + + ES7 section 17: Unless otherwise specified, the length property of a built-in + Function object has the attributes { [[Writable]]: false, [[Enumerable]]: + false, [[Configurable]]: true }. +features: [iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Iterator, 'length', { + value: 0, + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/name.js b/JSTests/test262/test/built-ins/Iterator/name.js new file mode 100644 index 000000000000..bb7ada2b6e53 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/name.js @@ -0,0 +1,30 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-iterator-constructor +description: > + The "name" property of Iterator +info: | + 17 ECMAScript Standard Built-in Objects + + Every built-in Function object, including constructors, that is not + identified as an anonymous function has a name property whose value is a + String. Unless otherwise specified, this value is the name that is given to + the function in this specification. + + ... + + Unless otherwise specified, the name property of a built-in Function + object, if it exists, has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +features: [iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Iterator, 'name', { + value: 'Iterator', + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/newtarget-or-active-function-object.js b/JSTests/test262/test/built-ins/Iterator/newtarget-or-active-function-object.js new file mode 100644 index 000000000000..de5ad257fcbc --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/newtarget-or-active-function-object.js @@ -0,0 +1,22 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-iterator +description: > + Iterator is not callable or constructable +info: | + When the Iterator function is called, the following steps are taken: + + If NewTarget is undefined or the active function object, throw a TypeError exception. + +features: [iterator-helpers] +---*/ + +assert.throws(TypeError, () => { + Iterator(); +}); + +assert.throws(TypeError, () => { + new Iterator(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prop-desc.js b/JSTests/test262/test/built-ins/Iterator/prop-desc.js new file mode 100644 index 000000000000..e93e9e513641 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prop-desc.js @@ -0,0 +1,27 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-iterator-constructor +description: > + Property descriptor of Iterator +info: | + The Iterator Constructor + + * is the initial value of the Iterator property of the global object. + + 17 ECMAScript Standard Built-in Objects + + Every other data property described in clauses 18 through 26 and in Annex B.2 + has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +features: [globalThis, iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(globalThis, 'Iterator', { + value: Iterator, + writable: true, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/proto-from-ctor-realm.js b/JSTests/test262/test/built-ins/Iterator/proto-from-ctor-realm.js new file mode 100644 index 000000000000..2f2f72b33fb3 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/proto-from-ctor-realm.js @@ -0,0 +1,36 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-iterator +description: Default [[Prototype]] value derived from realm of the NewTarget. +features: [cross-realm, iterator-helpers, Reflect, Symbol] +---*/ + +let other = $262.createRealm().global; +let newTarget = new other.Function(); +let ai; + +newTarget.prototype = undefined; +ai = Reflect.construct(Iterator, [1], newTarget); +assert.sameValue(Object.getPrototypeOf(ai), other.Iterator.prototype); + +newTarget.prototype = null; +ai = Reflect.construct(Iterator, [1], newTarget); +assert.sameValue(Object.getPrototypeOf(ai), other.Iterator.prototype); + +newTarget.prototype = true; +ai = Reflect.construct(Iterator, [1], newTarget); +assert.sameValue(Object.getPrototypeOf(ai), other.Iterator.prototype); + +newTarget.prototype = ''; +ai = Reflect.construct(Iterator, [1], newTarget); +assert.sameValue(Object.getPrototypeOf(ai), other.Iterator.prototype); + +newTarget.prototype = Symbol(); +ai = Reflect.construct(Iterator, [1], newTarget); +assert.sameValue(Object.getPrototypeOf(ai), other.Iterator.prototype); + +newTarget.prototype = 0; +ai = Reflect.construct(Iterator, [1], newTarget); +assert.sameValue(Object.getPrototypeOf(ai), other.Iterator.prototype); diff --git a/JSTests/test262/test/built-ins/Iterator/proto.js b/JSTests/test262/test/built-ins/Iterator/proto.js new file mode 100644 index 000000000000..f71d6eb7cd88 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/proto.js @@ -0,0 +1,16 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-properties-of-the-iterator-constructor +description: > + The value of the [[Prototype]] internal slot of the Iterator constructor is the + intrinsic object %FunctionPrototype%. +features: [iterator-helpers] +---*/ + +assert.sameValue( + Object.getPrototypeOf(Iterator), + Function.prototype, + 'Object.getPrototypeOf(Iterator) must return the value of Function.prototype' +); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/Symbol.iterator/is-function.js b/JSTests/test262/test/built-ins/Iterator/prototype/Symbol.iterator/is-function.js new file mode 100644 index 000000000000..cd6d2d96bfd5 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/Symbol.iterator/is-function.js @@ -0,0 +1,13 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.some +description: > + Iterator.prototype.some is a built-in function +features: [Symbol.iterator] +---*/ +const IteratorPrototype = Object.getPrototypeOf( + Object.getPrototypeOf([][Symbol.iterator]()) +); + +assert.sameValue(typeof IteratorPrototype[Symbol.iterator], 'function'); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/Symbol.iterator/length.js b/JSTests/test262/test/built-ins/Iterator/prototype/Symbol.iterator/length.js new file mode 100644 index 000000000000..404b17b1a5bb --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/Symbol.iterator/length.js @@ -0,0 +1,30 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.1.2.1 +description: Length of %IteratorPrototype%[ @@iterator ] +info: | + ES6 Section 17: + Every built-in Function object, including constructors, has a length + property whose value is an integer. Unless otherwise specified, this value + is equal to the largest number of named arguments shown in the subclause + headings for the function description, including optional parameters. + + [...] + + Unless otherwise specified, the length property of a built-in Function + object has the attributes { [[Writable]]: false, [[Enumerable]]: false, + [[Configurable]]: true }. +features: [Symbol.iterator] +includes: [propertyHelper.js] +---*/ +const IteratorPrototype = Object.getPrototypeOf( + Object.getPrototypeOf([][Symbol.iterator]()) +); + +verifyProperty(IteratorPrototype[Symbol.iterator], 'length', { + value: 0, + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/Symbol.iterator/name.js b/JSTests/test262/test/built-ins/Iterator/prototype/Symbol.iterator/name.js new file mode 100644 index 000000000000..2688c3d4b63f --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/Symbol.iterator/name.js @@ -0,0 +1,33 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.1.2.1 +description: Descriptor for `name` property +info: | + The value of the name property of this function is "[Symbol.iterator]". + + ES6 Section 17: ECMAScript Standard Built-in Objects + + Every built-in Function object, including constructors, that is not + identified as an anonymous function has a name property whose value is a + String. Unless otherwise specified, this value is the name that is given to + the function in this specification. + + [...] + + Unless otherwise specified, the name property of a built-in Function + object, if it exists, has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +features: [Symbol.iterator] +includes: [propertyHelper.js] +---*/ +const IteratorPrototype = Object.getPrototypeOf( + Object.getPrototypeOf([][Symbol.iterator]()) +); + +verifyProperty(IteratorPrototype[Symbol.iterator], 'name', { + value: '[Symbol.iterator]', + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/Symbol.iterator/prop-desc.js b/JSTests/test262/test/built-ins/Iterator/prototype/Symbol.iterator/prop-desc.js new file mode 100644 index 000000000000..29437e8f0fb0 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/Symbol.iterator/prop-desc.js @@ -0,0 +1,23 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.1.2.1 +description: Property descriptor +info: | + ES6 Section 17 + + Every other data property described in clauses 18 through 26 and in Annex + B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +features: [Symbol.iterator] +includes: [propertyHelper.js] +---*/ +const IteratorPrototype = Object.getPrototypeOf( + Object.getPrototypeOf([][Symbol.iterator]()) +); + +verifyProperty(IteratorPrototype, Symbol.iterator, { + writable: true, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/Symbol.iterator/return-val.js b/JSTests/test262/test/built-ins/Iterator/prototype/Symbol.iterator/return-val.js new file mode 100644 index 000000000000..d7c511149d21 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/Symbol.iterator/return-val.js @@ -0,0 +1,21 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-%iteratorprototype%-@@iterator +description: Return value of @@iterator on %IteratorPrototype% +info: | + %IteratorPrototype% [ @@iterator ] ( ) + 1. Return the this value. +features: [Symbol.iterator] +---*/ +const IteratorPrototype = Object.getPrototypeOf( + Object.getPrototypeOf([][Symbol.iterator]()) +); + +const getIterator = IteratorPrototype[Symbol.iterator]; + +const thisValues = [{}, Symbol(), 4, 4n, true, undefined, null]; + +for (const thisValue of thisValues) { + assert.sameValue(getIterator.call(thisValue), thisValue); +} diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/Symbol.toStringTag/prop-desc.js b/JSTests/test262/test/built-ins/Iterator/prototype/Symbol.toStringTag/prop-desc.js new file mode 100644 index 000000000000..8048fcf5c708 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/Symbol.toStringTag/prop-desc.js @@ -0,0 +1,20 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.1.2.1 +description: Property descriptor +info: | + ES6 Section 17 + + Every other data property described in clauses 18 through 26 and in Annex + B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +features: [iterator-helpers] +includes: [propertyHelper.js] +---*/ +verifyProperty(Iterator.prototype, Symbol.toStringTag, { + value: 'Iterator', + writable: true, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/drop/argument-effect-order.js b/JSTests/test262/test/built-ins/Iterator/prototype/drop/argument-effect-order.js new file mode 100644 index 000000000000..0917e8b3d0f7 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/drop/argument-effect-order.js @@ -0,0 +1,64 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.drop +description: > + Arguments and this value are evaluated in the correct order +info: | + %Iterator.prototype%.drop ( limit ) + +includes: [compareArray.js] +features: [iterator-helpers] +flags: [] +---*/ +let effects = []; + +Iterator.prototype.drop.call( + { + get next() { + effects.push('get next'); + return function () { + return { done: true, value: undefined }; + }; + }, + }, + { + valueOf() { + effects.push('ToNumber limit'); + return 0; + }, + } +); + +assert.compareArray(effects, ['ToNumber limit', 'get next']); + +effects = []; + +assert.throws(TypeError, function () { + Iterator.prototype.drop.call(null, { + valueOf() { + effects.push('ToNumber limit'); + return 0; + }, + }); +}); + +assert.compareArray(effects, []); + +effects = []; + +assert.throws(RangeError, function () { + Iterator.prototype.drop.call( + { + get next() { + effects.push('get next'); + return function () { + return { done: true, value: undefined }; + }; + }, + }, + NaN + ); +}); + +assert.compareArray(effects, []); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/drop/callable.js b/JSTests/test262/test/built-ins/Iterator/prototype/drop/callable.js new file mode 100644 index 000000000000..79536d2564b1 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/drop/callable.js @@ -0,0 +1,13 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.drop +description: > + Iterator.prototype.drop is callable +features: [iterator-helpers] +---*/ +function* g() {} +Iterator.prototype.drop.call(g(), 0); + +let iter = g(); +iter.drop(0); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/drop/exhaustion-does-not-call-return.js b/JSTests/test262/test/built-ins/Iterator/prototype/drop/exhaustion-does-not-call-return.js new file mode 100644 index 000000000000..744574b6cd39 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/drop/exhaustion-does-not-call-return.js @@ -0,0 +1,60 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.drop +description: > + Underlying iterator return is not called when result iterator is exhausted +info: | + %Iterator.prototype%.drop ( limit ) + + 6.b.ii. Let next be ? IteratorStep(iterated). + 6.b.iii. If next is false, return undefined. + 6.c. Repeat, + 6.c.i. Let next be ? IteratorStep(iterated). + 6.c.ii. If next is false, return undefined. + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + yield 0; + yield 1; + yield 2; +} + +class TestIterator extends Iterator { + get next() { + let n = g(); + return function() { + return n.next(); + }; + } + return() { + throw new Test262Error(); + } +} + +let iterator = new TestIterator(); +iterator = iterator.drop(0); +iterator.next(); +iterator.next(); +iterator.next(); +iterator.next(); +iterator.next(); + +iterator = new TestIterator(); +iterator = iterator.drop(1); +iterator.next(); +iterator.next(); +iterator.next(); +iterator.next(); + +iterator = new TestIterator(); +iterator = iterator.drop(1).drop(1).drop(1).drop(1).drop(1); +iterator.next(); +iterator.next(); + +iterator = new TestIterator(); +iterator = iterator.drop(10); +iterator.next(); +iterator.next(); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/drop/get-next-method-only-once.js b/JSTests/test262/test/built-ins/Iterator/prototype/drop/get-next-method-only-once.js new file mode 100644 index 000000000000..c6d574614cb0 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/drop/get-next-method-only-once.js @@ -0,0 +1,41 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.drop +description: > + Gets the next method from the underlying iterator only once +info: | + %Iterator.prototype%.drop ( limit ) + + 1. Let iterated be ? GetIteratorDirect(this value). + +features: [iterator-helpers] +flags: [] +---*/ +let nextGets = 0; +let nextCalls = 0; + +class CountingIterator extends Iterator { + get next() { + ++nextGets; + let iter = (function* () { + for (let i = 1; i < 5; ++i) { + yield i; + } + })(); + return function () { + ++nextCalls; + return iter.next(); + }; + } +} + +let iterator = new CountingIterator(); + +assert.sameValue(nextGets, 0); +assert.sameValue(nextCalls, 0); + +for (const value of iterator.drop(2)); + +assert.sameValue(nextGets, 1); +assert.sameValue(nextCalls, 5); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/drop/get-next-method-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/drop/get-next-method-throws.js new file mode 100644 index 000000000000..20b97d688bf1 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/drop/get-next-method-throws.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.drop +description: > + Underlying iterator has throwing next getter +info: | + %Iterator.prototype%.drop ( limit ) + + 1. Let iterated be ? GetIteratorDirect(this value). + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + get next() { + throw new Test262Error(); + } +} + +let iterator = new ThrowingIterator(); + +assert.throws(Test262Error, function () { + iterator.drop(0); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/drop/get-return-method-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/drop/get-return-method-throws.js new file mode 100644 index 000000000000..2ecc1a1b1fed --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/drop/get-return-method-throws.js @@ -0,0 +1,30 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.drop +description: > + Underlying iterator return is throwing getter +info: | + %Iterator.prototype%.drop ( limit ) + +features: [iterator-helpers] +flags: [] +---*/ +class TestIterator extends Iterator { + next() { + return { + done: false, + value: 1, + }; + } + get return() { + throw new Test262Error(); + } +} + +let iterator = new TestIterator().drop(1); +iterator.next(); + +assert.throws(Test262Error, function () { + iterator.return(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/drop/is-function.js b/JSTests/test262/test/built-ins/Iterator/prototype/drop/is-function.js new file mode 100644 index 000000000000..9f20d000aa27 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/drop/is-function.js @@ -0,0 +1,10 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.drop +description: > + Iterator.prototype.drop is a built-in function +features: [iterator-helpers] +---*/ + +assert.sameValue(typeof Iterator.prototype.drop, 'function'); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/drop/length.js b/JSTests/test262/test/built-ins/Iterator/prototype/drop/length.js new file mode 100644 index 000000000000..5258228bd5bb --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/drop/length.js @@ -0,0 +1,22 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.drop +description: > + Iterator.prototype.drop has a "length" property whose value is 1. +info: | + ECMAScript Standard Built-in Objects + + Unless otherwise specified, the length property of a built-in + Function object has the attributes { [[Writable]]: false, [[Enumerable]]: + false, [[Configurable]]: true }. +features: [iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Iterator.prototype.drop, 'length', { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/drop/limit-equals-total.js b/JSTests/test262/test/built-ins/Iterator/prototype/drop/limit-equals-total.js new file mode 100644 index 000000000000..6dab6111de9d --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/drop/limit-equals-total.js @@ -0,0 +1,22 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.drop +description: > + Removes entries from this iterator, specified by limit argument. +info: | + %Iterator.prototype%.drop ( limit ) + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + yield 1; + yield 2; +} + +let iterator = g().drop(2); +let { value, done } = iterator.next(); + +assert.sameValue(value, undefined); +assert.sameValue(done, true); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/drop/limit-greater-than-total.js b/JSTests/test262/test/built-ins/Iterator/prototype/drop/limit-greater-than-total.js new file mode 100644 index 000000000000..97670ad82518 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/drop/limit-greater-than-total.js @@ -0,0 +1,37 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.drop +description: > + Removes entries from this iterator, specified by limit argument. +info: | + %Iterator.prototype%.drop ( limit ) + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + yield 1; + yield 2; +} + +{ + let iterator = g().drop(3); + let { value, done } = iterator.next(); + assert.sameValue(value, undefined); + assert.sameValue(done, true); +} + +{ + let iterator = g().drop(Number.MAX_SAFE_INTEGER); + let { value, done } = iterator.next(); + assert.sameValue(value, undefined); + assert.sameValue(done, true); +} + +{ + let iterator = g().drop(Infinity); + let { value, done } = iterator.next(); + assert.sameValue(value, undefined); + assert.sameValue(done, true); +} diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/drop/limit-less-than-total.js b/JSTests/test262/test/built-ins/Iterator/prototype/drop/limit-less-than-total.js new file mode 100644 index 000000000000..a08ede359183 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/drop/limit-less-than-total.js @@ -0,0 +1,30 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.drop +description: > + Removes entries from this iterator, specified by limit argument. +info: | + %Iterator.prototype%.drop ( limit ) + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + yield 1; + yield 2; +} + +let iterator = g().drop(1); + +{ + let { value, done } = iterator.next(); + assert.sameValue(value, 2); + assert.sameValue(done, false); +} + +{ + let { value, done } = iterator.next(); + assert.sameValue(value, undefined); + assert.sameValue(done, true); +} diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/drop/limit-rangeerror.js b/JSTests/test262/test/built-ins/Iterator/prototype/drop/limit-rangeerror.js new file mode 100644 index 000000000000..f30ea6ba87e1 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/drop/limit-rangeerror.js @@ -0,0 +1,36 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.drop +description: > + Throws a RangeError exception when limit argument is NaN or less than 0. +info: | + %Iterator.prototype%.drop ( limit ) + + 3. If numLimit is NaN, throw a RangeError exception. + 4. Let integerLimit be ! ToIntegerOrInfinity(numLimit). + 5. If integerLimit < 0, throw a RangeError exception. + +features: [iterator-helpers] +---*/ +let iterator = (function* () {})(); + +iterator.drop(0); +iterator.drop(-0.5); +iterator.drop(null); + +assert.throws(RangeError, () => { + iterator.drop(-1); +}); + +assert.throws(RangeError, () => { + iterator.drop(); +}); + +assert.throws(RangeError, () => { + iterator.drop(undefined); +}); + +assert.throws(RangeError, () => { + iterator.drop(NaN); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/drop/limit-tonumber-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/drop/limit-tonumber-throws.js new file mode 100644 index 000000000000..44145e530bf5 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/drop/limit-tonumber-throws.js @@ -0,0 +1,22 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.drop +description: > + Throws a RangeError exception when limit argument valueOf throws. +info: | + %Iterator.prototype%.drop ( limit ) + + 2. Let numLimit be ? ToNumber(limit). + +features: [iterator-helpers] +---*/ +let iterator = (function* () {})(); + +assert.throws(Test262Error, () => { + iterator.drop({ + valueOf: function () { + throw new Test262Error(); + }, + }); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/drop/limit-tonumber.js b/JSTests/test262/test/built-ins/Iterator/prototype/drop/limit-tonumber.js new file mode 100644 index 000000000000..80b9bbd48342 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/drop/limit-tonumber.js @@ -0,0 +1,37 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.drop +description: > + Converts the limit argument to a Number using ToNumber and valueOf/toString. +info: | + %Iterator.prototype%.drop ( limit ) + + 2. Let numLimit be ? ToNumber(limit). + +features: [iterator-helpers] +---*/ +function* g() { + yield 1; + yield 2; +} + +{ + let iterator = g(); + let { value, done } = iterator + .drop({ + valueOf: function () { + return 1; + }, + }) + .next(); + assert.sameValue(value, 2); + assert.sameValue(done, false); +} + +{ + let iterator = g(); + let { value, done } = iterator.drop([]).drop([1]).next(); + assert.sameValue(value, 2); + assert.sameValue(done, false); +} diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/drop/name.js b/JSTests/test262/test/built-ins/Iterator/prototype/drop/name.js new file mode 100644 index 000000000000..928e37657053 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/drop/name.js @@ -0,0 +1,29 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.drop +description: > + The "name" property of Iterator.prototype.drop +info: | + 17 ECMAScript Standard Built-in Objects + + Every built-in Function object, including constructors, that is not + identified as an anonymous function has a name property whose value is a + String. Unless otherwise specified, this value is the name that is given to + the function in this specification. + + ... + + Unless otherwise specified, the name property of a built-in Function + object, if it exists, has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +features: [iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Iterator.prototype.drop, 'name', { + value: 'drop', + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/drop/next-method-returns-non-object.js b/JSTests/test262/test/built-ins/Iterator/prototype/drop/next-method-returns-non-object.js new file mode 100644 index 000000000000..028db0226b2f --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/drop/next-method-returns-non-object.js @@ -0,0 +1,33 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.drop +description: > + Underlying iterator next returns non-object +info: | + %Iterator.prototype%.drop ( limit ) + + 6.b.ii. Let next be ? IteratorStep(iterated). + + 6.c.i. Let next be ? IteratorStep(iterated). + +features: [iterator-helpers] +flags: [] +---*/ +class NonObjectIterator extends Iterator { + next() { + return null; + } +} + +let iterator = new NonObjectIterator().drop(0); + +assert.throws(TypeError, function () { + iterator.next(); +}); + +iterator = new NonObjectIterator().drop(2); + +assert.throws(TypeError, function () { + iterator.next(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/drop/next-method-returns-throwing-done.js b/JSTests/test262/test/built-ins/Iterator/prototype/drop/next-method-returns-throwing-done.js new file mode 100644 index 000000000000..88ef17ea195a --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/drop/next-method-returns-throwing-done.js @@ -0,0 +1,41 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.drop +description: > + Underlying iterator next returns object with throwing done getter +info: | + %Iterator.prototype%.drop ( limit ) + + 6.b.ii. Let next be ? IteratorStep(iterated). + + 6.c.i. Let next be ? IteratorStep(iterated). + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + return { + get done() { + throw new Test262Error(); + }, + value: 1, + }; + } + return() { + throw new Error(); + } +} + +let iterator = new ThrowingIterator().drop(0); + +assert.throws(Test262Error, function () { + iterator.next(); +}); + +iterator = new ThrowingIterator().drop(1); + +assert.throws(Test262Error, function () { + iterator.next(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/drop/next-method-returns-throwing-value-done.js b/JSTests/test262/test/built-ins/Iterator/prototype/drop/next-method-returns-throwing-value-done.js new file mode 100644 index 000000000000..06adf97062fb --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/drop/next-method-returns-throwing-value-done.js @@ -0,0 +1,36 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.drop +description: > + Underlying iterator next returns object with throwing value getter, but is already done +info: | + %Iterator.prototype%.drop ( limit ) + + 6.c.ii. If next is false, return undefined. + +features: [iterator-helpers] +flags: [] +---*/ +class ReturnCalledError extends Error {} +class ValueGetterError extends Error {} + +class ThrowingIterator extends Iterator { + next() { + return { + done: true, + get value() { + throw new ValueGetterError(); + }, + }; + } + return() { + throw new ReturnCalledError(); + } +} + +let iterator = new ThrowingIterator().drop(0); +iterator.next(); + +iterator = new ThrowingIterator().drop(1); +iterator.next(); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/drop/next-method-returns-throwing-value.js b/JSTests/test262/test/built-ins/Iterator/prototype/drop/next-method-returns-throwing-value.js new file mode 100644 index 000000000000..da90956616bb --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/drop/next-method-returns-throwing-value.js @@ -0,0 +1,39 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.drop +description: > + Underlying iterator next returns object with throwing value getter +info: | + %Iterator.prototype%.drop ( limit ) + + 6.c.iii. Let completion be Completion(Yield(? IteratorValue(next))). + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + return { + done: false, + get value() { + throw new Test262Error(); + }, + }; + } + return() { + throw new Error(); + } +} + +let iterator = new ThrowingIterator().drop(0); + +assert.throws(Test262Error, function () { + iterator.next(); +}); + +iterator = new ThrowingIterator().drop(1); + +assert.throws(Test262Error, function () { + iterator.next(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/drop/next-method-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/drop/next-method-throws.js new file mode 100644 index 000000000000..573294057a53 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/drop/next-method-throws.js @@ -0,0 +1,33 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.drop +description: > + Underlying iterator has throwing next method +info: | + %Iterator.prototype%.drop ( limit ) + + 6.b.ii. Let next be ? IteratorStep(iterated). + + 6.c.i. Let next be ? IteratorStep(iterated). + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + throw new Test262Error(); + } +} + +let iterator = new ThrowingIterator().drop(0); + +assert.throws(Test262Error, function () { + iterator.next(); +}); + +iterator = new ThrowingIterator().drop(1); + +assert.throws(Test262Error, function () { + iterator.next(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/drop/non-constructible.js b/JSTests/test262/test/built-ins/Iterator/prototype/drop/non-constructible.js new file mode 100644 index 000000000000..391c53d8490a --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/drop/non-constructible.js @@ -0,0 +1,28 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.drop +description: > + Iterator.prototype.drop is not constructible. + + Built-in function objects that are not identified as constructors do not implement the [[Construct]] internal method unless otherwise specified in the description of a particular function. +features: [iterator-helpers] +---*/ +function* g() {} +let iter = g(); + +assert.throws(TypeError, () => { + new iter.drop(); +}); + +assert.throws(TypeError, () => { + new iter.drop(0); +}); + +assert.throws(TypeError, () => { + new Iterator.prototype.drop(0); +}); + +assert.throws(TypeError, () => { + new class extends Iterator {}.drop(0); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/drop/prop-desc.js b/JSTests/test262/test/built-ins/Iterator/prototype/drop/prop-desc.js new file mode 100644 index 000000000000..f2018fcc8aeb --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/drop/prop-desc.js @@ -0,0 +1,25 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.drop +description: > + Property descriptor of Iterator.prototype.drop +info: | + Iterator.prototype.drop + + * is the initial value of the Iterator.prototype.drop property of the global object. + + 17 ECMAScript Standard Built-in Objects + + Every other data property described in clauses 18 through 26 and in Annex B.2 + has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +features: [globalThis, iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Iterator.prototype, 'drop', { + writable: true, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/drop/proto.js b/JSTests/test262/test/built-ins/Iterator/prototype/drop/proto.js new file mode 100644 index 000000000000..97ee0374275b --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/drop/proto.js @@ -0,0 +1,11 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.drop +description: > + The value of the [[Prototype]] internal slot of Iterator.prototype.drop is the + intrinsic object %FunctionPrototype%. +features: [iterator-helpers] +---*/ + +assert.sameValue(Object.getPrototypeOf(Iterator.prototype.drop), Function.prototype); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/drop/result-is-iterator.js b/JSTests/test262/test/built-ins/Iterator/prototype/drop/result-is-iterator.js new file mode 100644 index 000000000000..7ccf4aa57fd4 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/drop/result-is-iterator.js @@ -0,0 +1,11 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.drop +description: > + The value of the [[Prototype]] internal slot of the return value of Iterator.prototype.drop is the + intrinsic object %IteratorHelperPrototype%. +features: [iterator-helpers] +---*/ + +assert((function* () {})().drop(0) instanceof Iterator, 'function*(){}().drop(0) must return an Iterator'); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/drop/return-is-forwarded.js b/JSTests/test262/test/built-ins/Iterator/prototype/drop/return-is-forwarded.js new file mode 100644 index 000000000000..fea82f7ab771 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/drop/return-is-forwarded.js @@ -0,0 +1,54 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.drop +description: > + Underlying iterator return is called when result iterator is closed +info: | + %Iterator.prototype%.drop ( limit ) + + 6.c.iii. Let completion be Completion(Yield(? IteratorValue(next))). + 6.c.iv. IfAbruptCloseIterator(completion, iterated). + +features: [iterator-helpers] +flags: [] +---*/ +let returnCount = 0; + +class TestIterator extends Iterator { + next() { + return { + done: false, + value: 1, + }; + } + return() { + ++returnCount; + return {}; + } +} + +let iterator = new TestIterator().drop(0); +assert.sameValue(returnCount, 0); +iterator.return(); +assert.sameValue(returnCount, 1); +iterator.return(); +assert.sameValue(returnCount, 1); + +returnCount = 0; + +iterator = new TestIterator().drop(1); +assert.sameValue(returnCount, 0); +iterator.return(); +assert.sameValue(returnCount, 1); +iterator.return(); +assert.sameValue(returnCount, 1); + +returnCount = 0; + +iterator = new TestIterator().drop(1).drop(1).drop(1).drop(1).drop(1); +assert.sameValue(returnCount, 0); +iterator.return(); +assert.sameValue(returnCount, 1); +iterator.return(); +assert.sameValue(returnCount, 1); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/drop/return-is-not-forwarded-after-exhaustion.js b/JSTests/test262/test/built-ins/Iterator/prototype/drop/return-is-not-forwarded-after-exhaustion.js new file mode 100644 index 000000000000..0917b4a423da --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/drop/return-is-not-forwarded-after-exhaustion.js @@ -0,0 +1,50 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.drop +description: > + Underlying iterator return is not called after result iterator observes that underlying iterator is exhausted +info: | + %Iterator.prototype%.drop ( limit ) + +features: [iterator-helpers] +flags: [] +---*/ +let returnCount = 0; + +class TestIterator extends Iterator { + next() { + return { + done: true, + value: undefined, + }; + } + return() { + throw new Test262Error(); + } +} + +let iterator = new TestIterator().drop(0); +assert.throws(Test262Error, function () { + iterator.return(); +}); +iterator.next(); +iterator.return(); + +iterator = new TestIterator().drop(1); +iterator.next(); +iterator.return(); + +iterator = new TestIterator().drop(1); +assert.throws(Test262Error, function () { + iterator.return(); +}); +iterator.next(); +iterator.return(); + +iterator = new TestIterator().drop(1).drop(1).drop(1).drop(1).drop(1); +assert.throws(Test262Error, function () { + iterator.return(); +}); +iterator.next(); +iterator.return(); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/drop/this-non-callable-next.js b/JSTests/test262/test/built-ins/Iterator/prototype/drop/this-non-callable-next.js new file mode 100644 index 000000000000..6fed69ac238c --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/drop/this-non-callable-next.js @@ -0,0 +1,19 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.drop +description: > + Iterator.prototype.drop throws TypeError when its this value is an object with a non-callable next +info: | + %Iterator.prototype%.drop ( limit ) + + 1. Let iterated be ? GetIteratorDirect(this value). + +features: [iterator-helpers] +flags: [] +---*/ +let iter = Iterator.prototype.drop.call({ next: 0 }, 1); + +assert.throws(TypeError, function () { + iter.next(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/drop/this-non-object.js b/JSTests/test262/test/built-ins/Iterator/prototype/drop/this-non-object.js new file mode 100644 index 000000000000..2e3b2f3f7816 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/drop/this-non-object.js @@ -0,0 +1,34 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.drop +description: > + Iterator.prototype.drop throws TypeError when its this value is a non-object +info: | + %Iterator.prototype%.drop ( limit ) + + 1. Let iterated be ? GetIteratorDirect(this value). + +features: [iterator-helpers] +flags: [] +---*/ +assert.throws(TypeError, function () { + Iterator.prototype.drop.call(null, 1); +}); + +assert.throws(TypeError, function () { + Iterator.prototype.drop.call(null, { + valueOf: function () { + throw new Test262Error(); + }, + }); +}); + +Object.defineProperty(Number.prototype, 'next', { + get: function () { + throw new Test262Error(); + }, +}); +assert.throws(TypeError, function () { + Iterator.prototype.drop.call(0, 1); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/drop/this-plain-iterator.js b/JSTests/test262/test/built-ins/Iterator/prototype/drop/this-plain-iterator.js new file mode 100644 index 000000000000..77071c652fb2 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/drop/this-plain-iterator.js @@ -0,0 +1,30 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.drop +description: > + Iterator.prototype.drop supports a this value that does not inherit from Iterator.prototype but implements the iterator protocol +info: | + %Iterator.prototype%.drop ( limit ) + + 1. Let iterated be ? GetIteratorDirect(this value). + +features: [iterator-helpers] +flags: [] +---*/ +let iter = { + get next() { + let count = 3; + return function () { + --count; + return count >= 0 ? { done: false, value: count } : { done: true, value: undefined }; + }; + }, +}; + +let dropIter = Iterator.prototype.drop.call(iter, 1); + +let { done, value } = dropIter.next(); + +assert.sameValue(done, false); +assert.sameValue(value, 1); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/drop/underlying-iterator-advanced-in-parallel.js b/JSTests/test262/test/built-ins/Iterator/prototype/drop/underlying-iterator-advanced-in-parallel.js new file mode 100644 index 000000000000..5040a33d6304 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/drop/underlying-iterator-advanced-in-parallel.js @@ -0,0 +1,39 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.drop +description: > + Underlying iterator is advanced after calling drop +info: | + %Iterator.prototype%.drop ( limit ) + +features: [iterator-helpers] +flags: [] +---*/ +let iterator = (function* () { + for (let i = 0; i < 5; ++i) { + yield i; + } +})(); + +let dropped = iterator.drop(2); + +let { value, done } = iterator.next(); + +assert.sameValue(value, 0); +assert.sameValue(done, false); + +({ value, done } = dropped.next()); + +assert.sameValue(value, 3); +assert.sameValue(done, false); + +({ value, done } = dropped.next()); + +assert.sameValue(value, 4); +assert.sameValue(done, false); + +({ value, done } = dropped.next()); + +assert.sameValue(value, undefined); +assert.sameValue(done, true); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/drop/underlying-iterator-closed-in-parallel.js b/JSTests/test262/test/built-ins/Iterator/prototype/drop/underlying-iterator-closed-in-parallel.js new file mode 100644 index 000000000000..f8f68198ae1d --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/drop/underlying-iterator-closed-in-parallel.js @@ -0,0 +1,26 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.drop +description: > + Underlying iterator is closed after calling drop +info: | + %Iterator.prototype%.drop ( limit ) + +features: [iterator-helpers] +flags: [] +---*/ +let iterator = (function* () { + for (let i = 0; i < 5; ++i) { + yield i; + } +})(); + +let dropped = iterator.drop(2); + +iterator.return(); + +let { value, done } = dropped.next(); + +assert.sameValue(value, undefined); +assert.sameValue(done, true); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/drop/underlying-iterator-closed.js b/JSTests/test262/test/built-ins/Iterator/prototype/drop/underlying-iterator-closed.js new file mode 100644 index 000000000000..e3cfd1ec4f71 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/drop/underlying-iterator-closed.js @@ -0,0 +1,26 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.drop +description: > + Underlying iterator is closed before calling drop +info: | + %Iterator.prototype%.drop ( limit ) + +features: [iterator-helpers] +flags: [] +---*/ +let iterator = (function* () { + for (let i = 0; i < 5; ++i) { + yield i; + } +})(); + +iterator.return(); + +let dropped = iterator.drop(2); + +let { value, done } = dropped.next(); + +assert.sameValue(value, undefined); +assert.sameValue(done, true); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/every/argument-effect-order.js b/JSTests/test262/test/built-ins/Iterator/prototype/every/argument-effect-order.js new file mode 100644 index 000000000000..76753982590e --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/every/argument-effect-order.js @@ -0,0 +1,30 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.every +description: > + Arguments and this value are evaluated in the correct order +info: | + %Iterator.prototype%.every ( predicate ) + +includes: [compareArray.js] +features: [iterator-helpers] +flags: [] +---*/ +let effects = []; + +assert.throws(TypeError, function () { + Iterator.prototype.every.call( + { + get next() { + effects.push('get next'); + return function () { + return { done: true, value: undefined }; + }; + }, + }, + null + ); +}); + +assert.compareArray(effects, []); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/every/callable.js b/JSTests/test262/test/built-ins/Iterator/prototype/every/callable.js new file mode 100644 index 000000000000..30bd81e7e70a --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/every/callable.js @@ -0,0 +1,13 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.every +description: > + Iterator.prototype.every is callable +features: [iterator-helpers] +---*/ +function* g() {} +Iterator.prototype.every.call(g(), () => {}); + +let iter = g(); +iter.every(() => {}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/every/get-next-method-only-once.js b/JSTests/test262/test/built-ins/Iterator/prototype/every/get-next-method-only-once.js new file mode 100644 index 000000000000..58baec871470 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/every/get-next-method-only-once.js @@ -0,0 +1,38 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.every +description: > + Gets the next method from the iterator only once +info: | + %Iterator.prototype%.every ( predicate ) + + 1. Let iterated be ? GetIteratorDirect(this value). + +features: [iterator-helpers] +flags: [] +---*/ +let nextGets = 0; + +class TestIterator extends Iterator { + get next() { + ++nextGets; + let counter = 5; + return function () { + if (counter < 0) { + return { done: true, value: undefined }; + } else { + return { done: false, value: --counter }; + } + }; + } +} + +let iterator = new TestIterator(); + +assert.sameValue(nextGets, 0); +assert.sameValue( + iterator.every(() => true), + true +); +assert.sameValue(nextGets, 1); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/every/get-next-method-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/every/get-next-method-throws.js new file mode 100644 index 000000000000..067167aa9c08 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/every/get-next-method-throws.js @@ -0,0 +1,25 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.every +description: > + Iterator has throwing next getter +info: | + %Iterator.prototype%.every ( predicate ) + + 1. Let iterated be ? GetIteratorDirect(this value). + +features: [iterator-helpers] +flags: [] +---*/ +class IteratorThrows extends Iterator { + get next() { + throw new Test262Error(); + } +} + +let iterator = new IteratorThrows(); + +assert.throws(Test262Error, function () { + iterator.every(() => {}); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/every/get-return-method-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/every/get-return-method-throws.js new file mode 100644 index 000000000000..b90f0b103a1c --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/every/get-return-method-throws.js @@ -0,0 +1,31 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.every +description: > + Iterator has throwing return getter +info: | + %Iterator.prototype%.every ( predicate ) + + 4.f. If ToBoolean(result) is false, return ? IteratorClose(iterated, NormalCompletion(false)). + +features: [iterator-helpers] +flags: [] +---*/ +class IteratorThrows extends Iterator { + next() { + return { + done: false, + value: 0, + }; + } + get return() { + throw new Test262Error(); + } +} + +let iterator = new IteratorThrows([1, 2]); + +assert.throws(Test262Error, function () { + iterator.every(() => false); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/every/is-function.js b/JSTests/test262/test/built-ins/Iterator/prototype/every/is-function.js new file mode 100644 index 000000000000..91367c99c0a6 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/every/is-function.js @@ -0,0 +1,10 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.every +description: > + Iterator.prototype.every is a built-in function +features: [iterator-helpers] +---*/ + +assert.sameValue(typeof Iterator.prototype.every, 'function'); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/every/iterator-already-exhausted.js b/JSTests/test262/test/built-ins/Iterator/prototype/every/iterator-already-exhausted.js new file mode 100644 index 000000000000..43b5bc7216e3 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/every/iterator-already-exhausted.js @@ -0,0 +1,26 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.every +description: > + Iterator.prototype.every returns true when the iterator has already been exhausted +info: | + %Iterator.prototype%.every ( predicate ) + + 4.a. Let next be ? IteratorStep(iterated). + 4.b. If next is false, return true. + +features: [iterator-helpers] +flags: [] +---*/ +let iterator = (function* () {})(); + +let { value, done } = iterator.next(); +assert.sameValue(value, undefined); +assert.sameValue(done, true); + +let result = iterator.every(() => true); +assert.sameValue(result, true); + +result = iterator.every(() => false); +assert.sameValue(result, true); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/every/iterator-has-no-return.js b/JSTests/test262/test/built-ins/Iterator/prototype/every/iterator-has-no-return.js new file mode 100644 index 000000000000..d772403ace1b --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/every/iterator-has-no-return.js @@ -0,0 +1,27 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.every +description: > + The underlying iterator is sometimes unable to be closed (has no return method) +info: | + %Iterator.prototype%.every ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +let iterator = [1, 2, 3, 4, 5][Symbol.iterator](); + +assert.sameValue(iterator.return, undefined); + +let ret = iterator.every(v => v < 4); + +assert.sameValue(ret, false); + +let { done, value } = iterator.next(); +assert.sameValue(done, false); +assert.sameValue(value, 5); + +({ done, value } = iterator.next()); +assert.sameValue(done, true); +assert.sameValue(value, undefined); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/every/iterator-return-method-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/every/iterator-return-method-throws.js new file mode 100644 index 000000000000..b221322e768c --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/every/iterator-return-method-throws.js @@ -0,0 +1,31 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.every +description: > + Iterator has throwing return +info: | + %Iterator.prototype%.every ( predicate ) + + 4.f. If ToBoolean(result) is false, return ? IteratorClose(iterated, NormalCompletion(false)). + +features: [iterator-helpers] +flags: [] +---*/ +class IteratorThrows extends Iterator { + next() { + return { + done: false, + value: 0, + }; + } + return() { + throw new Test262Error(); + } +} + +let iterator = new IteratorThrows(); + +assert.throws(Test262Error, function () { + iterator.every(() => false); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/every/length.js b/JSTests/test262/test/built-ins/Iterator/prototype/every/length.js new file mode 100644 index 000000000000..762f9bdbe1cf --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/every/length.js @@ -0,0 +1,22 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.every +description: > + Iterator.prototype.every has a "length" property whose value is 1. +info: | + ECMAScript Standard Built-in Objects + + Unless otherwise specified, the length property of a built-in + Function object has the attributes { [[Writable]]: false, [[Enumerable]]: + false, [[Configurable]]: true }. +features: [iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Iterator.prototype.every, 'length', { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/every/name.js b/JSTests/test262/test/built-ins/Iterator/prototype/every/name.js new file mode 100644 index 000000000000..a0226f87782a --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/every/name.js @@ -0,0 +1,29 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.every +description: > + The "name" property of Iterator.prototype.every +info: | + 17 ECMAScript Standard Built-in Objects + + Every built-in Function object, including constructors, that is not + identified as an anonymous function has a name property whose value is a + String. Unless otherwise specified, this value is the name that is given to + the function in this specification. + + ... + + Unless otherwise specified, the name property of a built-in Function + object, if it exists, has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +features: [iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Iterator.prototype.every, 'name', { + value: 'every', + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/every/next-method-returns-non-object.js b/JSTests/test262/test/built-ins/Iterator/prototype/every/next-method-returns-non-object.js new file mode 100644 index 000000000000..d0ec0e3ee361 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/every/next-method-returns-non-object.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.every +description: > + Underlying iterator next returns non-object +info: | + %Iterator.prototype%.every ( predicate ) + + 4.a. Let next be ? IteratorStep(iterated). + +features: [iterator-helpers] +flags: [] +---*/ +class NonObjectIterator extends Iterator { + next() { + return null; + } +} + +let iterator = new NonObjectIterator(); + +assert.throws(TypeError, function () { + iterator.every(() => {}); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/every/next-method-returns-throwing-done.js b/JSTests/test262/test/built-ins/Iterator/prototype/every/next-method-returns-throwing-done.js new file mode 100644 index 000000000000..56dc8d62d4b1 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/every/next-method-returns-throwing-done.js @@ -0,0 +1,33 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.every +description: > + Underlying iterator next returns object with throwing done getter +info: | + %Iterator.prototype%.every ( predicate ) + + 4.a. Let next be ? IteratorStep(iterated). + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + return { + get done() { + throw new Test262Error(); + }, + value: 1, + }; + } + return() { + throw new Error(); + } +} + +let iterator = new ThrowingIterator(); + +assert.throws(Test262Error, function () { + iterator.every(() => {}); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/every/next-method-returns-throwing-value-done.js b/JSTests/test262/test/built-ins/Iterator/prototype/every/next-method-returns-throwing-value-done.js new file mode 100644 index 000000000000..983a243ab0b0 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/every/next-method-returns-throwing-value-done.js @@ -0,0 +1,30 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.every +description: > + Underlying iterator next returns object with throwing value getter, but is already done +info: | + %Iterator.prototype%.every ( predicate ) + + 4.c. Let value be ? IteratorValue(next). + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + return { + done: true, + get value() { + throw new Test262Error(); + }, + }; + } + return() { + throw new Error(); + } +} + +let iterator = new ThrowingIterator(); +iterator.every(() => {}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/every/next-method-returns-throwing-value.js b/JSTests/test262/test/built-ins/Iterator/prototype/every/next-method-returns-throwing-value.js new file mode 100644 index 000000000000..b2b5f53558f7 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/every/next-method-returns-throwing-value.js @@ -0,0 +1,33 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.every +description: > + Underlying iterator next returns object with throwing value getter +info: | + %Iterator.prototype%.every ( predicate ) + + 4.c. Let value be ? IteratorValue(next). + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + return { + done: false, + get value() { + throw new Test262Error(); + }, + }; + } + return() { + throw new Error(); + } +} + +let iterator = new ThrowingIterator(); + +assert.throws(Test262Error, function () { + iterator.every(() => {}); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/every/next-method-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/every/next-method-throws.js new file mode 100644 index 000000000000..91df2bcf65f3 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/every/next-method-throws.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.every +description: > + Underlying iterator has throwing next method +info: | + %Iterator.prototype%.every ( predicate ) + + 4.a. Let next be ? IteratorStep(iterated). + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + throw new Test262Error(); + } +} + +let iterator = new ThrowingIterator(); + +assert.throws(Test262Error, function () { + iterator.every(() => {}); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/every/non-callable-predicate.js b/JSTests/test262/test/built-ins/Iterator/prototype/every/non-callable-predicate.js new file mode 100644 index 000000000000..51728975bfe3 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/every/non-callable-predicate.js @@ -0,0 +1,22 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.every +description: > + Iterator.prototype.every expects to be called with a callable argument. +info: | + %Iterator.prototype%.every ( predicate ) + + 2. If IsCallable(predicate) is false, throw a TypeError exception. + +features: [iterator-helpers] +flags: [] +---*/ +let nonCallable = {}; +let iterator = (function* () { + yield 1; +})(); + +assert.throws(TypeError, function () { + iterator.every(nonCallable); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/every/non-constructible.js b/JSTests/test262/test/built-ins/Iterator/prototype/every/non-constructible.js new file mode 100644 index 000000000000..1b222db1c163 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/every/non-constructible.js @@ -0,0 +1,28 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.every +description: > + Iterator.prototype.every is not constructible. + + Built-in function objects that are not identified as constructors do not implement the [[Construct]] internal method unless otherwise specified in the description of a particular function. +features: [iterator-helpers] +---*/ +function* g() {} +let iter = g(); + +assert.throws(TypeError, () => { + new iter.every(); +}); + +assert.throws(TypeError, () => { + new iter.every(() => {}); +}); + +assert.throws(TypeError, () => { + new Iterator.prototype.every(() => {}); +}); + +assert.throws(TypeError, () => { + new class extends Iterator {}.every(() => {}); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/every/predicate-args.js b/JSTests/test262/test/built-ins/Iterator/prototype/every/predicate-args.js new file mode 100644 index 000000000000..e2f2fb0e612b --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/every/predicate-args.js @@ -0,0 +1,43 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.every +description: > + Iterator.prototype.every predicate is passed the yielded value and a counter as arguments +info: | + %Iterator.prototype%.every ( predicate ) + + 4.d. Let result be Completion(Call(predicate, undefined, « value, 𝔽(counter) »)). + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + yield 'a'; + yield 'b'; + yield 'c'; +} + +let iter = g(); + +let assertionCount = 0; +let result = iter.every((v, count) => { + switch (v) { + case 'a': + assert.sameValue(count, 0); + break; + case 'b': + assert.sameValue(count, 1); + break; + case 'c': + assert.sameValue(count, 2); + break; + default: + throw new Error(); + } + ++assertionCount; + return true; +}); + +assert.sameValue(result, true); +assert.sameValue(assertionCount, 3); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/every/predicate-returns-falsey.js b/JSTests/test262/test/built-ins/Iterator/prototype/every/predicate-returns-falsey.js new file mode 100644 index 000000000000..6e5b973cfbb8 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/every/predicate-returns-falsey.js @@ -0,0 +1,33 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.every +description: > + Iterator.prototype.every returns false and closes the iterator when the predicate returns falsey immediately +info: | + %Iterator.prototype%.every ( predicate ) + + 4.f. If ToBoolean(result) is false, return ? IteratorClose(iterated, NormalCompletion(false)). + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + yield 0; + yield 1; +} + +let iter = g(); + +let predicateCalls = 0; +let result = iter.every(v => { + ++predicateCalls; + return false; +}); + +assert.sameValue(result, false); +assert.sameValue(predicateCalls, 1); + +let { done, value } = iter.next(); +assert.sameValue(done, true); +assert.sameValue(value, undefined); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/every/predicate-returns-non-boolean.js b/JSTests/test262/test/built-ins/Iterator/prototype/every/predicate-returns-non-boolean.js new file mode 100644 index 000000000000..3c545ed70c40 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/every/predicate-returns-non-boolean.js @@ -0,0 +1,30 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.every +description: > + Iterator.prototype.every coerces predicate return value to boolean +info: | + %Iterator.prototype%.every ( predicate ) + + 4.f. If ToBoolean(result) is false, return ? IteratorClose(iterated, NormalCompletion(false)). + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + for (let i = 4; i >= 0; --i) { + yield i; + } +} + +let iter = g(); + +let predicateCalls = 0; +let result = iter.every(v => { + ++predicateCalls; + return v; +}); + +assert.sameValue(result, false); +assert.sameValue(predicateCalls, 5); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/every/predicate-returns-truthy-then-falsey.js b/JSTests/test262/test/built-ins/Iterator/prototype/every/predicate-returns-truthy-then-falsey.js new file mode 100644 index 000000000000..28c3bfa43cd8 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/every/predicate-returns-truthy-then-falsey.js @@ -0,0 +1,34 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.every +description: > + Iterator.prototype.every returns false and closes the iterator when the predicate returns truthy for some iterated values and falsey for others +info: | + %Iterator.prototype%.every ( predicate ) + + 4.f. If ToBoolean(result) is false, return ? IteratorClose(iterated, NormalCompletion(false)). + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + for (let i = 0; i < 5; ++i) { + yield i; + } +} + +let iter = g(); + +let predicateCalls = 0; +let result = iter.every(v => { + ++predicateCalls; + return v < 3; +}); + +assert.sameValue(result, false); +assert.sameValue(predicateCalls, 4); + +let { done, value } = iter.next(); +assert.sameValue(done, true); +assert.sameValue(value, undefined); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/every/predicate-returns-truthy.js b/JSTests/test262/test/built-ins/Iterator/prototype/every/predicate-returns-truthy.js new file mode 100644 index 000000000000..3305f926d6ff --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/every/predicate-returns-truthy.js @@ -0,0 +1,24 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.every +description: > + Iterator.prototype.every returns true when the predicate returns truthy for all iterated values +info: | + %Iterator.prototype%.every ( predicate ) + + 4.b. If next is false, return true. + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + yield 0; + yield 1; + yield 2; + yield 3; + yield 4; +} + +let result = g().every(() => true); +assert.sameValue(result, true); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/every/predicate-this.js b/JSTests/test262/test/built-ins/Iterator/prototype/every/predicate-this.js new file mode 100644 index 000000000000..529c809a2c16 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/every/predicate-this.js @@ -0,0 +1,33 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.every +description: > + Iterator.prototype.every predicate this value is undefined +info: | + %Iterator.prototype%.every ( predicate ) + + 4.d. Let result be Completion(Call(predicate, undefined, « value, 𝔽(counter) »)). + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + yield 0; +} + +let iter = g(); + +let expectedThis = function () { + return this; +}.call(undefined); + +let assertionCount = 0; +let result = iter.every(function (v, count) { + assert.sameValue(this, expectedThis); + ++assertionCount; + return true; +}); + +assert.sameValue(result, true); +assert.sameValue(assertionCount, 1); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/every/predicate-throws-then-closing-iterator-also-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/every/predicate-throws-then-closing-iterator-also-throws.js new file mode 100644 index 000000000000..9f149cae37a1 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/every/predicate-throws-then-closing-iterator-also-throws.js @@ -0,0 +1,39 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.every +description: > + Attempts to close iterator when predicate throws, but that throws +info: | + %Iterator.prototype%.every ( predicate ) + + 4.d. Let result be Completion(Call(predicate, undefined, « value, 𝔽(counter) »)). + 4.e. IfAbruptCloseIterator(result, iterated). + +features: [iterator-helpers] +flags: [] +---*/ +let returnCalls = 0; + +class TestIterator extends Iterator { + next() { + return { + done: false, + value: 1, + }; + } + return() { + ++returnCalls; + throw new Error(); + } +} + +let iterator = new TestIterator(); + +assert.throws(Test262Error, function () { + iterator.every(() => { + throw new Test262Error(); + }); +}); + +assert.sameValue(returnCalls, 1); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/every/predicate-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/every/predicate-throws.js new file mode 100644 index 000000000000..c99c983314bb --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/every/predicate-throws.js @@ -0,0 +1,43 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.every +description: > + Closes iterator and throws when predicate throws +info: | + %Iterator.prototype%.every ( predicate ) + + 4.d. Let result be Completion(Call(predicate, undefined, « value, 𝔽(counter) »)). + 4.e. IfAbruptCloseIterator(result, iterated). + +features: [iterator-helpers] +flags: [] +---*/ +let returnCalls = 0; + +class TestIterator extends Iterator { + next() { + return { + done: false, + value: 1, + }; + } + return() { + ++returnCalls; + return {}; + } +} + +let iterator = new TestIterator(); + +let callbackCalls = 0; + +assert.throws(Test262Error, function () { + iterator.every(() => { + ++callbackCalls; + throw new Test262Error(); + }); +}); + +assert.sameValue(callbackCalls, 1); +assert.sameValue(returnCalls, 1); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/every/prop-desc.js b/JSTests/test262/test/built-ins/Iterator/prototype/every/prop-desc.js new file mode 100644 index 000000000000..fe365a87a27e --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/every/prop-desc.js @@ -0,0 +1,25 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.every +description: > + Property descriptor of Iterator.prototype.every +info: | + Iterator.prototype.every + + * is the initial value of the Iterator.prototype.every property of the global object. + + 17 ECMAScript Standard Built-in Objects + + Every other data property described in clauses 18 through 26 and in Annex B.2 + has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +features: [globalThis, iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Iterator.prototype, 'every', { + writable: true, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/every/proto.js b/JSTests/test262/test/built-ins/Iterator/prototype/every/proto.js new file mode 100644 index 000000000000..be8c22cb3b32 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/every/proto.js @@ -0,0 +1,11 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.every +description: > + The value of the [[Prototype]] internal slot of Iterator.prototype.every is the + intrinsic object %Function%. +features: [iterator-helpers] +---*/ + +assert.sameValue(Object.getPrototypeOf(Iterator.prototype.every), Function.prototype); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/every/result-is-boolean.js b/JSTests/test262/test/built-ins/Iterator/prototype/every/result-is-boolean.js new file mode 100644 index 000000000000..9d19ac672d87 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/every/result-is-boolean.js @@ -0,0 +1,11 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.every +description: > + Iterator.prototype.every returns a boolean +features: [iterator-helpers] +---*/ +function* g() {} +let iter = g(); +assert.sameValue(typeof iter.every(() => {}), 'boolean'); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/every/this-non-callable-next.js b/JSTests/test262/test/built-ins/Iterator/prototype/every/this-non-callable-next.js new file mode 100644 index 000000000000..7c9d792cd348 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/every/this-non-callable-next.js @@ -0,0 +1,17 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.every +description: > + Iterator.prototype.every throws TypeError when its this value is an object with a non-callable next +info: | + %Iterator.prototype%.every ( predicate ) + + 1. Let iterated be ? GetIteratorDirect(this value). + +features: [iterator-helpers] +flags: [] +---*/ +assert.throws(TypeError, function () { + Iterator.prototype.every.call({ next: 0 }, () => true); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/every/this-non-object.js b/JSTests/test262/test/built-ins/Iterator/prototype/every/this-non-object.js new file mode 100644 index 000000000000..c8d895307134 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/every/this-non-object.js @@ -0,0 +1,26 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.every +description: > + Iterator.prototype.every throws TypeError when its this value is a non-object +info: | + %Iterator.prototype%.every ( predicate ) + + 1. Let iterated be ? GetIteratorDirect(this value). + +features: [iterator-helpers] +flags: [] +---*/ +assert.throws(TypeError, function () { + Iterator.prototype.every.call(null, () => {}); +}); + +Object.defineProperty(Number.prototype, 'next', { + get: function () { + throw new Test262Error(); + }, +}); +assert.throws(TypeError, function () { + Iterator.prototype.every.call(0, () => {}); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/every/this-plain-iterator.js b/JSTests/test262/test/built-ins/Iterator/prototype/every/this-plain-iterator.js new file mode 100644 index 000000000000..bf3ba73da65e --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/every/this-plain-iterator.js @@ -0,0 +1,32 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.every +description: > + Iterator.prototype.every supports a this value that does not inherit from Iterator.prototype but implements the iterator protocol +info: | + %Iterator.prototype%.every ( predicate ) + + 1. Let iterated be ? GetIteratorDirect(this value). + +features: [iterator-helpers] +flags: [] +---*/ +let iter = { + get next() { + let count = 3; + return function () { + --count; + return count >= 0 ? { done: false, value: count } : { done: true, value: undefined }; + }; + }, +}; + +let predicateCalls = 0; +let result = Iterator.prototype.every.call(iter, function (v) { + ++predicateCalls; + return v; +}); + +assert.sameValue(result, false); +assert.sameValue(predicateCalls, 3); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/filter/argument-effect-order.js b/JSTests/test262/test/built-ins/Iterator/prototype/filter/argument-effect-order.js new file mode 100644 index 000000000000..66b390806bf1 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/filter/argument-effect-order.js @@ -0,0 +1,30 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.filter +description: > + Arguments and this value are evaluated in the correct order +info: | + %Iterator.prototype%.filter ( predicate ) + +includes: [compareArray.js] +features: [iterator-helpers] +flags: [] +---*/ +let effects = []; + +assert.throws(TypeError, function () { + Iterator.prototype.filter.call( + { + get next() { + effects.push('get next'); + return function () { + return { done: true, value: undefined }; + }; + }, + }, + null + ); +}); + +assert.compareArray(effects, []); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/filter/callable.js b/JSTests/test262/test/built-ins/Iterator/prototype/filter/callable.js new file mode 100644 index 000000000000..c27e2fb450b6 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/filter/callable.js @@ -0,0 +1,13 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.filter +description: > + Iterator.prototype.filter is callable +features: [iterator-helpers] +---*/ +function* g() {} +Iterator.prototype.filter.call(g(), () => false); + +let iter = g(); +iter.filter(() => false); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/filter/exhaustion-does-not-call-return.js b/JSTests/test262/test/built-ins/Iterator/prototype/filter/exhaustion-does-not-call-return.js new file mode 100644 index 000000000000..7176212a1625 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/filter/exhaustion-does-not-call-return.js @@ -0,0 +1,37 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.filter +description: > + Underlying iterator return is not called when result iterator is exhausted +info: | + %Iterator.prototype%.filter ( predicate ) + + 3.b.i. Let next be ? IteratorStep(iterated). + 3.b.ii. If next is false, return undefined. + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + yield 0; + yield 1; + yield 2; +} + +class TestIterator extends Iterator { + get next() { + let n = g(); + return function() { + return n.next(); + }; + } + return() { + throw new Test262Error(); + } +} + +let iterator = new TestIterator().filter(() => false); +iterator.next(); +iterator.next(); +iterator.next(); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/filter/get-next-method-only-once.js b/JSTests/test262/test/built-ins/Iterator/prototype/filter/get-next-method-only-once.js new file mode 100644 index 000000000000..fc7a957a414a --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/filter/get-next-method-only-once.js @@ -0,0 +1,41 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.filter +description: > + Gets the next method from the underlying iterator only once +info: | + %Iterator.prototype%.filter ( predicate ) + + 1. Let iterated be ? GetIteratorDirect(this value). + +features: [iterator-helpers] +flags: [] +---*/ +let nextGets = 0; +let nextCalls = 0; + +class CountingIterator extends Iterator { + get next() { + ++nextGets; + let iter = (function* () { + for (let i = 1; i < 5; ++i) { + yield i; + } + })(); + return function () { + ++nextCalls; + return iter.next(); + }; + } +} + +let iterator = new CountingIterator(); + +assert.sameValue(nextGets, 0); +assert.sameValue(nextCalls, 0); + +for (const value of iterator.filter(() => false)); + +assert.sameValue(nextGets, 1); +assert.sameValue(nextCalls, 5); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/filter/get-next-method-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/filter/get-next-method-throws.js new file mode 100644 index 000000000000..4b411d3239a6 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/filter/get-next-method-throws.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.filter +description: > + Underlying iterator has throwing next getter +info: | + %Iterator.prototype%.filter ( predicate ) + + 1. Let iterated be ? GetIteratorDirect(this value). + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + get next() { + throw new Test262Error(); + } +} + +let iterator = new ThrowingIterator(); + +assert.throws(Test262Error, function () { + iterator.filter(() => false); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/filter/get-return-method-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/filter/get-return-method-throws.js new file mode 100644 index 000000000000..30831e5cd1aa --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/filter/get-return-method-throws.js @@ -0,0 +1,30 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.filter +description: > + Underlying iterator return is throwing getter +info: | + %Iterator.prototype%.filter ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +class TestIterator extends Iterator { + next() { + return { + done: false, + value: 1, + }; + } + get return() { + throw new Test262Error(); + } +} + +let iterator = new TestIterator().filter(() => true); +iterator.next(); + +assert.throws(Test262Error, function () { + iterator.return(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/filter/is-function.js b/JSTests/test262/test/built-ins/Iterator/prototype/filter/is-function.js new file mode 100644 index 000000000000..f43e683c37b8 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/filter/is-function.js @@ -0,0 +1,10 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.filter +description: > + Iterator.prototype.filter is a built-in function +features: [iterator-helpers] +---*/ + +assert.sameValue(typeof Iterator.prototype.filter, 'function'); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/filter/iterator-already-exhausted.js b/JSTests/test262/test/built-ins/Iterator/prototype/filter/iterator-already-exhausted.js new file mode 100644 index 000000000000..ddb4ba65f94e --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/filter/iterator-already-exhausted.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.filter +description: > + Iterator.prototype.filter returns an empty iterator when the iterator has already been exhausted +info: | + %Iterator.prototype%.filter ( predicate ) + + 3.b.i. Let next be ? IteratorStep(iterated). + 3.b.ii. If next is false, return undefined. + +features: [iterator-helpers] +flags: [] +---*/ +let iterator = (function* () {})(); + +let { value, done } = iterator.next(); +assert.sameValue(value, undefined); +assert.sameValue(done, true); + +iterator = iterator.filter(() => true); +({ value, done } = iterator.next()); +assert.sameValue(value, undefined); +assert.sameValue(done, true); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/filter/iterator-return-method-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/filter/iterator-return-method-throws.js new file mode 100644 index 000000000000..a1d74c2c1b97 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/filter/iterator-return-method-throws.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.filter +description: > + Iterator has throwing return +info: | + %Iterator.prototype%.filter ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +class IteratorThrows extends Iterator { + next() { + return { + done: false, + value: 0, + }; + } + return() { + throw new Test262Error(); + } +} + +let iterator = new IteratorThrows().filter(() => false); + +assert.throws(Test262Error, function () { + iterator.return(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/filter/length.js b/JSTests/test262/test/built-ins/Iterator/prototype/filter/length.js new file mode 100644 index 000000000000..7ae2f45278f5 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/filter/length.js @@ -0,0 +1,22 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.filter +description: > + Iterator.prototype.filter has a "length" property whose value is 1. +info: | + ECMAScript Standard Built-in Objects + + Unless otherwise specified, the length property of a built-in + Function object has the attributes { [[Writable]]: false, [[Enumerable]]: + false, [[Configurable]]: true }. +features: [iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Iterator.prototype.filter, 'length', { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/filter/name.js b/JSTests/test262/test/built-ins/Iterator/prototype/filter/name.js new file mode 100644 index 000000000000..3e556d4f767c --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/filter/name.js @@ -0,0 +1,29 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.filter +description: > + The "name" property of Iterator.prototype.filter +info: | + 17 ECMAScript Standard Built-in Objects + + Every built-in Function object, including constructors, that is not + identified as an anonymous function has a name property whose value is a + String. Unless otherwise specified, this value is the name that is given to + the function in this specification. + + ... + + Unless otherwise specified, the name property of a built-in Function + object, if it exists, has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +features: [iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Iterator.prototype.filter, 'name', { + value: 'filter', + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/filter/next-method-returns-non-object.js b/JSTests/test262/test/built-ins/Iterator/prototype/filter/next-method-returns-non-object.js new file mode 100644 index 000000000000..06e154363a9e --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/filter/next-method-returns-non-object.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.filter +description: > + Underlying iterator next returns non-object +info: | + %Iterator.prototype%.filter ( predicate ) + + 3.b.i. Let next be ? IteratorStep(iterated). + +features: [iterator-helpers] +flags: [] +---*/ +class NonObjectIterator extends Iterator { + next() { + return null; + } +} + +let iterator = new NonObjectIterator().filter(() => true); + +assert.throws(TypeError, function () { + iterator.next(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/filter/next-method-returns-throwing-done.js b/JSTests/test262/test/built-ins/Iterator/prototype/filter/next-method-returns-throwing-done.js new file mode 100644 index 000000000000..e0ea4d820f81 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/filter/next-method-returns-throwing-done.js @@ -0,0 +1,33 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.filter +description: > + Underlying iterator next returns object with throwing done getter +info: | + %Iterator.prototype%.filter ( predicate ) + + 3.b.i. Let next be ? IteratorStep(iterated). + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + return { + get done() { + throw new Test262Error(); + }, + value: 1, + }; + } + return() { + throw new Error(); + } +} + +let iterator = new ThrowingIterator().filter(() => true); + +assert.throws(Test262Error, function () { + iterator.next(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/filter/next-method-returns-throwing-value-done.js b/JSTests/test262/test/built-ins/Iterator/prototype/filter/next-method-returns-throwing-value-done.js new file mode 100644 index 000000000000..1f7c325d772d --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/filter/next-method-returns-throwing-value-done.js @@ -0,0 +1,30 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.filter +description: > + Underlying iterator next returns object with throwing value getter, but is already done +info: | + %Iterator.prototype%.filter ( predicate ) + + 3.b.ii. If next is false, return undefined. + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + return { + done: true, + get value() { + throw new Test262Error(); + }, + }; + } + return() { + throw new Error(); + } +} + +let iterator = new ThrowingIterator().filter(() => true); +iterator.next(); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/filter/next-method-returns-throwing-value.js b/JSTests/test262/test/built-ins/Iterator/prototype/filter/next-method-returns-throwing-value.js new file mode 100644 index 000000000000..11e67ee5e223 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/filter/next-method-returns-throwing-value.js @@ -0,0 +1,33 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.filter +description: > + Underlying iterator next returns object with throwing value getter +info: | + %Iterator.prototype%.filter ( predicate ) + + 3.b.iii. Let value be ? IteratorValue(next). + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + return { + done: false, + get value() { + throw new Test262Error(); + }, + }; + } + return() { + throw new Error(); + } +} + +let iterator = new ThrowingIterator().filter(() => true); + +assert.throws(Test262Error, function () { + iterator.next(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/filter/next-method-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/filter/next-method-throws.js new file mode 100644 index 000000000000..b114cf1d97a9 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/filter/next-method-throws.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.filter +description: > + Underlying iterator has throwing next method +info: | + %Iterator.prototype%.filter ( predicate ) + + 3.b.i. Let next be ? IteratorStep(iterated). + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + throw new Test262Error(); + } +} + +let iterator = new ThrowingIterator().filter(() => true); + +assert.throws(Test262Error, function () { + iterator.next(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/filter/non-callable-predicate.js b/JSTests/test262/test/built-ins/Iterator/prototype/filter/non-callable-predicate.js new file mode 100644 index 000000000000..8bf18c5113b5 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/filter/non-callable-predicate.js @@ -0,0 +1,20 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.filter +description: > + Iterator.prototype.filter expects to be called with a callable argument. +info: | + %Iterator.prototype%.filter ( predicate ) + + 2. If IsCallable(predicate) is false, throw a TypeError exception. + +features: [iterator-helpers] +flags: [] +---*/ +let nonCallable = {}; +let iterator = (function* () {})(); + +assert.throws(TypeError, function () { + iterator.filter(nonCallable); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/filter/non-constructible.js b/JSTests/test262/test/built-ins/Iterator/prototype/filter/non-constructible.js new file mode 100644 index 000000000000..3f63331b4c18 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/filter/non-constructible.js @@ -0,0 +1,28 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.filter +description: > + Iterator.prototype.filter is not constructible. + + Built-in function objects that are not identified as constructors do not implement the [[Construct]] internal method unless otherwise specified in the description of a particular function. +features: [iterator-helpers] +---*/ +function* g() {} +let iter = g(); + +assert.throws(TypeError, () => { + new iter.filter(); +}); + +assert.throws(TypeError, () => { + new iter.filter(() => true); +}); + +assert.throws(TypeError, () => { + new Iterator.prototype.filter(() => true); +}); + +assert.throws(TypeError, () => { + new class extends Iterator {}.filter(() => true); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/filter/predicate-args.js b/JSTests/test262/test/built-ins/Iterator/prototype/filter/predicate-args.js new file mode 100644 index 000000000000..aefcf7c03fdd --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/filter/predicate-args.js @@ -0,0 +1,44 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.filter +description: > + Iterator.prototype.filter predicate is passed the yielded value and a counter as arguments +info: | + %Iterator.prototype%.filter ( predicate ) + + 3.b.iv. Let selected be Completion(Call(predicate, undefined, « value, 𝔽(counter) »)). + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + yield 'a'; + yield 'b'; + yield 'c'; +} + +let assertionCount = 0; +let iter = g().filter((v, count) => { + switch (v) { + case 'a': + assert.sameValue(count, 0); + break; + case 'b': + assert.sameValue(count, 1); + break; + case 'c': + assert.sameValue(count, 2); + break; + default: + throw new Error(); + } + ++assertionCount; + return true; +}); + +assert.sameValue(assertionCount, 0); + +for (let i of iter); + +assert.sameValue(assertionCount, 3); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/filter/predicate-filters.js b/JSTests/test262/test/built-ins/Iterator/prototype/filter/predicate-filters.js new file mode 100644 index 000000000000..8bef4428a99c --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/filter/predicate-filters.js @@ -0,0 +1,40 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.filter +description: > + Iterator.prototype.filter returns only items for which the predicate returned true. +info: | + %Iterator.prototype%.filter ( filterer ) + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + yield 1; + yield 0; + yield 2; + yield 0; + yield 3; + yield 0; + yield 4; +} + +let iterator = g(); + +let predicateCalls = 0; +iterator = iterator.filter(value => { + ++predicateCalls; + return value !== 0; +}); + +let resultCount = 0; +for (let value of iterator) { + ++resultCount; + assert.sameValue(value, resultCount); +} +assert.sameValue(resultCount, 4); + +let { value, done } = iterator.next(); +assert.sameValue(value, undefined); +assert.sameValue(done, true); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/filter/predicate-returns-non-boolean.js b/JSTests/test262/test/built-ins/Iterator/prototype/filter/predicate-returns-non-boolean.js new file mode 100644 index 000000000000..7ec64e314f10 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/filter/predicate-returns-non-boolean.js @@ -0,0 +1,38 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.filter +description: > + Iterator.prototype.filter coerces predicate return value to boolean +info: | + %Iterator.prototype%.filter ( predicate ) + + 3.b.vi. If ToBoolean(selected) is true, then + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + yield 0; + yield 0; + yield 0; + yield 1; +} + +let iter = g(); + +let predicateCalls = 0; +iter = iter.filter(v => { + ++predicateCalls; + return v; +}); + +assert.sameValue(predicateCalls, 0); + +iter.next(); + +assert.sameValue(predicateCalls, 4); + +iter.next(); + +assert.sameValue(predicateCalls, 4); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/filter/predicate-this.js b/JSTests/test262/test/built-ins/Iterator/prototype/filter/predicate-this.js new file mode 100644 index 000000000000..4d8d8ba014af --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/filter/predicate-this.js @@ -0,0 +1,33 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.filter +description: > + Iterator.prototype.filter predicate this value is undefined +info: | + %Iterator.prototype%.filter ( predicate ) + + 3.b.iv. Let selected be Completion(Call(predicate, undefined, « value, 𝔽(counter) »)). + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + yield 0; +} + +let iter = g(); + +let expectedThis = function () { + return this; +}.call(undefined); + +let assertionCount = 0; +iter = iter.filter(function (v, count) { + assert.sameValue(this, expectedThis); + ++assertionCount; + return true; +}); + +iter.next(); +assert.sameValue(assertionCount, 1); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/filter/predicate-throws-then-closing-iterator-also-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/filter/predicate-throws-then-closing-iterator-also-throws.js new file mode 100644 index 000000000000..ec033aba716e --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/filter/predicate-throws-then-closing-iterator-also-throws.js @@ -0,0 +1,40 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.filter +description: > + Attempts to close iterator when predicate throws, but that throws +info: | + %Iterator.prototype%.filter ( predicate ) + + 3.b.v. IfAbruptCloseIterator(selected, iterated). + +features: [iterator-helpers] +flags: [] +---*/ +let returnCalls = 0; + +class TestIterator extends Iterator { + next() { + return { + done: false, + value: 1, + }; + } + return() { + ++returnCalls; + throw new Error(); + } +} + +let iterator = new TestIterator().filter(() => { + throw new Test262Error(); +}); + +assert.sameValue(returnCalls, 0); + +assert.throws(Test262Error, function () { + iterator.next(); +}); + +assert.sameValue(returnCalls, 1); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/filter/predicate-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/filter/predicate-throws.js new file mode 100644 index 000000000000..63bba837ebc0 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/filter/predicate-throws.js @@ -0,0 +1,41 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.filter +description: > + Closes iterator and throws when predicate throws +info: | + %Iterator.prototype%.filter ( predicate ) + + 3.b.v. IfAbruptCloseIterator(selected, iterated). + +features: [iterator-helpers] +flags: [] +---*/ +let returnCalls = 0; + +class TestIterator extends Iterator { + next() { + return { + done: false, + value: 1, + }; + } + return() { + ++returnCalls; + return {}; + } +} + +let callbackCalls = 0; +let iterator = new TestIterator().filter(() => { + ++callbackCalls; + throw new Test262Error(); +}); + +assert.throws(Test262Error, function () { + iterator.next(); +}); + +assert.sameValue(callbackCalls, 1); +assert.sameValue(returnCalls, 1); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/filter/prop-desc.js b/JSTests/test262/test/built-ins/Iterator/prototype/filter/prop-desc.js new file mode 100644 index 000000000000..8f9d9dbab854 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/filter/prop-desc.js @@ -0,0 +1,25 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.filter +description: > + Property descriptor of Iterator.prototype.filter +info: | + Iterator.prototype.filter + + * is the initial value of the Iterator.prototype.filter property of the global object. + + 17 ECMAScript Standard Built-in Objects + + Every other data property described in clauses 18 through 26 and in Annex B.2 + has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +features: [globalThis, iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Iterator.prototype, 'filter', { + writable: true, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/filter/proto.js b/JSTests/test262/test/built-ins/Iterator/prototype/filter/proto.js new file mode 100644 index 000000000000..f496d487bc8b --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/filter/proto.js @@ -0,0 +1,11 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.filter +description: > + The value of the [[Prototype]] internal slot of Iterator.prototype.filter is the + intrinsic object %FunctionPrototype%. +features: [iterator-helpers] +---*/ + +assert.sameValue(Object.getPrototypeOf(Iterator.prototype.filter), Function.prototype); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/filter/result-is-iterator.js b/JSTests/test262/test/built-ins/Iterator/prototype/filter/result-is-iterator.js new file mode 100644 index 000000000000..462afb585a2f --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/filter/result-is-iterator.js @@ -0,0 +1,14 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.filter +description: > + The value of the [[Prototype]] internal slot of the return value of Iterator.prototype.filter is the + intrinsic object %IteratorHelperPrototype%. +features: [iterator-helpers] +---*/ + +assert( + (function* () {})().filter(() => true) instanceof Iterator, + 'function*(){}().filter(() => true) must return an Iterator' +); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/filter/return-is-forwarded.js b/JSTests/test262/test/built-ins/Iterator/prototype/filter/return-is-forwarded.js new file mode 100644 index 000000000000..0a6efad3c45c --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/filter/return-is-forwarded.js @@ -0,0 +1,33 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.filter +description: > + Underlying iterator return is called when result iterator is closed +info: | + %Iterator.prototype%.filter ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +let returnCount = 0; + +class TestIterator extends Iterator { + next() { + return { + done: false, + value: 1, + }; + } + return() { + ++returnCount; + return {}; + } +} + +let iterator = new TestIterator().filter(() => false); +assert.sameValue(returnCount, 0); +iterator.return(); +assert.sameValue(returnCount, 1); +iterator.return(); +assert.sameValue(returnCount, 1); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/filter/return-is-not-forwarded-after-exhaustion.js b/JSTests/test262/test/built-ins/Iterator/prototype/filter/return-is-not-forwarded-after-exhaustion.js new file mode 100644 index 000000000000..196f903fa6bb --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/filter/return-is-not-forwarded-after-exhaustion.js @@ -0,0 +1,46 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.filter +description: > + Underlying iterator return is not called after result iterator observes that underlying iterator is exhausted +info: | + %Iterator.prototype%.filter ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +let returnCount = 0; + +class TestIterator extends Iterator { + next() { + return { + done: true, + value: undefined, + }; + } + return() { + throw new Test262Error(); + } +} + +let iterator = new TestIterator().filter(() => true); +assert.throws(Test262Error, function () { + iterator.return(); +}); +iterator.next(); +iterator.return(); + +iterator = new TestIterator().filter(() => true); +iterator.next(); +iterator.return(); + +iterator = new TestIterator() + .filter(() => true) + .filter(() => true) + .filter(() => true); +assert.throws(Test262Error, function () { + iterator.return(); +}); +iterator.next(); +iterator.return(); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/filter/this-non-callable-next.js b/JSTests/test262/test/built-ins/Iterator/prototype/filter/this-non-callable-next.js new file mode 100644 index 000000000000..bd43672c5c7e --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/filter/this-non-callable-next.js @@ -0,0 +1,19 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.filter +description: > + Iterator.prototype.filter throws TypeError when its this value is an object with a non-callable next +info: | + %Iterator.prototype%.filter ( predicate ) + + 1. Let iterated be ? GetIteratorDirect(this value). + +features: [iterator-helpers] +flags: [] +---*/ +let iter = Iterator.prototype.filter.call({ next: 0 }, () => true); + +assert.throws(TypeError, function () { + iter.next(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/filter/this-non-object.js b/JSTests/test262/test/built-ins/Iterator/prototype/filter/this-non-object.js new file mode 100644 index 000000000000..3a48b97608fe --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/filter/this-non-object.js @@ -0,0 +1,26 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.filter +description: > + Iterator.prototype.filter throws TypeError when its this value is a non-object +info: | + %Iterator.prototype%.filter ( predicate ) + + 1. Let iterated be ? GetIteratorDirect(this value). + +features: [iterator-helpers] +flags: [] +---*/ +assert.throws(TypeError, function () { + Iterator.prototype.filter.call(null, () => true); +}); + +Object.defineProperty(Number.prototype, 'next', { + get: function () { + throw new Test262Error(); + }, +}); +assert.throws(TypeError, function () { + Iterator.prototype.filter.call(0, () => true); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/filter/this-plain-iterator.js b/JSTests/test262/test/built-ins/Iterator/prototype/filter/this-plain-iterator.js new file mode 100644 index 000000000000..2bddfe1b76ae --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/filter/this-plain-iterator.js @@ -0,0 +1,33 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.filter +description: > + Iterator.prototype.filter supports a this value that does not inherit from Iterator.prototype but implements the iterator protocol +info: | + %Iterator.prototype%.filter ( predicate ) + + 1. Let iterated be ? GetIteratorDirect(this value). + +features: [iterator-helpers] +flags: [] +---*/ +let iter = { + get next() { + let count = 3; + return function () { + --count; + return count >= 0 ? { done: false, value: count } : { done: true, value: undefined }; + }; + }, +}; + +let predicateCalls = 0; +iter = Iterator.prototype.filter.call(iter, function (v) { + ++predicateCalls; + return v; +}); + +for (let e of iter); + +assert.sameValue(predicateCalls, 3); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/filter/underlying-iterator-advanced-in-parallel.js b/JSTests/test262/test/built-ins/Iterator/prototype/filter/underlying-iterator-advanced-in-parallel.js new file mode 100644 index 000000000000..4ff2b6f6233d --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/filter/underlying-iterator-advanced-in-parallel.js @@ -0,0 +1,42 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.filter +description: > + Underlying iterator is advanced after calling filter +info: | + %Iterator.prototype%.filter ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +let iterator = (function* () { + for (let i = 0; i < 5; ++i) { + yield i; + } +})(); + +let filtered = iterator.filter(() => true); + +let { value, done } = iterator.next(); + +assert.sameValue(value, 0); +assert.sameValue(done, false); + +iterator.next(); +iterator.next(); + +({ value, done } = filtered.next()); + +assert.sameValue(value, 3); +assert.sameValue(done, false); + +({ value, done } = filtered.next()); + +assert.sameValue(value, 4); +assert.sameValue(done, false); + +({ value, done } = filtered.next()); + +assert.sameValue(value, undefined); +assert.sameValue(done, true); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/filter/underlying-iterator-closed-in-parallel.js b/JSTests/test262/test/built-ins/Iterator/prototype/filter/underlying-iterator-closed-in-parallel.js new file mode 100644 index 000000000000..2888553c70d7 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/filter/underlying-iterator-closed-in-parallel.js @@ -0,0 +1,26 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.filter +description: > + Underlying iterator is closed after calling filter +info: | + %Iterator.prototype%.filter ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +let iterator = (function* () { + for (let i = 0; i < 5; ++i) { + yield i; + } +})(); + +let filtered = iterator.filter(() => true); + +iterator.return(); + +let { value, done } = filtered.next(); + +assert.sameValue(value, undefined); +assert.sameValue(done, true); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/filter/underlying-iterator-closed.js b/JSTests/test262/test/built-ins/Iterator/prototype/filter/underlying-iterator-closed.js new file mode 100644 index 000000000000..92de4e3d7981 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/filter/underlying-iterator-closed.js @@ -0,0 +1,26 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.filter +description: > + Underlying iterator is closed before calling filter +info: | + %Iterator.prototype%.filter ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +let iterator = (function* () { + for (let i = 0; i < 5; ++i) { + yield i; + } +})(); + +iterator.return(); + +let filtered = iterator.filter(() => true); + +let { value, done } = filtered.next(); + +assert.sameValue(value, undefined); +assert.sameValue(done, true); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/find/argument-effect-order.js b/JSTests/test262/test/built-ins/Iterator/prototype/find/argument-effect-order.js new file mode 100644 index 000000000000..3651081f73aa --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/find/argument-effect-order.js @@ -0,0 +1,30 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.find +description: > + Arguments and this value are evaluated in the correct order +info: | + %Iterator.prototype%.find ( predicate ) + +includes: [compareArray.js] +features: [iterator-helpers] +flags: [] +---*/ +let effects = []; + +assert.throws(TypeError, function () { + Iterator.prototype.find.call( + { + get next() { + effects.push('get next'); + return function () { + return { done: true, value: undefined }; + }; + }, + }, + null + ); +}); + +assert.compareArray(effects, []); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/find/callable.js b/JSTests/test262/test/built-ins/Iterator/prototype/find/callable.js new file mode 100644 index 000000000000..a7238402c76b --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/find/callable.js @@ -0,0 +1,13 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.find +description: > + Iterator.prototype.find is callable +features: [iterator-helpers] +---*/ +function* g() {} +Iterator.prototype.find.call(g(), () => {}); + +let iter = g(); +iter.find(() => {}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/find/get-next-method-only-once.js b/JSTests/test262/test/built-ins/Iterator/prototype/find/get-next-method-only-once.js new file mode 100644 index 000000000000..2851c3f5631b --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/find/get-next-method-only-once.js @@ -0,0 +1,36 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.find +description: > + Gets the next method from the iterator only once +info: | + %Iterator.prototype%.find ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +let nextGets = 0; + +class TestIterator extends Iterator { + get next() { + ++nextGets; + let counter = 5; + return function () { + if (counter < 0) { + return { done: true, value: undefined }; + } else { + return { done: false, value: --counter }; + } + }; + } +} + +let iterator = new TestIterator(); + +assert.sameValue(nextGets, 0); +assert.sameValue( + iterator.find(() => true), + 4 +); +assert.sameValue(nextGets, 1); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/find/get-next-method-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/find/get-next-method-throws.js new file mode 100644 index 000000000000..9f74b3135ad0 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/find/get-next-method-throws.js @@ -0,0 +1,23 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.find +description: > + Iterator has throwing next getter +info: | + %Iterator.prototype%.find ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +class IteratorThrows extends Iterator { + get next() { + throw new Test262Error(); + } +} + +let iterator = new IteratorThrows(); + +assert.throws(Test262Error, function () { + iterator.find(() => {}); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/find/get-return-method-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/find/get-return-method-throws.js new file mode 100644 index 000000000000..c50098651cf2 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/find/get-return-method-throws.js @@ -0,0 +1,29 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.find +description: > + Iterator has throwing return getter +info: | + %Iterator.prototype%.find ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +class IteratorThrows extends Iterator { + next() { + return { + done: false, + value: 0, + }; + } + get return() { + throw new Test262Error(); + } +} + +let iterator = new IteratorThrows([1, 2]); + +assert.throws(Test262Error, function () { + iterator.find(() => true); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/find/is-function.js b/JSTests/test262/test/built-ins/Iterator/prototype/find/is-function.js new file mode 100644 index 000000000000..146bdeec3a58 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/find/is-function.js @@ -0,0 +1,10 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.find +description: > + Iterator.prototype.find is a built-in function +features: [iterator-helpers] +---*/ + +assert.sameValue(typeof Iterator.prototype.find, 'function'); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/find/iterator-already-exhausted.js b/JSTests/test262/test/built-ins/Iterator/prototype/find/iterator-already-exhausted.js new file mode 100644 index 000000000000..ca383b24a675 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/find/iterator-already-exhausted.js @@ -0,0 +1,23 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.find +description: > + Iterator.prototype.find returns undefined when the iterator has already been exhausted +info: | + %Iterator.prototype%.find ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +let iterator = (function* () {})(); + +let { value, done } = iterator.next(); +assert.sameValue(value, undefined); +assert.sameValue(done, true); + +let result = iterator.find(() => true); +assert.sameValue(result, undefined); + +result = iterator.find(() => false); +assert.sameValue(result, undefined); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/find/iterator-has-no-return.js b/JSTests/test262/test/built-ins/Iterator/prototype/find/iterator-has-no-return.js new file mode 100644 index 000000000000..09862a2009b0 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/find/iterator-has-no-return.js @@ -0,0 +1,27 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.find +description: > + The underlying iterator is sometimes unable to be closed (has no return method) +info: | + %Iterator.prototype%.find ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +let iterator = [1, 2, 3, 4, 5][Symbol.iterator](); + +assert.sameValue(iterator.return, undefined); + +let ret = iterator.find(v => v > 3); + +assert.sameValue(ret, 4); + +let { done, value } = iterator.next(); +assert.sameValue(done, false); +assert.sameValue(value, 5); + +({ done, value } = iterator.next()); +assert.sameValue(done, true); +assert.sameValue(value, undefined); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/find/iterator-return-method-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/find/iterator-return-method-throws.js new file mode 100644 index 000000000000..9dc822570ab2 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/find/iterator-return-method-throws.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.find +description: > + Iterator has throwing return +info: | + %Iterator.prototype%.find ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +class IteratorThrows extends Iterator { + next() { + return { + done: false, + value: 0, + }; + } + return() { + throw new Test262Error(); + } +} + +let iterator = new IteratorThrows(); + +assert.throws(Test262Error, function () { + iterator.find(() => true); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/find/length.js b/JSTests/test262/test/built-ins/Iterator/prototype/find/length.js new file mode 100644 index 000000000000..e7d50f06377f --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/find/length.js @@ -0,0 +1,22 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.find +description: > + Iterator.prototype.find has a "length" property whose value is 1. +info: | + ECMAScript Standard Built-in Objects + + Unless otherwise specified, the length property of a built-in + Function object has the attributes { [[Writable]]: false, [[Enumerable]]: + false, [[Configurable]]: true }. +features: [iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Iterator.prototype.find, 'length', { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/find/name.js b/JSTests/test262/test/built-ins/Iterator/prototype/find/name.js new file mode 100644 index 000000000000..4735b28c8394 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/find/name.js @@ -0,0 +1,29 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.find +description: > + The "name" property of Iterator.prototype.find +info: | + 17 ECMAScript Standard Built-in Objects + + Every built-in Function object, including constructors, that is not + identified as an anonymous function has a name property whose value is a + String. Unless otherwise specified, this value is the name that is given to + the function in this specification. + + ... + + Unless otherwise specified, the name property of a built-in Function + object, if it exists, has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +features: [iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Iterator.prototype.find, 'name', { + value: 'find', + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/find/next-method-returns-non-object.js b/JSTests/test262/test/built-ins/Iterator/prototype/find/next-method-returns-non-object.js new file mode 100644 index 000000000000..519c14a9621c --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/find/next-method-returns-non-object.js @@ -0,0 +1,23 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.find +description: > + Underlying iterator next returns non-object +info: | + %Iterator.prototype%.find ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +class NonObjectIterator extends Iterator { + next() { + return null; + } +} + +let iterator = new NonObjectIterator(); + +assert.throws(TypeError, function () { + iterator.find(() => {}); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/find/next-method-returns-throwing-done.js b/JSTests/test262/test/built-ins/Iterator/prototype/find/next-method-returns-throwing-done.js new file mode 100644 index 000000000000..9a3e0a7d859a --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/find/next-method-returns-throwing-done.js @@ -0,0 +1,31 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.find +description: > + Underlying iterator next returns object with throwing done getter +info: | + %Iterator.prototype%.find ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + return { + get done() { + throw new Test262Error(); + }, + value: 1, + }; + } + return() { + throw new Error(); + } +} + +let iterator = new ThrowingIterator(); + +assert.throws(Test262Error, function () { + iterator.find(() => {}); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/find/next-method-returns-throwing-value-done.js b/JSTests/test262/test/built-ins/Iterator/prototype/find/next-method-returns-throwing-value-done.js new file mode 100644 index 000000000000..a03849a8e2eb --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/find/next-method-returns-throwing-value-done.js @@ -0,0 +1,28 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.find +description: > + Underlying iterator next returns object with throwing value getter, but is already done +info: | + %Iterator.prototype%.find ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + return { + done: true, + get value() { + throw new Test262Error(); + }, + }; + } + return() { + throw new Error(); + } +} + +let iterator = new ThrowingIterator(); +iterator.find(() => {}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/find/next-method-returns-throwing-value.js b/JSTests/test262/test/built-ins/Iterator/prototype/find/next-method-returns-throwing-value.js new file mode 100644 index 000000000000..9453b8c08f4b --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/find/next-method-returns-throwing-value.js @@ -0,0 +1,31 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.find +description: > + Underlying iterator next returns object with throwing value getter +info: | + %Iterator.prototype%.find ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + return { + done: false, + get value() { + throw new Test262Error(); + }, + }; + } + return() { + throw new Error(); + } +} + +let iterator = new ThrowingIterator(); + +assert.throws(Test262Error, function () { + iterator.find(() => {}); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/find/next-method-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/find/next-method-throws.js new file mode 100644 index 000000000000..3a658321fd7b --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/find/next-method-throws.js @@ -0,0 +1,23 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.find +description: > + Underlying iterator has throwing next method +info: | + %Iterator.prototype%.find ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + throw new Test262Error(); + } +} + +let iterator = new ThrowingIterator(); + +assert.throws(Test262Error, function () { + iterator.find(() => {}); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/find/non-callable-predicate.js b/JSTests/test262/test/built-ins/Iterator/prototype/find/non-callable-predicate.js new file mode 100644 index 000000000000..a2aa43c147d2 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/find/non-callable-predicate.js @@ -0,0 +1,20 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.find +description: > + Iterator.prototype.find expects to be called with a callable argument. +info: | + %Iterator.prototype%.find ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +let nonCallable = {}; +let iterator = (function* () { + yield 1; +})(); + +assert.throws(TypeError, function () { + iterator.find(nonCallable); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/find/non-constructible.js b/JSTests/test262/test/built-ins/Iterator/prototype/find/non-constructible.js new file mode 100644 index 000000000000..df0eef60c95c --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/find/non-constructible.js @@ -0,0 +1,28 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.find +description: > + Iterator.prototype.find is not constructible. + + Built-in function objects that are not identified as constructors do not implement the [[Construct]] internal method unless otherwise specified in the description of a particular function. +features: [iterator-helpers] +---*/ +function* g() {} +let iter = g(); + +assert.throws(TypeError, () => { + new iter.find(); +}); + +assert.throws(TypeError, () => { + new iter.find(() => {}); +}); + +assert.throws(TypeError, () => { + new Iterator.prototype.find(() => {}); +}); + +assert.throws(TypeError, () => { + new class extends Iterator {}.find(() => {}); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/find/predicate-args.js b/JSTests/test262/test/built-ins/Iterator/prototype/find/predicate-args.js new file mode 100644 index 000000000000..75a584874c6b --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/find/predicate-args.js @@ -0,0 +1,41 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.find +description: > + Iterator.prototype.find predicate is passed the yielded value and a counter as arguments +info: | + %Iterator.prototype%.find ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + yield 'a'; + yield 'b'; + yield 'c'; +} + +let iter = g(); + +let assertionCount = 0; +let result = iter.find((v, count) => { + switch (v) { + case 'a': + assert.sameValue(count, 0); + break; + case 'b': + assert.sameValue(count, 1); + break; + case 'c': + assert.sameValue(count, 2); + break; + default: + throw new Error(); + } + ++assertionCount; + return false; +}); + +assert.sameValue(result, undefined); +assert.sameValue(assertionCount, 3); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/find/predicate-returns-falsey-then-truthy.js b/JSTests/test262/test/built-ins/Iterator/prototype/find/predicate-returns-falsey-then-truthy.js new file mode 100644 index 000000000000..2732fba78980 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/find/predicate-returns-falsey-then-truthy.js @@ -0,0 +1,32 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.find +description: > + Iterator.prototype.find returns the found value and closes the iterator when the predicate returns falsey for some iterated values and truthy for others +info: | + %Iterator.prototype%.find ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + for (let i = 0; i < 5; ++i) { + yield i; + } +} + +let iter = g(); + +let predicateCalls = 0; +let result = iter.find(v => { + ++predicateCalls; + return v > 2; +}); + +assert.sameValue(result, 3); +assert.sameValue(predicateCalls, 4); + +let { done, value } = iter.next(); +assert.sameValue(done, true); +assert.sameValue(value, undefined); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/find/predicate-returns-falsey.js b/JSTests/test262/test/built-ins/Iterator/prototype/find/predicate-returns-falsey.js new file mode 100644 index 000000000000..11d353b14ca0 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/find/predicate-returns-falsey.js @@ -0,0 +1,21 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.find +description: > + Iterator.prototype.find returns undefined when the predicate returns falsey for all iterated values +info: | + %Iterator.prototype%.find ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + yield 0; + yield 1; + yield 2; + yield 3; +} + +let result = g().find(() => false); +assert.sameValue(result, undefined); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/find/predicate-returns-non-boolean.js b/JSTests/test262/test/built-ins/Iterator/prototype/find/predicate-returns-non-boolean.js new file mode 100644 index 000000000000..136fb4e83b34 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/find/predicate-returns-non-boolean.js @@ -0,0 +1,32 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.find +description: > + Iterator.prototype.find coerces predicate return value to boolean +info: | + %Iterator.prototype%.find ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + yield ''; + yield null; + yield undefined; + yield 0; + yield 1; + yield 2; + yield 3; +} + +let iter = g(); + +let predicateCalls = 0; +let result = iter.find(v => { + ++predicateCalls; + return v; +}); + +assert.sameValue(result, 1); +assert.sameValue(predicateCalls, 5); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/find/predicate-returns-truthy.js b/JSTests/test262/test/built-ins/Iterator/prototype/find/predicate-returns-truthy.js new file mode 100644 index 000000000000..a265869f42be --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/find/predicate-returns-truthy.js @@ -0,0 +1,32 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.find +description: > + Iterator.prototype.find returns the found value and closes the iterator when the predicate returns truthy immediately +info: | + %Iterator.prototype%.find ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + yield 0; + yield 1; + yield 2; +} + +let iter = g(); + +let predicateCalls = 0; +let result = iter.find(v => { + ++predicateCalls; + return true; +}); + +assert.sameValue(result, 0); +assert.sameValue(predicateCalls, 1); + +let { done, value } = iter.next(); +assert.sameValue(done, true); +assert.sameValue(value, undefined); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/find/predicate-this.js b/JSTests/test262/test/built-ins/Iterator/prototype/find/predicate-this.js new file mode 100644 index 000000000000..84452f53696c --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/find/predicate-this.js @@ -0,0 +1,31 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.find +description: > + Iterator.prototype.find predicate this value is undefined +info: | + %Iterator.prototype%.find ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + yield 0; +} + +let iter = g(); + +let expectedThis = function () { + return this; +}.call(undefined); + +let assertionCount = 0; +let result = iter.find(function (v, count) { + assert.sameValue(this, expectedThis); + ++assertionCount; + return true; +}); + +assert.sameValue(result, 0); +assert.sameValue(assertionCount, 1); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/find/predicate-throws-then-closing-iterator-also-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/find/predicate-throws-then-closing-iterator-also-throws.js new file mode 100644 index 000000000000..f070e00dd7ba --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/find/predicate-throws-then-closing-iterator-also-throws.js @@ -0,0 +1,36 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.find +description: > + Attempts to close iterator when predicate throws, but that throws +info: | + %Iterator.prototype%.find ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +let returnCalls = 0; + +class TestIterator extends Iterator { + next() { + return { + done: false, + value: 1, + }; + } + return() { + ++returnCalls; + throw new Error(); + } +} + +let iterator = new TestIterator(); + +assert.throws(Test262Error, function () { + iterator.find(() => { + throw new Test262Error(); + }); +}); + +assert.sameValue(returnCalls, 1); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/find/predicate-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/find/predicate-throws.js new file mode 100644 index 000000000000..c031e43be8a2 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/find/predicate-throws.js @@ -0,0 +1,40 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.find +description: > + Closes iterator and throws when predicate throws +info: | + %Iterator.prototype%.find ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +let returnCalls = 0; + +class TestIterator extends Iterator { + next() { + return { + done: false, + value: 1, + }; + } + return() { + ++returnCalls; + return {}; + } +} + +let iterator = new TestIterator(); + +let callbackCalls = 0; + +assert.throws(Test262Error, function () { + iterator.find(() => { + ++callbackCalls; + throw new Test262Error(); + }); +}); + +assert.sameValue(callbackCalls, 1); +assert.sameValue(returnCalls, 1); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/find/prop-desc.js b/JSTests/test262/test/built-ins/Iterator/prototype/find/prop-desc.js new file mode 100644 index 000000000000..c38c9508ea2f --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/find/prop-desc.js @@ -0,0 +1,25 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.find +description: > + Property descriptor of Iterator.prototype.find +info: | + Iterator.prototype.find + + * is the initial value of the Iterator.prototype.find property of the global object. + + 17 ECMAScript Standard Built-in Objects + + every other data property described in clauses 18 through 26 and in Annex B.2 + has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +features: [globalThis, iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Iterator.prototype, 'find', { + writable: true, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/find/proto.js b/JSTests/test262/test/built-ins/Iterator/prototype/find/proto.js new file mode 100644 index 000000000000..0d9ca0095162 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/find/proto.js @@ -0,0 +1,11 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.find +description: > + The value of the [[Prototype]] internal slot of Iterator.prototype.find is the + intrinsic object %Function%. +features: [iterator-helpers] +---*/ + +assert.sameValue(Object.getPrototypeOf(Iterator.prototype.find), Function.prototype); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/find/this-non-callable-next.js b/JSTests/test262/test/built-ins/Iterator/prototype/find/this-non-callable-next.js new file mode 100644 index 000000000000..3168b25b793b --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/find/this-non-callable-next.js @@ -0,0 +1,15 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.find +description: > + Iterator.prototype.find throws TypeError when its this value is an object with a non-callable next +info: | + %Iterator.prototype%.find ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +assert.throws(TypeError, function () { + Iterator.prototype.find.call({ next: 0 }, () => true); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/find/this-non-object.js b/JSTests/test262/test/built-ins/Iterator/prototype/find/this-non-object.js new file mode 100644 index 000000000000..05b0c264c5ce --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/find/this-non-object.js @@ -0,0 +1,24 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.find +description: > + Iterator.prototype.find throws TypeError when its this value is a non-object +info: | + %Iterator.prototype%.find ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +assert.throws(TypeError, function () { + Iterator.prototype.find.call(null, () => {}); +}); + +Object.defineProperty(Number.prototype, 'next', { + get: function () { + throw new Test262Error(); + }, +}); +assert.throws(TypeError, function () { + Iterator.prototype.find.call(0, () => {}); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/find/this-plain-iterator.js b/JSTests/test262/test/built-ins/Iterator/prototype/find/this-plain-iterator.js new file mode 100644 index 000000000000..4461ad137c3e --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/find/this-plain-iterator.js @@ -0,0 +1,30 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.find +description: > + Iterator.prototype.find supports a this value that does not inherit from Iterator.prototype but implements the iterator protocol +info: | + %Iterator.prototype%.find ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +let iter = { + get next() { + let count = 3; + return function () { + --count; + return count >= 0 ? { done: false, value: count } : { done: true, value: undefined }; + }; + }, +}; + +let predicateCalls = 0; +let result = Iterator.prototype.find.call(iter, function (v) { + ++predicateCalls; + return v === 0; +}); + +assert.sameValue(result, 0); +assert.sameValue(predicateCalls, 3); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/argument-effect-order.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/argument-effect-order.js new file mode 100644 index 000000000000..4683a3024c0f --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/argument-effect-order.js @@ -0,0 +1,42 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Arguments and this value are evaluated in the correct order +info: | + %Iterator.prototype%.flatMap ( mapper ) + + 1. Let O be the this value. + 2. If O is not an Object, throw a TypeError exception. + 3. If IsCallable(mapper) is false, throw a TypeError exception. + 4. Let iterated be ? GetIteratorDirect(O). + +includes: [compareArray.js] +features: [iterator-helpers] +flags: [] +---*/ +let effects = []; + +assert.throws(TypeError, function () { + Iterator.prototype.flatMap.call( + { + get next() { + effects.push('get next'); + return function () { + return { done: true, value: undefined }; + }; + }, + }, + { + valueOf() { + effects.push('valueOf mapper'); + return function () { + return []; + }; + }, + } + ); +}); + +assert.compareArray(effects, []); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/callable.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/callable.js new file mode 100644 index 000000000000..0626011c7d50 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/callable.js @@ -0,0 +1,13 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Iterator.prototype.flatMap is callable +features: [iterator-helpers] +---*/ +function* g() {} +Iterator.prototype.flatMap.call(g(), () => []); + +let iter = g(); +iter.flatMap(() => []); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/exhaustion-does-not-call-return.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/exhaustion-does-not-call-return.js new file mode 100644 index 000000000000..a33ef7ed16d1 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/exhaustion-does-not-call-return.js @@ -0,0 +1,34 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Underlying iterator return is not called when result iterator is exhausted +info: | + %Iterator.prototype%.flatMap ( mapper ) + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + yield 0; + yield 1; + yield 2; +} + +class TestIterator extends Iterator { + get next() { + let n = g(); + return function() { + return n.next(); + }; + } + return() { + throw new Test262Error(); + } +} + +let iterator = new TestIterator().flatMap(() => []); +iterator.next(); +iterator.next(); +iterator.next(); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/flattens-iterable.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/flattens-iterable.js new file mode 100644 index 000000000000..6668426d51cb --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/flattens-iterable.js @@ -0,0 +1,30 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Iterator.prototype.flatMap flattens iterables returned by the mapper +info: | + %Iterator.prototype%.flatMap ( mapper ) + +includes: [compareArray.js] +features: [iterator-helpers] +flags: [] +---*/ + +function* g() { + yield 0; + yield 1; + yield 2; + yield 3; +} + +let iter = g().flatMap((v, count) => { + let result = []; + for (let i = 0; i < v; ++i) { + result.push(v); + } + return result; +}); + +assert.compareArray(Array.from(iter), [1, 2, 2, 3, 3, 3]); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/flattens-iterator.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/flattens-iterator.js new file mode 100644 index 000000000000..da236b0fabc1 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/flattens-iterator.js @@ -0,0 +1,44 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Iterator.prototype.flatMap flattens non-iterable iterators returned by the mapper +info: | + %Iterator.prototype%.flatMap ( mapper ) + + 5.b.vi. Let innerIterator be Completion(GetIteratorFlattenable(mapped)). + +includes: [compareArray.js] +features: [iterator-helpers] +flags: [] +---*/ + +function* g() { + yield 0; + yield 1; + yield 2; + yield 3; +} + +let iter = g().flatMap((v, count) => { + let i = 0; + return { + next: function () { + if (i < v) { + ++i; + return { + value: v, + done: false, + }; + } else { + return { + value: undefined, + done: true, + }; + } + }, + }; +}); + +assert.compareArray(Array.from(iter), [1, 2, 2, 3, 3, 3]); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/flattens-only-depth-1.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/flattens-only-depth-1.js new file mode 100644 index 000000000000..1ed5e8b52c65 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/flattens-only-depth-1.js @@ -0,0 +1,34 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Iterator.prototype.flatMap does not flatten recursively +info: | + %Iterator.prototype%.flatMap ( mapper ) + +includes: [compareArray.js] +features: [iterator-helpers] +flags: [] +---*/ + +let arr = [ + { + [Symbol.iterator]: function () { + throw new Test262Error(); + }, + }, + { + next: function () { + throw new Test262Error(); + }, + }, +]; + +function* g() { + yield arr; +} + +let iter = g().flatMap(v => v); + +assert.compareArray(Array.from(iter), arr); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/get-next-method-only-once.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/get-next-method-only-once.js new file mode 100644 index 000000000000..feb5c7094ea1 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/get-next-method-only-once.js @@ -0,0 +1,41 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Gets the next method from the underlying iterator only once +info: | + %Iterator.prototype%.flatMap ( mapper ) + + 4. Let iterated be ? GetIteratorDirect(O). + +features: [iterator-helpers] +flags: [] +---*/ +let nextGets = 0; +let nextCalls = 0; + +class CountingIterator extends Iterator { + get next() { + ++nextGets; + let iter = (function* () { + for (let i = 1; i < 5; ++i) { + yield i; + } + })(); + return function () { + ++nextCalls; + return iter.next(); + }; + } +} + +let iterator = new CountingIterator(); + +assert.sameValue(nextGets, 0); +assert.sameValue(nextCalls, 0); + +for (const value of iterator.flatMap(() => [])); + +assert.sameValue(nextGets, 1); +assert.sameValue(nextCalls, 5); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/get-next-method-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/get-next-method-throws.js new file mode 100644 index 000000000000..a5ae5fababa9 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/get-next-method-throws.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Underlying iterator has throwing next getter +info: | + %Iterator.prototype%.flatMap ( mapper ) + + 4. Let iterated be ? GetIteratorDirect(O). + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + get next() { + throw new Test262Error(); + } +} + +let iterator = new ThrowingIterator(); + +assert.throws(Test262Error, function () { + iterator.flatMap(() => []); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/get-return-method-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/get-return-method-throws.js new file mode 100644 index 000000000000..e51b9e333630 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/get-return-method-throws.js @@ -0,0 +1,30 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Underlying iterator return is throwing getter +info: | + %Iterator.prototype%.flatMap ( mapper ) + +features: [iterator-helpers] +flags: [] +---*/ +class TestIterator extends Iterator { + next() { + return { + done: false, + value: 1, + }; + } + get return() { + throw new Test262Error(); + } +} + +let iterator = new TestIterator().flatMap(x => [x]); +iterator.next(); + +assert.throws(Test262Error, function () { + iterator.return(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/is-function.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/is-function.js new file mode 100644 index 000000000000..8d2ed6202a62 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/is-function.js @@ -0,0 +1,10 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Iterator.prototype.flatMap is a built-in function +features: [iterator-helpers] +---*/ + +assert.sameValue(typeof Iterator.prototype.flatMap, 'function'); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/iterable-primitives-are-not-flattened.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/iterable-primitives-are-not-flattened.js new file mode 100644 index 000000000000..e3eed45277e5 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/iterable-primitives-are-not-flattened.js @@ -0,0 +1,37 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Iterator.prototype.flatMap does not respect the iterability of any primitive +info: | + %Iterator.prototype%.flatMap ( mapper ) + + 5.b.vi. Let innerIterator be Completion(GetIteratorFlattenable(mapped)). + +includes: [compareArray.js] +features: [iterator-helpers] +flags: [] +---*/ + +function* g() { + yield 0; +} + +Number.prototype[Symbol.iterator] = function* () { + let i = 0; + let target = this >>> 0; + while (i < target) { + yield i; + ++i; + } +}; + +assert.compareArray(Array.from(5), [0, 1, 2, 3, 4]); + +assert.throws(TypeError, function () { + for (let unused of g().flatMap(v => 5)); +}); + +let iter = g().flatMap(v => new Number(5)); +assert.compareArray(Array.from(iter), [0, 1, 2, 3, 4]); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/iterable-to-iterator-fallback.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/iterable-to-iterator-fallback.js new file mode 100644 index 000000000000..0324025e68ff --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/iterable-to-iterator-fallback.js @@ -0,0 +1,57 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Iterator.prototype.flatMap falls back to treating mapper return values as iterators if the Symbol.iterator property is null/undefined +info: | + %Iterator.prototype%.flatMap ( mapper ) + + 5.b.vi. Let innerIterator be Completion(GetIteratorFlattenable(mapped)). + +includes: [compareArray.js] +features: [iterator-helpers] +flags: [] +---*/ + +function* g() { + yield 0; +} + +function* h() { + yield 0; + yield 1; + yield 2; +} + +let iter = g().flatMap(v => { + let n = h(); + return { + [Symbol.iterator]: 0, + next: () => n.next(), + }; +}); + +assert.throws(TypeError, function () { + iter.next(); +}); + +iter = g().flatMap(v => { + let n = h(); + return { + [Symbol.iterator]: null, + next: () => n.next(), + }; +}); + +assert.compareArray(Array.from(iter), [0, 1, 2]); + +iter = g().flatMap(v => { + let n = h(); + return { + [Symbol.iterator]: undefined, + next: () => n.next(), + }; +}); + +assert.compareArray(Array.from(iter), [0, 1, 2]); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/iterator-already-exhausted.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/iterator-already-exhausted.js new file mode 100644 index 000000000000..ef17517fe935 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/iterator-already-exhausted.js @@ -0,0 +1,22 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Iterator.prototype.flatMap returns an empty iterator when the iterator has already been exhausted +info: | + %Iterator.prototype%.flatMap ( mapper ) + +features: [iterator-helpers] +flags: [] +---*/ +let iterator = (function* () {})(); + +let { value, done } = iterator.next(); +assert.sameValue(value, undefined); +assert.sameValue(done, true); + +iterator = iterator.flatMap(x => [x]); +({ value, done } = iterator.next()); +assert.sameValue(value, undefined); +assert.sameValue(done, true); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/iterator-return-method-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/iterator-return-method-throws.js new file mode 100644 index 000000000000..5d8eb462914e --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/iterator-return-method-throws.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Iterator has throwing return +info: | + %Iterator.prototype%.flatMap ( mapper ) + +features: [iterator-helpers] +flags: [] +---*/ +class IteratorThrows extends Iterator { + next() { + return { + done: false, + value: 0, + }; + } + return() { + throw new Test262Error(); + } +} + +let iterator = new IteratorThrows().flatMap(() => []); + +assert.throws(Test262Error, function () { + iterator.return(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/length.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/length.js new file mode 100644 index 000000000000..2f6183680680 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/length.js @@ -0,0 +1,22 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Iterator.prototype.flatMap has a "length" property whose value is 1. +info: | + ECMAScript Standard Built-in Objects + + Unless otherwise specified, the length property of a built-in + Function object has the attributes { [[Writable]]: false, [[Enumerable]]: + false, [[Configurable]]: true }. +features: [iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Iterator.prototype.flatMap, 'length', { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/mapper-args.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/mapper-args.js new file mode 100644 index 000000000000..07594d3ca8d7 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/mapper-args.js @@ -0,0 +1,55 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Iterator.prototype.flatMap mapper is passed the yielded value and a counter as arguments +info: | + %Iterator.prototype%.flatMap ( mapper ) + + 5.b.iv. Let mapped be Completion(Call(mapper, undefined, « value, 𝔽(counter) »)). + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + yield 'a'; + yield 'b'; + yield 'c'; + yield 'd'; + yield 'e'; +} + +let assertionCount = 0; +let iter = g().flatMap((v, count) => { + switch (v) { + case 'a': + assert.sameValue(count, 0); + ++assertionCount; + return [0]; + case 'b': + assert.sameValue(count, 1); + ++assertionCount; + return [0]; + case 'c': + assert.sameValue(count, 2); + ++assertionCount; + return [1, 2]; + case 'd': + assert.sameValue(count, 3); + ++assertionCount; + return [3, 4, 5]; + case 'e': + assert.sameValue(count, 4); + ++assertionCount; + return [6, 7, 8, 9]; + default: + throw new Error(); + } +}); + +assert.sameValue(assertionCount, 0); + +for (let i of iter); + +assert.sameValue(assertionCount, 5); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/mapper-returns-closed-iterator.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/mapper-returns-closed-iterator.js new file mode 100644 index 000000000000..e44010a73319 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/mapper-returns-closed-iterator.js @@ -0,0 +1,30 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Iterator.prototype.flatMap handles closed return values from mapper and does not try to close them again +info: | + %Iterator.prototype%.flatMap ( mapper ) + +features: [iterator-helpers] +flags: [] +---*/ + +function* g() { + yield 0; + yield 1; + yield 2; +} + +let closed = g(); +closed.return(); +closed.return = function () { + throw new Test262Error(); +}; + +let iter = g().flatMap(v => closed); +let { value, done } = iter.next(); + +assert.sameValue(value, undefined); +assert.sameValue(done, true); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/mapper-returns-non-object.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/mapper-returns-non-object.js new file mode 100644 index 000000000000..c40ce55f83c2 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/mapper-returns-non-object.js @@ -0,0 +1,34 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Iterator.prototype.flatMap mapper return value must be an object +info: | + %Iterator.prototype%.flatMap ( mapper ) + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + yield 0; + yield 0; + yield 0; + yield 1; +} + +let iter = g(); + +let mapperCalls = 0; +iter = iter.flatMap(v => { + ++mapperCalls; + return null; +}); + +assert.sameValue(mapperCalls, 0); + +assert.throws(TypeError, function () { + iter.next(); +}); + +assert.sameValue(mapperCalls, 1); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/mapper-this.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/mapper-this.js new file mode 100644 index 000000000000..dee13a7208b8 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/mapper-this.js @@ -0,0 +1,33 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Iterator.prototype.flatMap mapper this value is undefined +info: | + %Iterator.prototype%.flatMap ( mapper ) + + 5.b.iv. Let mapped be Completion(Call(mapper, undefined, « value, 𝔽(counter) »)). + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + yield 0; +} + +let iter = g(); + +let expectedThis = function () { + return this; +}.call(undefined); + +let assertionCount = 0; +iter = iter.flatMap(function (v, count) { + assert.sameValue(this, expectedThis); + ++assertionCount; + return [v]; +}); + +iter.next(); +assert.sameValue(assertionCount, 1); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/mapper-throws-then-closing-iterator-also-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/mapper-throws-then-closing-iterator-also-throws.js new file mode 100644 index 000000000000..41fd2e1204f2 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/mapper-throws-then-closing-iterator-also-throws.js @@ -0,0 +1,40 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Attempts to close iterator when mapper throws, but that throws +info: | + %Iterator.prototype%.flatMap ( mapper ) + + 5.b.v. IfAbruptCloseIterator(mapped, iterated). + +features: [iterator-helpers] +flags: [] +---*/ +let returnCalls = 0; + +class TestIterator extends Iterator { + next() { + return { + done: false, + value: 1, + }; + } + return() { + ++returnCalls; + throw new Error(); + } +} + +let iterator = new TestIterator().flatMap(() => { + throw new Test262Error(); +}); + +assert.sameValue(returnCalls, 0); + +assert.throws(Test262Error, function () { + iterator.next(); +}); + +assert.sameValue(returnCalls, 1); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/mapper-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/mapper-throws.js new file mode 100644 index 000000000000..8e77c245dfe5 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/mapper-throws.js @@ -0,0 +1,41 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Closes iterator and throws when mapper throws +info: | + %Iterator.prototype%.flatMap ( mapper ) + + 5.b.v. IfAbruptCloseIterator(mapped, iterated). + +features: [iterator-helpers] +flags: [] +---*/ +let returnCalls = 0; + +class TestIterator extends Iterator { + next() { + return { + done: false, + value: 1, + }; + } + return() { + ++returnCalls; + return {}; + } +} + +let callbackCalls = 0; +let iterator = new TestIterator().flatMap(() => { + ++callbackCalls; + throw new Test262Error(); +}); + +assert.throws(Test262Error, function () { + iterator.next(); +}); + +assert.sameValue(callbackCalls, 1); +assert.sameValue(returnCalls, 1); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/name.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/name.js new file mode 100644 index 000000000000..d0a24e862f87 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/name.js @@ -0,0 +1,29 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + The "name" property of Iterator.prototype.flatMap +info: | + 17 ECMAScript Standard Built-in Objects + + Every built-in Function object, including constructors, that is not + identified as an anonymous function has a name property whose value is a + String. Unless otherwise specified, this value is the name that is given to + the function in this specification. + + ... + + Unless otherwise specified, the name property of a built-in Function + object, if it exists, has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +features: [iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Iterator.prototype.flatMap, 'name', { + value: 'flatMap', + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/next-method-returns-non-object.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/next-method-returns-non-object.js new file mode 100644 index 000000000000..3a427325cdbd --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/next-method-returns-non-object.js @@ -0,0 +1,23 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Underlying iterator next returns non-object +info: | + %Iterator.prototype%.flatMap ( mapper ) + +features: [iterator-helpers] +flags: [] +---*/ +class NonObjectIterator extends Iterator { + next() { + return null; + } +} + +let iterator = new NonObjectIterator().flatMap(x => [x]); + +assert.throws(TypeError, function () { + iterator.next(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/next-method-returns-throwing-done.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/next-method-returns-throwing-done.js new file mode 100644 index 000000000000..7dac1daa2ef1 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/next-method-returns-throwing-done.js @@ -0,0 +1,31 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Underlying iterator next returns object with throwing done getter +info: | + %Iterator.prototype%.flatMap ( mapper ) + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + return { + get done() { + throw new Test262Error(); + }, + value: 1, + }; + } + return() { + throw new Error(); + } +} + +let iterator = new ThrowingIterator().flatMap(x => [x]); + +assert.throws(Test262Error, function () { + iterator.next(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/next-method-returns-throwing-value-done.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/next-method-returns-throwing-value-done.js new file mode 100644 index 000000000000..ece5b2d777c9 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/next-method-returns-throwing-value-done.js @@ -0,0 +1,28 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Underlying iterator next returns object with throwing value getter, but is already done +info: | + %Iterator.prototype%.flatMap ( mapper ) + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + return { + done: true, + get value() { + throw new Test262Error(); + }, + }; + } + return() { + throw new Error(); + } +} + +let iterator = new ThrowingIterator().flatMap(x => [x]); +iterator.next(); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/next-method-returns-throwing-value.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/next-method-returns-throwing-value.js new file mode 100644 index 000000000000..c11cfacd6aba --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/next-method-returns-throwing-value.js @@ -0,0 +1,31 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Underlying iterator next returns object with throwing value getter +info: | + %Iterator.prototype%.flatMap ( mapper ) + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + return { + done: false, + get value() { + throw new Test262Error(); + }, + }; + } + return() { + throw new Error(); + } +} + +let iterator = new ThrowingIterator().flatMap(x => [x]); + +assert.throws(Test262Error, function () { + iterator.next(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/next-method-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/next-method-throws.js new file mode 100644 index 000000000000..aef686179217 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/next-method-throws.js @@ -0,0 +1,23 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Underlying iterator has throwing next method +info: | + %Iterator.prototype%.flatMap ( mapper ) + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + throw new Test262Error(); + } +} + +let iterator = new ThrowingIterator().flatMap(x => [x]); + +assert.throws(Test262Error, function () { + iterator.next(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/non-callable-mapper.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/non-callable-mapper.js new file mode 100644 index 000000000000..b596288ec6e6 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/non-callable-mapper.js @@ -0,0 +1,20 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Iterator.prototype.flatMap expects to be called with a callable argument. +info: | + %Iterator.prototype%.flatMap ( mapper ) + + 3. If IsCallable(mapper) is false, throw a TypeError exception. + +features: [iterator-helpers] +flags: [] +---*/ +let nonCallable = {}; +let iterator = (function* () {})(); + +assert.throws(TypeError, function () { + iterator.flatMap(nonCallable); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/non-constructible.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/non-constructible.js new file mode 100644 index 000000000000..e2adfb424143 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/non-constructible.js @@ -0,0 +1,28 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Iterator.prototype.flatMap is not constructible. + + Built-in function objects that are not identified as constructors do not implement the [[Construct]] internal method unless otherwise specified in the description of a particular function. +features: [iterator-helpers] +---*/ +function* g() {} +let iter = g(); + +assert.throws(TypeError, () => { + new iter.flatMap(); +}); + +assert.throws(TypeError, () => { + new iter.flatMap(() => []); +}); + +assert.throws(TypeError, () => { + new Iterator.prototype.flatMap(() => []); +}); + +assert.throws(TypeError, () => { + new class extends Iterator {}.flatMap(() => []); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/prop-desc.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/prop-desc.js new file mode 100644 index 000000000000..97266ef53ca6 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/prop-desc.js @@ -0,0 +1,25 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Property descriptor of Iterator.prototype.flatMap +info: | + Iterator.prototype.flatMap + + * is the initial value of the Iterator.prototype.flatMap property of the global object. + + 17 ECMAScript Standard Built-in Objects + + Every other data property described in clauses 18 through 26 and in Annex B.2 + has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +features: [globalThis, iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Iterator.prototype, 'flatMap', { + writable: true, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/proto.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/proto.js new file mode 100644 index 000000000000..60feb748e41e --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/proto.js @@ -0,0 +1,11 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + The value of the [[Prototype]] internal slot of Iterator.prototype.flatMap is the + intrinsic object %FunctionPrototype%. +features: [iterator-helpers] +---*/ + +assert.sameValue(Object.getPrototypeOf(Iterator.prototype.flatMap), Function.prototype); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/result-is-iterator.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/result-is-iterator.js new file mode 100644 index 000000000000..e85cf38aba50 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/result-is-iterator.js @@ -0,0 +1,14 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + The value of the [[Prototype]] internal slot of the return value of Iterator.prototype.flatMap is the + intrinsic object %IteratorHelperPrototype%. +features: [iterator-helpers] +---*/ + +assert( + (function* () {})().flatMap(() => []) instanceof Iterator, + 'function*(){}().flatMap(() => []) must return an Iterator' +); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/return-is-forwarded-to-mapper-result.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/return-is-forwarded-to-mapper-result.js new file mode 100644 index 000000000000..004911659a1b --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/return-is-forwarded-to-mapper-result.js @@ -0,0 +1,45 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Mapper returned iterator return is called when result iterator is closed +info: | + %Iterator.prototype%.flatMap ( mapper ) + +features: [iterator-helpers] +flags: [] +---*/ +let returnCount = 0; + +function* g() { + yield 0; +} + +let iter = g().flatMap(v => ({ + next() { + return { + done: false, + value: 1, + }; + }, + return() { + ++returnCount; + return {}; + }, +})); + +assert.sameValue(returnCount, 0); + +let { done, value } = iter.next(); + +assert.sameValue(done, false); +assert.sameValue(value, 1); + +assert.sameValue(returnCount, 0); + +iter.return(); +assert.sameValue(returnCount, 1); + +iter.return(); +assert.sameValue(returnCount, 1); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/return-is-forwarded-to-underlying-iterator.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/return-is-forwarded-to-underlying-iterator.js new file mode 100644 index 000000000000..cf2a3a475554 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/return-is-forwarded-to-underlying-iterator.js @@ -0,0 +1,33 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Underlying iterator return is called when result iterator is closed +info: | + %Iterator.prototype%.flatMap ( mapper ) + +features: [iterator-helpers] +flags: [] +---*/ +let returnCount = 0; + +class TestIterator extends Iterator { + next() { + return { + done: false, + value: 1, + }; + } + return() { + ++returnCount; + return {}; + } +} + +let iterator = new TestIterator().flatMap(() => []); +assert.sameValue(returnCount, 0); +iterator.return(); +assert.sameValue(returnCount, 1); +iterator.return(); +assert.sameValue(returnCount, 1); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/return-is-not-forwarded-after-exhaustion.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/return-is-not-forwarded-after-exhaustion.js new file mode 100644 index 000000000000..d970908da346 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/return-is-not-forwarded-after-exhaustion.js @@ -0,0 +1,46 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Underlying iterator return is not called after result iterator observes that underlying iterator is exhausted +info: | + %Iterator.prototype%.flatMap ( mapper ) + +features: [iterator-helpers] +flags: [] +---*/ +let returnCount = 0; + +class TestIterator extends Iterator { + next() { + return { + done: true, + value: undefined, + }; + } + return() { + throw new Test262Error(); + } +} + +let iterator = new TestIterator().flatMap(x => [x]); +assert.throws(Test262Error, function () { + iterator.return(); +}); +iterator.next(); +iterator.return(); + +iterator = new TestIterator().flatMap(x => [x]); +iterator.next(); +iterator.return(); + +iterator = new TestIterator() + .flatMap(x => [x]) + .flatMap(x => [x]) + .flatMap(x => [x]); +assert.throws(Test262Error, function () { + iterator.return(); +}); +iterator.next(); +iterator.return(); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/strings-are-not-flattened.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/strings-are-not-flattened.js new file mode 100644 index 000000000000..258486076699 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/strings-are-not-flattened.js @@ -0,0 +1,26 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Iterator.prototype.flatMap does not respect the iterability of primitive strings +info: | + %Iterator.prototype%.flatMap ( mapper ) + + 5.b.vi. Let innerIterator be Completion(GetIteratorFlattenable(mapped)). + +includes: [compareArray.js] +features: [iterator-helpers] +flags: [] +---*/ + +function* g() { + yield 0; +} + +assert.throws(TypeError, function () { + for (let unused of g().flatMap(v => 'string')); +}); + +let iter = g().flatMap(v => new String('string')); +assert.compareArray(Array.from(iter), ['s', 't', 'r', 'i', 'n', 'g']); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/this-non-callable-next.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/this-non-callable-next.js new file mode 100644 index 000000000000..871f6223f6c5 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/this-non-callable-next.js @@ -0,0 +1,17 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Iterator.prototype.flatMap throws TypeError when its this value is an object with a non-callable next +info: | + %Iterator.prototype%.flatMap ( mapper ) + +features: [iterator-helpers] +flags: [] +---*/ +let iter = Iterator.prototype.flatMap.call({ next: 0 }, () => []); + +assert.throws(TypeError, function () { + iter.next(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/this-non-object.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/this-non-object.js new file mode 100644 index 000000000000..8893a15046c0 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/this-non-object.js @@ -0,0 +1,26 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Iterator.prototype.flatMap throws TypeError when its this value is a non-object +info: | + %Iterator.prototype%.flatMap ( mapper ) + + 2. If O is not an Object, throw a TypeError exception. + +features: [iterator-helpers] +flags: [] +---*/ +assert.throws(TypeError, function () { + Iterator.prototype.flatMap.call(null, () => []); +}); + +Object.defineProperty(Number.prototype, 'next', { + get: function () { + throw new Test262Error(); + }, +}); +assert.throws(TypeError, function () { + Iterator.prototype.flatMap.call(0, () => []); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/this-plain-iterator.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/this-plain-iterator.js new file mode 100644 index 000000000000..677d6adbcc84 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/this-plain-iterator.js @@ -0,0 +1,31 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Iterator.prototype.flatMap supports a this value that does not inherit from Iterator.prototype but implements the iterator protocol +info: | + %Iterator.prototype%.flatMap ( mapper ) + +features: [iterator-helpers] +flags: [] +---*/ +let iter = { + get next() { + let count = 3; + return function () { + --count; + return count >= 0 ? { done: false, value: count } : { done: true, value: undefined }; + }; + }, +}; + +let mapperCalls = 0; +iter = Iterator.prototype.flatMap.call(iter, function (v) { + ++mapperCalls; + return [v]; +}); + +for (let e of iter); + +assert.sameValue(mapperCalls, 3); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/underlying-iterator-advanced-in-parallel.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/underlying-iterator-advanced-in-parallel.js new file mode 100644 index 000000000000..0d2f9f677e80 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/underlying-iterator-advanced-in-parallel.js @@ -0,0 +1,42 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Underlying iterator is advanced after calling flatMap +info: | + %Iterator.prototype%.flatMap ( mapper ) + +features: [iterator-helpers] +flags: [] +---*/ +let iterator = (function* () { + for (let i = 0; i < 5; ++i) { + yield i; + } +})(); + +let mapped = iterator.flatMap(x => [x]); + +let { value, done } = iterator.next(); + +assert.sameValue(value, 0); +assert.sameValue(done, false); + +iterator.next(); +iterator.next(); + +({ value, done } = mapped.next()); + +assert.sameValue(value, 3); +assert.sameValue(done, false); + +({ value, done } = mapped.next()); + +assert.sameValue(value, 4); +assert.sameValue(done, false); + +({ value, done } = mapped.next()); + +assert.sameValue(value, undefined); +assert.sameValue(done, true); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/underlying-iterator-closed-in-parallel.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/underlying-iterator-closed-in-parallel.js new file mode 100644 index 000000000000..be65e4fba8e8 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/underlying-iterator-closed-in-parallel.js @@ -0,0 +1,26 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Underlying iterator is closed after calling flatMap +info: | + %Iterator.prototype%.flatMap ( mapper ) + +features: [iterator-helpers] +flags: [] +---*/ +let iterator = (function* () { + for (let i = 0; i < 5; ++i) { + yield i; + } +})(); + +let mapped = iterator.flatMap(x => [x]); + +iterator.return(); + +let { value, done } = mapped.next(); + +assert.sameValue(value, undefined); +assert.sameValue(done, true); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/underlying-iterator-closed.js b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/underlying-iterator-closed.js new file mode 100644 index 000000000000..9f54585ed882 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/flatMap/underlying-iterator-closed.js @@ -0,0 +1,26 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Underlying iterator is closed before calling flatMap +info: | + %Iterator.prototype%.flatMap ( mapper ) + +features: [iterator-helpers] +flags: [] +---*/ +let iterator = (function* () { + for (let i = 0; i < 5; ++i) { + yield i; + } +})(); + +iterator.return(); + +let mapped = iterator.flatMap(() => []); + +let { value, done } = mapped.next(); + +assert.sameValue(value, undefined); +assert.sameValue(done, true); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/forEach/argument-effect-order.js b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/argument-effect-order.js new file mode 100644 index 000000000000..acf139d90c23 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/argument-effect-order.js @@ -0,0 +1,35 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.forEach +description: > + Arguments and this value are evaluated in the correct order +info: | + %Iterator.prototype%.forEach ( fn ) + + 1. Let O be the this value. + 2. If O is not an Object, throw a TypeError exception. + 3. If IsCallable(fn) is false, throw a TypeError exception. + 4. Let iterated be ? GetIteratorDirect(O). + +includes: [compareArray.js] +features: [iterator-helpers] +flags: [] +---*/ +let effects = []; + +assert.throws(TypeError, function () { + Iterator.prototype.forEach.call( + { + get next() { + effects.push('get next'); + return function () { + return { done: true, value: undefined }; + }; + }, + }, + null + ); +}); + +assert.compareArray(effects, []); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/forEach/callable.js b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/callable.js new file mode 100644 index 000000000000..344442e7ecc5 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/callable.js @@ -0,0 +1,13 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.forEach +description: > + Iterator.prototype.forEach is callable +features: [iterator-helpers] +---*/ +function* g() {} +Iterator.prototype.forEach.call(g(), () => {}); + +let iter = g(); +iter.forEach(() => {}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/forEach/fn-args.js b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/fn-args.js new file mode 100644 index 000000000000..de5d875321ef --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/fn-args.js @@ -0,0 +1,40 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.forEach +description: > + Iterator.prototype.forEach fn is passed the yielded value and a counter as arguments +info: | + %Iterator.prototype%.forEach ( fn ) + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + yield 'a'; + yield 'b'; + yield 'c'; +} + +let iter = g(); + +let assertionCount = 0; +let result = iter.forEach((v, count) => { + switch (v) { + case 'a': + assert.sameValue(count, 0); + break; + case 'b': + assert.sameValue(count, 1); + break; + case 'c': + assert.sameValue(count, 2); + break; + default: + throw new Error(); + } + ++assertionCount; +}); + +assert.sameValue(result, undefined); +assert.sameValue(assertionCount, 3); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/forEach/fn-called-for-each-yielded-value.js b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/fn-called-for-each-yielded-value.js new file mode 100644 index 000000000000..1df839d6a4fb --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/fn-called-for-each-yielded-value.js @@ -0,0 +1,28 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.forEach +description: > + Iterator.prototype.forEach calls fn once for each yielded value, in order +info: | + %Iterator.prototype%.forEach ( fn ) + + 6.d. Let result be Completion(Call(fn, undefined, « value, 𝔽(counter) »)). + +includes: [compareArray.js] +features: [iterator-helpers] +flags: [] +---*/ +let effects = []; + +function* g() { + yield 'a'; + yield 'b'; + yield 'c'; +} + +g().forEach((value, count) => { + effects.push(value, count); +}); + +assert.compareArray(effects, ['a', 0, 'b', 1, 'c', 2]); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/forEach/fn-this.js b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/fn-this.js new file mode 100644 index 000000000000..eb0cb574b84a --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/fn-this.js @@ -0,0 +1,30 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.forEach +description: > + Iterator.prototype.forEach fn this value is undefined +info: | + %Iterator.prototype%.forEach ( fn ) + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + yield 0; +} + +let iter = g(); + +let expectedThis = function () { + return this; +}.call(undefined); + +let assertionCount = 0; +let result = iter.forEach(function (v, count) { + assert.sameValue(this, expectedThis); + ++assertionCount; +}); + +assert.sameValue(result, undefined); +assert.sameValue(assertionCount, 1); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/forEach/fn-throws-then-closing-iterator-also-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/fn-throws-then-closing-iterator-also-throws.js new file mode 100644 index 000000000000..520f3ab590b0 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/fn-throws-then-closing-iterator-also-throws.js @@ -0,0 +1,36 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.forEach +description: > + Attempts to close iterator when fn throws, but that throws +info: | + %Iterator.prototype%.forEach ( fn ) + +features: [iterator-helpers] +flags: [] +---*/ +let returnCalls = 0; + +class TestIterator extends Iterator { + next() { + return { + done: false, + value: 1, + }; + } + return() { + ++returnCalls; + throw new Error(); + } +} + +let iterator = new TestIterator(); + +assert.throws(Test262Error, function () { + iterator.forEach(() => { + throw new Test262Error(); + }); +}); + +assert.sameValue(returnCalls, 1); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/forEach/fn-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/fn-throws.js new file mode 100644 index 000000000000..a860244d3af9 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/fn-throws.js @@ -0,0 +1,40 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.forEach +description: > + Closes iterator and throws when fn throws +info: | + %Iterator.prototype%.forEach ( fn ) + +features: [iterator-helpers] +flags: [] +---*/ +let returnCalls = 0; + +class TestIterator extends Iterator { + next() { + return { + done: false, + value: 1, + }; + } + return() { + ++returnCalls; + return {}; + } +} + +let iterator = new TestIterator(); + +let callbackCalls = 0; + +assert.throws(Test262Error, function () { + iterator.forEach(() => { + ++callbackCalls; + throw new Test262Error(); + }); +}); + +assert.sameValue(callbackCalls, 1); +assert.sameValue(returnCalls, 1); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/forEach/get-next-method-only-once.js b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/get-next-method-only-once.js new file mode 100644 index 000000000000..ccb0db7da297 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/get-next-method-only-once.js @@ -0,0 +1,36 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.forEach +description: > + Gets the next method from the iterator only once +info: | + %Iterator.prototype%.forEach ( fn ) + +features: [iterator-helpers] +flags: [] +---*/ +let nextGets = 0; + +class TestIterator extends Iterator { + get next() { + ++nextGets; + let counter = 5; + return function () { + if (counter < 0) { + return { done: true, value: undefined }; + } else { + return { done: false, value: --counter }; + } + }; + } +} + +let iterator = new TestIterator(); + +assert.sameValue(nextGets, 0); +assert.sameValue( + iterator.forEach(() => {}), + undefined +); +assert.sameValue(nextGets, 1); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/forEach/get-next-method-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/get-next-method-throws.js new file mode 100644 index 000000000000..17464a845776 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/get-next-method-throws.js @@ -0,0 +1,23 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.forEach +description: > + Iterator has throwing next getter +info: | + %Iterator.prototype%.forEach ( fn ) + +features: [iterator-helpers] +flags: [] +---*/ +class IteratorThrows extends Iterator { + get next() { + throw new Test262Error(); + } +} + +let iterator = new IteratorThrows(); + +assert.throws(Test262Error, function () { + iterator.forEach(() => {}); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/forEach/is-function.js b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/is-function.js new file mode 100644 index 000000000000..28e16f80b228 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/is-function.js @@ -0,0 +1,10 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.forEach +description: > + Iterator.prototype.forEach is a built-in function +features: [iterator-helpers] +---*/ + +assert.sameValue(typeof Iterator.prototype.forEach, 'function'); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/forEach/iterator-already-exhausted.js b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/iterator-already-exhausted.js new file mode 100644 index 000000000000..521f120ad502 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/iterator-already-exhausted.js @@ -0,0 +1,22 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.forEach +description: > + Iterator.prototype.forEach returns immediately when the iterator has already been exhausted +info: | + %Iterator.prototype%.forEach ( fn ) + +features: [iterator-helpers] +flags: [] +---*/ +let iterator = (function* () {})(); + +let { value, done } = iterator.next(); +assert.sameValue(value, undefined); +assert.sameValue(done, true); + +let result = iterator.forEach(() => { + throw new Error(); +}); +assert.sameValue(result, undefined); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/forEach/length.js b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/length.js new file mode 100644 index 000000000000..0bfeb8a1c37f --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/length.js @@ -0,0 +1,22 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.forEach +description: > + Iterator.prototype.forEach has a "length" property whose value is 1. +info: | + ECMAScript Standard Built-in Objects + + Unless otherwise specified, the length property of a built-in + Function object has the attributes { [[Writable]]: false, [[Enumerable]]: + false, [[Configurable]]: true }. +features: [iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Iterator.prototype.forEach, 'length', { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/forEach/name.js b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/name.js new file mode 100644 index 000000000000..780a73855e71 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/name.js @@ -0,0 +1,29 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.forEach +description: > + The "name" property of Iterator.prototype.forEach +info: | + 17 ECMAScript Standard Built-in Objects + + every built-in Function object, including constructors, that is not + identified as an anonymous function has a name property whose value is a + String. Unless otherwise specified, this value is the name that is given to + the function in this specification. + + ... + + Unless otherwise specified, the name property of a built-in Function + object, if it exists, has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +features: [iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Iterator.prototype.forEach, 'name', { + value: 'forEach', + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/forEach/next-method-returns-non-object.js b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/next-method-returns-non-object.js new file mode 100644 index 000000000000..c8de66c3cfbd --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/next-method-returns-non-object.js @@ -0,0 +1,23 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.forEach +description: > + Underlying iterator next returns non-object +info: | + %Iterator.prototype%.forEach ( fn ) + +features: [iterator-helpers] +flags: [] +---*/ +class NonObjectIterator extends Iterator { + next() { + return null; + } +} + +let iterator = new NonObjectIterator(); + +assert.throws(TypeError, function () { + iterator.forEach(() => {}); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/forEach/next-method-returns-throwing-done.js b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/next-method-returns-throwing-done.js new file mode 100644 index 000000000000..906c9d52875c --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/next-method-returns-throwing-done.js @@ -0,0 +1,31 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.forEach +description: > + Underlying iterator next returns object with throwing done getter +info: | + %Iterator.prototype%.forEach ( fn ) + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + return { + get done() { + throw new Test262Error(); + }, + value: 1, + }; + } + return() { + throw new Error(); + } +} + +let iterator = new ThrowingIterator(); + +assert.throws(Test262Error, function () { + iterator.forEach(() => {}); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/forEach/next-method-returns-throwing-value-done.js b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/next-method-returns-throwing-value-done.js new file mode 100644 index 000000000000..e1a586fd3d39 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/next-method-returns-throwing-value-done.js @@ -0,0 +1,28 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.forEach +description: > + Underlying iterator next returns object with throwing value getter, but is already done +info: | + %Iterator.prototype%.forEach ( fn ) + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + return { + done: true, + get value() { + throw new Test262Error(); + }, + }; + } + return() { + throw new Error(); + } +} + +let iterator = new ThrowingIterator(); +iterator.forEach(() => {}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/forEach/next-method-returns-throwing-value.js b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/next-method-returns-throwing-value.js new file mode 100644 index 000000000000..26c3cb04ea99 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/next-method-returns-throwing-value.js @@ -0,0 +1,31 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.forEach +description: > + Underlying iterator next returns object with throwing value getter +info: | + %Iterator.prototype%.forEach ( fn ) + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + return { + done: false, + get value() { + throw new Test262Error(); + }, + }; + } + return() { + throw new Error(); + } +} + +let iterator = new ThrowingIterator(); + +assert.throws(Test262Error, function () { + iterator.forEach(() => {}); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/forEach/next-method-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/next-method-throws.js new file mode 100644 index 000000000000..d6a79e8119b3 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/next-method-throws.js @@ -0,0 +1,23 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.forEach +description: > + Underlying iterator has throwing next method +info: | + %Iterator.prototype%.forEach ( fn ) + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + throw new Test262Error(); + } +} + +let iterator = new ThrowingIterator(); + +assert.throws(Test262Error, function () { + iterator.forEach(() => {}); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/forEach/non-callable-predicate.js b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/non-callable-predicate.js new file mode 100644 index 000000000000..abfbfd3639d1 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/non-callable-predicate.js @@ -0,0 +1,20 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.forEach +description: > + Iterator.prototype.forEach expects to be called with a callable argument. +info: | + %Iterator.prototype%.forEach ( fn ) + +features: [iterator-helpers] +flags: [] +---*/ +let nonCallable = {}; +let iterator = (function* () { + yield 1; +})(); + +assert.throws(TypeError, function () { + iterator.forEach(nonCallable); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/forEach/non-constructible.js b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/non-constructible.js new file mode 100644 index 000000000000..65156cd462af --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/non-constructible.js @@ -0,0 +1,28 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.forEach +description: > + Iterator.prototype.forEach is not constructible. + + Built-in function objects that are not identified as constructors do not implement the [[Construct]] internal method unless otherwise specified in the description of a particular function. +features: [iterator-helpers] +---*/ +function* g() {} +let iter = g(); + +assert.throws(TypeError, () => { + new iter.forEach(); +}); + +assert.throws(TypeError, () => { + new iter.forEach(() => {}); +}); + +assert.throws(TypeError, () => { + new Iterator.prototype.forEach(() => {}); +}); + +assert.throws(TypeError, () => { + new class extends Iterator {}.forEach(() => {}); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/forEach/prop-desc.js b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/prop-desc.js new file mode 100644 index 000000000000..01ce3e922791 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/prop-desc.js @@ -0,0 +1,25 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.forEach +description: > + Property descriptor of Iterator.prototype.forEach +info: | + Iterator.prototype.forEach + + * is the initial value of the Iterator.prototype.forEach property of the global object. + + 17 ECMAScript Standard Built-in Objects + + every other data property described in clauses 18 through 26 and in Annex B.2 + has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +features: [globalThis, iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Iterator.prototype, 'forEach', { + writable: true, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/forEach/proto.js b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/proto.js new file mode 100644 index 000000000000..1b21d9222217 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/proto.js @@ -0,0 +1,11 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.forEach +description: > + The value of the [[Prototype]] internal slot of Iterator.prototype.forEach is the + intrinsic object %Function%. +features: [iterator-helpers] +---*/ + +assert.sameValue(Object.getPrototypeOf(Iterator.prototype.forEach), Function.prototype); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/forEach/result-is-undefined.js b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/result-is-undefined.js new file mode 100644 index 000000000000..bd7f7975b509 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/result-is-undefined.js @@ -0,0 +1,18 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.forEach +description: > + Iterator.prototype.forEach returns undefined +features: [iterator-helpers] +---*/ +function* g() {} +let iter = g(); +assert.sameValue( + iter.forEach(() => {}), + undefined +); +assert.sameValue( + iter.forEach(() => 0), + undefined +); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/forEach/this-non-callable-next.js b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/this-non-callable-next.js new file mode 100644 index 000000000000..10a4772e43ba --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/this-non-callable-next.js @@ -0,0 +1,15 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.forEach +description: > + Iterator.prototype.forEach throws TypeError when its this value is an object with a non-callable next +info: | + %Iterator.prototype%.forEach ( fn ) + +features: [iterator-helpers] +flags: [] +---*/ +assert.throws(TypeError, function () { + Iterator.prototype.forEach.call({ next: 0 }, () => true); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/forEach/this-non-object.js b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/this-non-object.js new file mode 100644 index 000000000000..6f2058845a9e --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/this-non-object.js @@ -0,0 +1,24 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.forEach +description: > + Iterator.prototype.forEach throws TypeError when its this value is a non-object +info: | + %Iterator.prototype%.forEach ( fn ) + +features: [iterator-helpers] +flags: [] +---*/ +assert.throws(TypeError, function () { + Iterator.prototype.forEach.call(null, () => {}); +}); + +Object.defineProperty(Number.prototype, 'next', { + get: function () { + throw new Test262Error(); + }, +}); +assert.throws(TypeError, function () { + Iterator.prototype.forEach.call(0, () => {}); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/forEach/this-plain-iterator.js b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/this-plain-iterator.js new file mode 100644 index 000000000000..8ce4235b9000 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/forEach/this-plain-iterator.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.forEach +description: > + Iterator.prototype.forEach supports a this value that does not inherit from Iterator.prototype but implements the iterator protocol +info: | + %Iterator.prototype%.forEach ( fn ) + +features: [iterator-helpers] +flags: [] +---*/ +let iter = { + get next() { + let count = 3; + return function () { + --count; + return count >= 0 ? { done: false, value: count } : { done: true, value: undefined }; + }; + }, +}; + +let fnCalls = 0; +let result = Iterator.prototype.forEach.call(iter, function (v) { + ++fnCalls; +}); + +assert.sameValue(result, undefined); +assert.sameValue(fnCalls, 3); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/initial-value.js b/JSTests/test262/test/built-ins/Iterator/prototype/initial-value.js new file mode 100644 index 000000000000..82ab6afe2fa3 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/initial-value.js @@ -0,0 +1,23 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-iterator.prototype +description: > + The initial value of Iterator.prototype is %Iterator.prototype%. +info: | + Iterator.prototype + + The initial value of Iterator.prototype is %Iterator.prototype%. + + This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }. +features: [iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Iterator, 'prototype', { + value: Iterator.prototype, + writable: false, + enumerable: false, + configurable: false, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/map/argument-effect-order.js b/JSTests/test262/test/built-ins/Iterator/prototype/map/argument-effect-order.js new file mode 100644 index 000000000000..76c6fc55a15a --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/map/argument-effect-order.js @@ -0,0 +1,42 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.map +description: > + Arguments and this value are evaluated in the correct order +info: | + %Iterator.prototype%.map ( mapper ) + + 1. Let O be the this value. + 2. If O is not an Object, throw a TypeError exception. + 3. If IsCallable(mapper) is false, throw a TypeError exception. + 4. Let iterated be ? GetIteratorDirect(O). + +includes: [compareArray.js] +features: [iterator-helpers] +flags: [] +---*/ +let effects = []; + +assert.throws(TypeError, function () { + Iterator.prototype.map.call( + { + get next() { + effects.push('get next'); + return function () { + return { done: true, value: undefined }; + }; + }, + }, + { + valueOf() { + effects.push('valueOf mapper'); + return function () { + return []; + }; + }, + } + ); +}); + +assert.compareArray(effects, []); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/map/callable.js b/JSTests/test262/test/built-ins/Iterator/prototype/map/callable.js new file mode 100644 index 000000000000..fc70927b36fd --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/map/callable.js @@ -0,0 +1,13 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.map +description: > + Iterator.prototype.map is callable +features: [iterator-helpers] +---*/ +function* g() {} +Iterator.prototype.map.call(g(), () => 0); + +let iter = g(); +iter.map(() => 0); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/map/exhaustion-does-not-call-return.js b/JSTests/test262/test/built-ins/Iterator/prototype/map/exhaustion-does-not-call-return.js new file mode 100644 index 000000000000..e93c945ebd49 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/map/exhaustion-does-not-call-return.js @@ -0,0 +1,34 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.map +description: > + Underlying iterator return is not called when result iterator is exhausted +info: | + %Iterator.prototype%.map ( mapper ) + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + yield 0; + yield 1; + yield 2; +} + +class TestIterator extends Iterator { + get next() { + let n = g(); + return function() { + return n.next(); + }; + } + return() { + throw new Test262Error(); + } +} + +let iterator = new TestIterator().map(() => 0); +iterator.next(); +iterator.next(); +iterator.next(); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/map/get-next-method-only-once.js b/JSTests/test262/test/built-ins/Iterator/prototype/map/get-next-method-only-once.js new file mode 100644 index 000000000000..4971dfed3713 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/map/get-next-method-only-once.js @@ -0,0 +1,41 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.map +description: > + Gets the next method from the underlying iterator only once +info: | + %Iterator.prototype%.map ( mapper ) + + 4. Let iterated be ? GetIteratorDirect(O). + +features: [iterator-helpers] +flags: [] +---*/ +let nextGets = 0; +let nextCalls = 0; + +class CountingIterator extends Iterator { + get next() { + ++nextGets; + let iter = (function* () { + for (let i = 1; i < 5; ++i) { + yield i; + } + })(); + return function () { + ++nextCalls; + return iter.next(); + }; + } +} + +let iterator = new CountingIterator(); + +assert.sameValue(nextGets, 0); +assert.sameValue(nextCalls, 0); + +for (const value of iterator.map(() => 0)); + +assert.sameValue(nextGets, 1); +assert.sameValue(nextCalls, 5); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/map/get-next-method-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/map/get-next-method-throws.js new file mode 100644 index 000000000000..d0884cba5e15 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/map/get-next-method-throws.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.map +description: > + Underlying iterator has throwing next getter +info: | + %Iterator.prototype%.map ( mapper ) + + 4. Let iterated be ? GetIteratorDirect(O). + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + get next() { + throw new Test262Error(); + } +} + +let iterator = new ThrowingIterator(); + +assert.throws(Test262Error, function () { + iterator.map(() => 0); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/map/get-return-method-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/map/get-return-method-throws.js new file mode 100644 index 000000000000..4fc3299bba73 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/map/get-return-method-throws.js @@ -0,0 +1,30 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.map +description: > + Underlying iterator return is throwing getter +info: | + %Iterator.prototype%.map ( mapper ) + +features: [iterator-helpers] +flags: [] +---*/ +class TestIterator extends Iterator { + next() { + return { + done: false, + value: 1, + }; + } + get return() { + throw new Test262Error(); + } +} + +let iterator = new TestIterator().map(() => 0); +iterator.next(); + +assert.throws(Test262Error, function () { + iterator.return(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/map/is-function.js b/JSTests/test262/test/built-ins/Iterator/prototype/map/is-function.js new file mode 100644 index 000000000000..cbc51701ef9f --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/map/is-function.js @@ -0,0 +1,10 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.map +description: > + Iterator.prototype.map is a built-in function +features: [iterator-helpers] +---*/ + +assert.sameValue(typeof Iterator.prototype.map, 'function'); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/map/iterator-already-exhausted.js b/JSTests/test262/test/built-ins/Iterator/prototype/map/iterator-already-exhausted.js new file mode 100644 index 000000000000..05a0e7065337 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/map/iterator-already-exhausted.js @@ -0,0 +1,22 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.map +description: > + Iterator.prototype.map returns an empty iterator when the iterator has already been exhausted +info: | + %Iterator.prototype%.map ( mapper ) + +features: [iterator-helpers] +flags: [] +---*/ +let iterator = (function* () {})(); + +let { value, done } = iterator.next(); +assert.sameValue(value, undefined); +assert.sameValue(done, true); + +iterator = iterator.map(() => 0); +({ value, done } = iterator.next()); +assert.sameValue(value, undefined); +assert.sameValue(done, true); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/map/iterator-return-method-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/map/iterator-return-method-throws.js new file mode 100644 index 000000000000..69b67a279425 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/map/iterator-return-method-throws.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.map +description: > + Iterator has throwing return +info: | + %Iterator.prototype%.map ( mapper ) + +features: [iterator-helpers] +flags: [] +---*/ +class IteratorThrows extends Iterator { + next() { + return { + done: false, + value: 0, + }; + } + return() { + throw new Test262Error(); + } +} + +let iterator = new IteratorThrows().map(() => 0); + +assert.throws(Test262Error, function () { + iterator.return(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/map/length.js b/JSTests/test262/test/built-ins/Iterator/prototype/map/length.js new file mode 100644 index 000000000000..b6d4258b1acd --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/map/length.js @@ -0,0 +1,22 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.map +description: > + Iterator.prototype.map has a "length" property whose value is 1. +info: | + ECMAScript Standard Built-in Objects + + Unless otherwise specified, the length property of a built-in + Function object has the attributes { [[Writable]]: false, [[Enumerable]]: + false, [[Configurable]]: true }. +features: [iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Iterator.prototype.map, 'length', { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/map/mapper-args.js b/JSTests/test262/test/built-ins/Iterator/prototype/map/mapper-args.js new file mode 100644 index 000000000000..25994834a112 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/map/mapper-args.js @@ -0,0 +1,55 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.map +description: > + Iterator.prototype.map mapper is passed the yielded value and a counter as arguments +info: | + %Iterator.prototype%.map ( mapper ) + + 5.b.iv. Let mapped be Completion(Call(mapper, undefined, « value, 𝔽(counter) »)). + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + yield 'a'; + yield 'b'; + yield 'c'; + yield 'd'; + yield 'e'; +} + +let assertionCount = 0; +let iter = g().map((v, count) => { + switch (v) { + case 'a': + assert.sameValue(count, 0); + ++assertionCount; + return 0; + case 'b': + assert.sameValue(count, 1); + ++assertionCount; + return 1; + case 'c': + assert.sameValue(count, 2); + ++assertionCount; + return 2; + case 'd': + assert.sameValue(count, 3); + ++assertionCount; + return 3; + case 'e': + assert.sameValue(count, 4); + ++assertionCount; + return 4; + default: + throw new Error(); + } +}); + +assert.sameValue(assertionCount, 0); + +for (let i of iter); + +assert.sameValue(assertionCount, 5); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/map/mapper-this.js b/JSTests/test262/test/built-ins/Iterator/prototype/map/mapper-this.js new file mode 100644 index 000000000000..db3a611deac6 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/map/mapper-this.js @@ -0,0 +1,33 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.map +description: > + Iterator.prototype.map mapper this value is undefined +info: | + %Iterator.prototype%.map ( mapper ) + + 5.b.iv. Let mapped be Completion(Call(mapper, undefined, « value, 𝔽(counter) »)). + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + yield 0; +} + +let iter = g(); + +let expectedThis = function () { + return this; +}.call(undefined); + +let assertionCount = 0; +iter = iter.map(function (v, count) { + assert.sameValue(this, expectedThis); + ++assertionCount; + return v; +}); + +iter.next(); +assert.sameValue(assertionCount, 1); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/map/mapper-throws-then-closing-iterator-also-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/map/mapper-throws-then-closing-iterator-also-throws.js new file mode 100644 index 000000000000..9b0c772a2363 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/map/mapper-throws-then-closing-iterator-also-throws.js @@ -0,0 +1,40 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.map +description: > + Attempts to close iterator when mapper throws, but that throws +info: | + %Iterator.prototype%.map ( mapper ) + + 5.b.v. IfAbruptCloseIterator(mapped, iterated). + +features: [iterator-helpers] +flags: [] +---*/ +let returnCalls = 0; + +class TestIterator extends Iterator { + next() { + return { + done: false, + value: 1, + }; + } + return() { + ++returnCalls; + throw new Error(); + } +} + +let iterator = new TestIterator().map(() => { + throw new Test262Error(); +}); + +assert.sameValue(returnCalls, 0); + +assert.throws(Test262Error, function () { + iterator.next(); +}); + +assert.sameValue(returnCalls, 1); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/map/mapper-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/map/mapper-throws.js new file mode 100644 index 000000000000..e5142d0be248 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/map/mapper-throws.js @@ -0,0 +1,41 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.map +description: > + Closes iterator and throws when mapper throws +info: | + %Iterator.prototype%.map ( mapper ) + + 5.b.v. IfAbruptCloseIterator(mapped, iterated). + +features: [iterator-helpers] +flags: [] +---*/ +let returnCalls = 0; + +class TestIterator extends Iterator { + next() { + return { + done: false, + value: 1, + }; + } + return() { + ++returnCalls; + return {}; + } +} + +let callbackCalls = 0; +let iterator = new TestIterator().map(() => { + ++callbackCalls; + throw new Test262Error(); +}); + +assert.throws(Test262Error, function () { + iterator.next(); +}); + +assert.sameValue(callbackCalls, 1); +assert.sameValue(returnCalls, 1); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/map/name.js b/JSTests/test262/test/built-ins/Iterator/prototype/map/name.js new file mode 100644 index 000000000000..6815e789986c --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/map/name.js @@ -0,0 +1,29 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.map +description: > + The "name" property of Iterator.prototype.map +info: | + 17 ECMAScript Standard Built-in Objects + + Every built-in Function object, including constructors, that is not + identified as an anonymous function has a name property whose value is a + String. Unless otherwise specified, this value is the name that is given to + the function in this specification. + + ... + + Unless otherwise specified, the name property of a built-in Function + object, if it exists, has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +features: [iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Iterator.prototype.map, 'name', { + value: 'map', + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/map/next-method-returns-non-object.js b/JSTests/test262/test/built-ins/Iterator/prototype/map/next-method-returns-non-object.js new file mode 100644 index 000000000000..21f969105e0d --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/map/next-method-returns-non-object.js @@ -0,0 +1,23 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.map +description: > + Underlying iterator next returns non-object +info: | + %Iterator.prototype%.map ( mapper ) + +features: [iterator-helpers] +flags: [] +---*/ +class NonObjectIterator extends Iterator { + next() { + return null; + } +} + +let iterator = new NonObjectIterator().map(() => 0); + +assert.throws(TypeError, function () { + iterator.next(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/map/next-method-returns-throwing-done.js b/JSTests/test262/test/built-ins/Iterator/prototype/map/next-method-returns-throwing-done.js new file mode 100644 index 000000000000..c9da2ef6cb00 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/map/next-method-returns-throwing-done.js @@ -0,0 +1,31 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.map +description: > + Underlying iterator next returns object with throwing done getter +info: | + %Iterator.prototype%.map ( mapper ) + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + return { + get done() { + throw new Test262Error(); + }, + value: 1, + }; + } + return() { + throw new Error(); + } +} + +let iterator = new ThrowingIterator().map(() => 0); + +assert.throws(Test262Error, function () { + iterator.next(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/map/next-method-returns-throwing-value-done.js b/JSTests/test262/test/built-ins/Iterator/prototype/map/next-method-returns-throwing-value-done.js new file mode 100644 index 000000000000..d044cfb51635 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/map/next-method-returns-throwing-value-done.js @@ -0,0 +1,28 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.map +description: > + Underlying iterator next returns object with throwing value getter, but is already done +info: | + %Iterator.prototype%.map ( mapper ) + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + return { + done: true, + get value() { + throw new Test262Error(); + }, + }; + } + return() { + throw new Error(); + } +} + +let iterator = new ThrowingIterator().map(() => 0); +iterator.next(); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/map/next-method-returns-throwing-value.js b/JSTests/test262/test/built-ins/Iterator/prototype/map/next-method-returns-throwing-value.js new file mode 100644 index 000000000000..a34de32a0315 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/map/next-method-returns-throwing-value.js @@ -0,0 +1,31 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.map +description: > + Underlying iterator next returns object with throwing value getter +info: | + %Iterator.prototype%.map ( mapper ) + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + return { + done: false, + get value() { + throw new Test262Error(); + }, + }; + } + return() { + throw new Error(); + } +} + +let iterator = new ThrowingIterator().map(() => 0); + +assert.throws(Test262Error, function () { + iterator.next(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/map/next-method-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/map/next-method-throws.js new file mode 100644 index 000000000000..4a4480273cf4 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/map/next-method-throws.js @@ -0,0 +1,23 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.map +description: > + Underlying iterator has throwing next method +info: | + %Iterator.prototype%.map ( mapper ) + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + throw new Test262Error(); + } +} + +let iterator = new ThrowingIterator().map(() => 0); + +assert.throws(Test262Error, function () { + iterator.next(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/map/non-callable-mapper.js b/JSTests/test262/test/built-ins/Iterator/prototype/map/non-callable-mapper.js new file mode 100644 index 000000000000..dfa0c618f2ab --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/map/non-callable-mapper.js @@ -0,0 +1,20 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.map +description: > + Iterator.prototype.map expects to be called with a callable argument. +info: | + %Iterator.prototype%.map ( mapper ) + + 3. If IsCallable(mapper) is false, throw a TypeError exception. + +features: [iterator-helpers] +flags: [] +---*/ +let nonCallable = {}; +let iterator = (function* () {})(); + +assert.throws(TypeError, function () { + iterator.map(nonCallable); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/map/non-constructible.js b/JSTests/test262/test/built-ins/Iterator/prototype/map/non-constructible.js new file mode 100644 index 000000000000..a6cb47643026 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/map/non-constructible.js @@ -0,0 +1,28 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.map +description: > + Iterator.prototype.map is not constructible. + + Built-in function objects that are not identified as constructors do not implement the [[Construct]] internal method unless otherwise specified in the description of a particular function. +features: [iterator-helpers] +---*/ +function* g() {} +let iter = g(); + +assert.throws(TypeError, () => { + new iter.map(); +}); + +assert.throws(TypeError, () => { + new iter.map(() => 0); +}); + +assert.throws(TypeError, () => { + new Iterator.prototype.map(() => 0); +}); + +assert.throws(TypeError, () => { + new class extends Iterator {}.map(() => 0); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/map/prop-desc.js b/JSTests/test262/test/built-ins/Iterator/prototype/map/prop-desc.js new file mode 100644 index 000000000000..9d58c5fb679a --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/map/prop-desc.js @@ -0,0 +1,25 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.map +description: > + Property descriptor of Iterator.prototype.map +info: | + Iterator.prototype.map + + * is the initial value of the Iterator.prototype.map property of the global object. + + 17 ECMAScript Standard Built-in Objects + + Every other data property described in clauses 18 through 26 and in Annex B.2 + has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +features: [globalThis, iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Iterator.prototype, 'map', { + writable: true, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/map/proto.js b/JSTests/test262/test/built-ins/Iterator/prototype/map/proto.js new file mode 100644 index 000000000000..9d1851239ce0 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/map/proto.js @@ -0,0 +1,11 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.map +description: > + The value of the [[Prototype]] internal slot of Iterator.prototype.map is the + intrinsic object %FunctionPrototype%. +features: [iterator-helpers] +---*/ + +assert.sameValue(Object.getPrototypeOf(Iterator.prototype.map), Function.prototype); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/map/result-is-iterator.js b/JSTests/test262/test/built-ins/Iterator/prototype/map/result-is-iterator.js new file mode 100644 index 000000000000..66fa0d10b1ed --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/map/result-is-iterator.js @@ -0,0 +1,11 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.map +description: > + The value of the [[Prototype]] internal slot of the return value of Iterator.prototype.map is the + intrinsic object %IteratorHelperPrototype%. +features: [iterator-helpers] +---*/ + +assert((function* () {})().map(() => 0) instanceof Iterator, 'function*(){}().map(() => 0) must return an Iterator'); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/map/return-is-forwarded-to-underlying-iterator.js b/JSTests/test262/test/built-ins/Iterator/prototype/map/return-is-forwarded-to-underlying-iterator.js new file mode 100644 index 000000000000..a51ec50eb33a --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/map/return-is-forwarded-to-underlying-iterator.js @@ -0,0 +1,33 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.map +description: > + Underlying iterator return is called when result iterator is closed +info: | + %Iterator.prototype%.map ( mapper ) + +features: [iterator-helpers] +flags: [] +---*/ +let returnCount = 0; + +class TestIterator extends Iterator { + next() { + return { + done: false, + value: 1, + }; + } + return() { + ++returnCount; + return {}; + } +} + +let iterator = new TestIterator().map(() => 0); +assert.sameValue(returnCount, 0); +iterator.return(); +assert.sameValue(returnCount, 1); +iterator.return(); +assert.sameValue(returnCount, 1); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/map/return-is-not-forwarded-after-exhaustion.js b/JSTests/test262/test/built-ins/Iterator/prototype/map/return-is-not-forwarded-after-exhaustion.js new file mode 100644 index 000000000000..f3ca5fece992 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/map/return-is-not-forwarded-after-exhaustion.js @@ -0,0 +1,46 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.map +description: > + Underlying iterator return is not called after result iterator observes that underlying iterator is exhausted +info: | + %Iterator.prototype%.map ( mapper ) + +features: [iterator-helpers] +flags: [] +---*/ +let returnCount = 0; + +class TestIterator extends Iterator { + next() { + return { + done: true, + value: undefined, + }; + } + return() { + throw new Test262Error(); + } +} + +let iterator = new TestIterator().map(() => 0); +assert.throws(Test262Error, function () { + iterator.return(); +}); +iterator.next(); +iterator.return(); + +iterator = new TestIterator().map(() => 0); +iterator.next(); +iterator.return(); + +iterator = new TestIterator() + .map(x => x) + .map(x => x) + .map(x => x); +assert.throws(Test262Error, function () { + iterator.return(); +}); +iterator.next(); +iterator.return(); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/map/returned-iterator-yields-mapper-return-values.js b/JSTests/test262/test/built-ins/Iterator/prototype/map/returned-iterator-yields-mapper-return-values.js new file mode 100644 index 000000000000..5565de995a41 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/map/returned-iterator-yields-mapper-return-values.js @@ -0,0 +1,36 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.map +description: > + The values returned by the mapper are the values that are yielded by the iterator returned by map +info: | + %Iterator.prototype%.map ( mapper ) + + 5.b.vi. Let completion be Completion(Yield(mapped)). + +includes: [compareArray.js] +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + for (let i = 0; i < 5; ++i) { + yield i; + } +} + +assert.compareArray(Array.from(g()), [0, 1, 2, 3, 4]); +assert.compareArray(Array.from(g().map(x => x)), [0, 1, 2, 3, 4]); +assert.compareArray(Array.from(g().map(() => 0)), [0, 0, 0, 0, 0]); +assert.compareArray( + Array.from( + g() + .map(() => 0) + .map((v, c) => c) + ), + [0, 1, 2, 3, 4] +); +assert.compareArray(Array.from(g().map(x => x * 2)), [0, 2, 4, 6, 8]); + +let obj = {}; +assert.compareArray(Array.from(g().map(() => obj)), [obj, obj, obj, obj, obj]); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/map/this-non-callable-next.js b/JSTests/test262/test/built-ins/Iterator/prototype/map/this-non-callable-next.js new file mode 100644 index 000000000000..db127cb4c3a1 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/map/this-non-callable-next.js @@ -0,0 +1,17 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.map +description: > + Iterator.prototype.map throws TypeError when its this value is an object with a non-callable next +info: | + %Iterator.prototype%.map ( mapper ) + +features: [iterator-helpers] +flags: [] +---*/ +let iter = Iterator.prototype.map.call({ next: 0 }, () => 0); + +assert.throws(TypeError, function () { + iter.next(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/map/this-non-object.js b/JSTests/test262/test/built-ins/Iterator/prototype/map/this-non-object.js new file mode 100644 index 000000000000..e0d4480146c6 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/map/this-non-object.js @@ -0,0 +1,26 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.map +description: > + Iterator.prototype.map throws TypeError when its this value is a non-object +info: | + %Iterator.prototype%.map ( mapper ) + + 2. If O is not an Object, throw a TypeError exception. + +features: [iterator-helpers] +flags: [] +---*/ +assert.throws(TypeError, function () { + Iterator.prototype.map.call(null, () => 0); +}); + +Object.defineProperty(Number.prototype, 'next', { + get: function () { + throw new Test262Error(); + }, +}); +assert.throws(TypeError, function () { + Iterator.prototype.map.call(0, () => 0); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/map/this-plain-iterator.js b/JSTests/test262/test/built-ins/Iterator/prototype/map/this-plain-iterator.js new file mode 100644 index 000000000000..851eed8e2f8b --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/map/this-plain-iterator.js @@ -0,0 +1,31 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.map +description: > + Iterator.prototype.map supports a this value that does not inherit from Iterator.prototype but implements the iterator protocol +info: | + %Iterator.prototype%.map ( mapper ) + +features: [iterator-helpers] +flags: [] +---*/ +let iter = { + get next() { + let count = 3; + return function () { + --count; + return count >= 0 ? { done: false, value: count } : { done: true, value: undefined }; + }; + }, +}; + +let mapperCalls = 0; +iter = Iterator.prototype.map.call(iter, function (v) { + ++mapperCalls; + return v; +}); + +for (let e of iter); + +assert.sameValue(mapperCalls, 3); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/map/underlying-iterator-advanced-in-parallel.js b/JSTests/test262/test/built-ins/Iterator/prototype/map/underlying-iterator-advanced-in-parallel.js new file mode 100644 index 000000000000..bb95ca0765d2 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/map/underlying-iterator-advanced-in-parallel.js @@ -0,0 +1,42 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.map +description: > + Underlying iterator is advanced after calling map +info: | + %Iterator.prototype%.map ( mapper ) + +features: [iterator-helpers] +flags: [] +---*/ +let iterator = (function* () { + for (let i = 0; i < 5; ++i) { + yield i; + } +})(); + +let mapped = iterator.map(x => x); + +let { value, done } = iterator.next(); + +assert.sameValue(value, 0); +assert.sameValue(done, false); + +iterator.next(); +iterator.next(); + +({ value, done } = mapped.next()); + +assert.sameValue(value, 3); +assert.sameValue(done, false); + +({ value, done } = mapped.next()); + +assert.sameValue(value, 4); +assert.sameValue(done, false); + +({ value, done } = mapped.next()); + +assert.sameValue(value, undefined); +assert.sameValue(done, true); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/map/underlying-iterator-closed-in-parallel.js b/JSTests/test262/test/built-ins/Iterator/prototype/map/underlying-iterator-closed-in-parallel.js new file mode 100644 index 000000000000..c83679632ff8 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/map/underlying-iterator-closed-in-parallel.js @@ -0,0 +1,26 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.map +description: > + Underlying iterator is closed after calling map +info: | + %Iterator.prototype%.map ( mapper ) + +features: [iterator-helpers] +flags: [] +---*/ +let iterator = (function* () { + for (let i = 0; i < 5; ++i) { + yield i; + } +})(); + +let mapped = iterator.map(() => 0); + +iterator.return(); + +let { value, done } = mapped.next(); + +assert.sameValue(value, undefined); +assert.sameValue(done, true); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/map/underlying-iterator-closed.js b/JSTests/test262/test/built-ins/Iterator/prototype/map/underlying-iterator-closed.js new file mode 100644 index 000000000000..b49c27b793c3 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/map/underlying-iterator-closed.js @@ -0,0 +1,26 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.map +description: > + Underlying iterator is closed before calling map +info: | + %Iterator.prototype%.map ( mapper ) + +features: [iterator-helpers] +flags: [] +---*/ +let iterator = (function* () { + for (let i = 0; i < 5; ++i) { + yield i; + } +})(); + +iterator.return(); + +let mapped = iterator.map(() => 0); + +let { value, done } = mapped.next(); + +assert.sameValue(value, undefined); +assert.sameValue(done, true); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/reduce/argument-effect-order.js b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/argument-effect-order.js new file mode 100644 index 000000000000..25d809a2ca37 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/argument-effect-order.js @@ -0,0 +1,58 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.reduce +description: > + Arguments and this value are evaluated in the correct order +info: | + %Iterator.prototype%.reduce ( reducer ) + +includes: [compareArray.js] +features: [iterator-helpers] +flags: [] +---*/ +let effects = []; + +assert.throws(TypeError, function () { + Iterator.prototype.reduce.call( + { + get next() { + effects.push('get next'); + return function () { + return { done: true, value: undefined }; + }; + }, + }, + { + valueOf() { + effects.push('reducer valueOf'); + } + }, + { + valueOf() { + effects.push('initial value valueOf'); + } + } + ); +}); + +assert.compareArray(effects, []); + +Iterator.prototype.reduce.call( + { + get next() { + effects.push('get next'); + return function () { + return { done: true, value: undefined }; + }; + }, + }, + () => {}, + { + valueOf() { + effects.push('initial value valueOf'); + } + } +); + +assert.compareArray(effects, ['get next']); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/reduce/callable.js b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/callable.js new file mode 100644 index 000000000000..c1a4c343e438 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/callable.js @@ -0,0 +1,13 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.reduce +description: > + Iterator.prototype.reduce is callable +features: [iterator-helpers] +---*/ +function* g() {} +Iterator.prototype.reduce.call(g(), () => {}, 0); + +let iter = g(); +iter.reduce(() => {}, 0); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/reduce/get-next-method-only-once.js b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/get-next-method-only-once.js new file mode 100644 index 000000000000..89c30adb4ee7 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/get-next-method-only-once.js @@ -0,0 +1,36 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.reduce +description: > + Gets the next method from the iterator only once +info: | + %Iterator.prototype%.reduce ( reducer ) + +features: [iterator-helpers] +flags: [] +---*/ +let nextGets = 0; + +class TestIterator extends Iterator { + get next() { + ++nextGets; + let counter = 5; + return function () { + if (counter <= 0) { + return { done: true, value: undefined }; + } else { + return { done: false, value: --counter }; + } + }; + } +} + +let iterator = new TestIterator(); + +assert.sameValue(nextGets, 0); +assert.sameValue( + iterator.reduce(x => x), + 4 +); +assert.sameValue(nextGets, 1); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/reduce/get-next-method-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/get-next-method-throws.js new file mode 100644 index 000000000000..c3816f2651a0 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/get-next-method-throws.js @@ -0,0 +1,23 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.reduce +description: > + Iterator has throwing next getter +info: | + %Iterator.prototype%.reduce ( reducer ) + +features: [iterator-helpers] +flags: [] +---*/ +class IteratorThrows extends Iterator { + get next() { + throw new Test262Error(); + } +} + +let iterator = new IteratorThrows(); + +assert.throws(Test262Error, function () { + iterator.reduce(() => {}); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/reduce/is-function.js b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/is-function.js new file mode 100644 index 000000000000..4f144c588223 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/is-function.js @@ -0,0 +1,10 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.reduce +description: > + Iterator.prototype.reduce is a built-in function +features: [iterator-helpers] +---*/ + +assert.sameValue(typeof Iterator.prototype.reduce, 'function'); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/reduce/iterator-already-exhausted-initial-value.js b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/iterator-already-exhausted-initial-value.js new file mode 100644 index 000000000000..71f332cf1608 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/iterator-already-exhausted-initial-value.js @@ -0,0 +1,21 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.reduce +description: > + Iterator.prototype.reduce returns the initial value when the iterator has already been exhausted +info: | + %Iterator.prototype%.reduce ( reducer ) + +features: [iterator-helpers] +flags: [] +---*/ +let iterator = (function* () {})(); + +let { value, done } = iterator.next(); +assert.sameValue(value, undefined); +assert.sameValue(done, true); + +const initialValue = {}; +let result = iterator.reduce(() => {}, initialValue); +assert.sameValue(result, initialValue); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/reduce/iterator-already-exhausted-no-initial-value.js b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/iterator-already-exhausted-no-initial-value.js new file mode 100644 index 000000000000..22dec14757d2 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/iterator-already-exhausted-no-initial-value.js @@ -0,0 +1,21 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.reduce +description: > + Iterator.prototype.reduce without an initial value throws when the iterator has already been exhausted +info: | + %Iterator.prototype%.reduce ( reducer ) + +features: [iterator-helpers] +flags: [] +---*/ +let iterator = (function* () {})(); + +let { value, done } = iterator.next(); +assert.sameValue(value, undefined); +assert.sameValue(done, true); + +assert.throws(TypeError, function() { + iterator.reduce(() => {}); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/reduce/iterator-yields-once-initial-value.js b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/iterator-yields-once-initial-value.js new file mode 100644 index 000000000000..5f936c494648 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/iterator-yields-once-initial-value.js @@ -0,0 +1,35 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.reduce +description: > + Iterator.prototype.reduce calls reducer once for each value yielded by the underlying iterator when passed an initial value +info: | + %Iterator.prototype%.reduce ( reducer ) + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + yield 'a'; +} + +let iter = g(); + +let assertionCount = 0; +let initialValue = {}; +let result = iter.reduce((memo, v, count) => { + switch (v) { + case 'a': + assert.sameValue(memo, initialValue); + assert.sameValue(count, 0); + break; + default: + throw new Error(); + } + ++assertionCount; + return v; +}, initialValue); + +assert.sameValue(result, 'a'); +assert.sameValue(assertionCount, 1); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/reduce/iterator-yields-once-no-initial-value.js b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/iterator-yields-once-no-initial-value.js new file mode 100644 index 000000000000..38c4fdaaadae --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/iterator-yields-once-no-initial-value.js @@ -0,0 +1,26 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.reduce +description: > + Iterator.prototype.reduce calls reducer once for each value yielded by the underlying iterator except the first when not passed an initial value +info: | + %Iterator.prototype%.reduce ( reducer ) + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + yield 'a'; +} + +let iter = g(); + +let assertionCount = 0; +let result = iter.reduce((memo, v, count) => { + ++assertionCount; + return v; +}); + +assert.sameValue(result, 'a'); +assert.sameValue(assertionCount, 0); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/reduce/length.js b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/length.js new file mode 100644 index 000000000000..3b504529fea3 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/length.js @@ -0,0 +1,22 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.reduce +description: > + Iterator.prototype.reduce has a "length" property whose value is 1. +info: | + ECMAScript Standard Built-in Objects + + Unless otherwise specified, the length property of a built-in + Function object has the attributes { [[Writable]]: false, [[Enumerable]]: + false, [[Configurable]]: true }. +features: [iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Iterator.prototype.reduce, 'length', { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/reduce/name.js b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/name.js new file mode 100644 index 000000000000..d79e85887395 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/name.js @@ -0,0 +1,29 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.reduce +description: > + The "name" property of Iterator.prototype.reduce +info: | + 17 ECMAScript Standard Built-in Objects + + Every built-in Function object, including constructors, that is not + identified as an anonymous function has a name property whose value is a + String. Unless otherwise specified, this value is the name that is given to + the function in this specification. + + ... + + Unless otherwise specified, the name property of a built-in Function + object, if it exists, has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +features: [iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Iterator.prototype.reduce, 'name', { + value: 'reduce', + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/reduce/next-method-returns-non-object.js b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/next-method-returns-non-object.js new file mode 100644 index 000000000000..c23e1fd478df --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/next-method-returns-non-object.js @@ -0,0 +1,23 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.reduce +description: > + Underlying iterator next returns non-object +info: | + %Iterator.prototype%.reduce ( reducer ) + +features: [iterator-helpers] +flags: [] +---*/ +class NonObjectIterator extends Iterator { + next() { + return null; + } +} + +let iterator = new NonObjectIterator(); + +assert.throws(TypeError, function () { + iterator.reduce(() => {}); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/reduce/next-method-returns-throwing-done.js b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/next-method-returns-throwing-done.js new file mode 100644 index 000000000000..c855c5bc00b6 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/next-method-returns-throwing-done.js @@ -0,0 +1,31 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.reduce +description: > + Underlying iterator next returns object with throwing done getter +info: | + %Iterator.prototype%.reduce ( reducer ) + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + return { + get done() { + throw new Test262Error(); + }, + value: 1, + }; + } + return() { + throw new Error(); + } +} + +let iterator = new ThrowingIterator(); + +assert.throws(Test262Error, function () { + iterator.reduce(() => {}); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/reduce/next-method-returns-throwing-value-done.js b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/next-method-returns-throwing-value-done.js new file mode 100644 index 000000000000..4682a6e2a859 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/next-method-returns-throwing-value-done.js @@ -0,0 +1,28 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.reduce +description: > + Underlying iterator next returns object with throwing value getter, but is already done +info: | + %Iterator.prototype%.reduce ( reducer ) + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + return { + done: true, + get value() { + throw new Test262Error(); + }, + }; + } + return() { + throw new Error(); + } +} + +let iterator = new ThrowingIterator(); +iterator.reduce(() => {}, 0); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/reduce/next-method-returns-throwing-value.js b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/next-method-returns-throwing-value.js new file mode 100644 index 000000000000..900958e0a55e --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/next-method-returns-throwing-value.js @@ -0,0 +1,31 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.reduce +description: > + Underlying iterator next returns object with throwing value getter +info: | + %Iterator.prototype%.reduce ( reducer ) + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + return { + done: false, + get value() { + throw new Test262Error(); + }, + }; + } + return() { + throw new Error(); + } +} + +let iterator = new ThrowingIterator(); + +assert.throws(Test262Error, function () { + iterator.reduce(() => {}); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/reduce/next-method-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/next-method-throws.js new file mode 100644 index 000000000000..09cec5cdc4c3 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/next-method-throws.js @@ -0,0 +1,27 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.reduce +description: > + Underlying iterator has throwing next method +info: | + %Iterator.prototype%.reduce ( reducer ) + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + throw new Test262Error(); + } +} + +let iterator = new ThrowingIterator(); + +assert.throws(Test262Error, function () { + iterator.reduce(() => {}); +}); + +assert.throws(Test262Error, function () { + iterator.reduce(() => {}, 0); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/reduce/non-callable-reducer.js b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/non-callable-reducer.js new file mode 100644 index 000000000000..9a2cdd4810b0 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/non-callable-reducer.js @@ -0,0 +1,20 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.reduce +description: > + Iterator.prototype.reduce expects to be called with a callable argument. +info: | + %Iterator.prototype%.reduce ( reducer ) + +features: [iterator-helpers] +flags: [] +---*/ +let nonCallable = {}; +let iterator = (function* () { + yield 1; +})(); + +assert.throws(TypeError, function () { + iterator.reduce(nonCallable); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/reduce/non-constructible.js b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/non-constructible.js new file mode 100644 index 000000000000..83f6882b73de --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/non-constructible.js @@ -0,0 +1,32 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.reduce +description: > + Iterator.prototype.reduce is not constructible. + + Built-in function objects that are not identified as constructors do not implement the [[Construct]] internal method unless otherwise specified in the description of a particular function. +features: [iterator-helpers] +---*/ +function* g() {} +let iter = g(); + +assert.throws(TypeError, () => { + new iter.reduce(); +}); + +assert.throws(TypeError, () => { + new iter.reduce(() => {}); +}); + +assert.throws(TypeError, () => { + new iter.reduce(() => {}, 0); +}); + +assert.throws(TypeError, () => { + new Iterator.prototype.reduce(() => {}, 0); +}); + +assert.throws(TypeError, () => { + new class extends Iterator {}.reduce(() => {}, 0); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/reduce/prop-desc.js b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/prop-desc.js new file mode 100644 index 000000000000..1fca6a372a95 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/prop-desc.js @@ -0,0 +1,25 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.reduce +description: > + Property descriptor of Iterator.prototype.reduce +info: | + Iterator.prototype.reduce + + * is the initial value of the Iterator.prototype.reduce property of the global object. + + 17 ECMAScript Standard Built-in Objects + + every other data property described in clauses 18 through 26 and in Annex B.2 + has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +features: [globalThis, iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Iterator.prototype, 'reduce', { + writable: true, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/reduce/proto.js b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/proto.js new file mode 100644 index 000000000000..18f9123a5609 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/proto.js @@ -0,0 +1,11 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.reduce +description: > + The value of the [[Prototype]] internal slot of Iterator.prototype.reduce is the + intrinsic object %Function%. +features: [iterator-helpers] +---*/ + +assert.sameValue(Object.getPrototypeOf(Iterator.prototype.reduce), Function.prototype); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/reduce/reducer-args-initial-value.js b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/reducer-args-initial-value.js new file mode 100644 index 000000000000..1803917e81f4 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/reducer-args-initial-value.js @@ -0,0 +1,45 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.reduce +description: > + Iterator.prototype.reduce reducer is passed the yielded value and a counter as arguments +info: | + %Iterator.prototype%.reduce ( reducer ) + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + yield 'a'; + yield 'b'; + yield 'c'; +} + +let iter = g(); + +let assertionCount = 0; +let initialValue = {}; +let result = iter.reduce((memo, v, count) => { + switch (v) { + case 'a': + assert.sameValue(memo, initialValue); + assert.sameValue(count, 0); + break; + case 'b': + assert.sameValue(memo, 'a'); + assert.sameValue(count, 1); + break; + case 'c': + assert.sameValue(memo, 'b'); + assert.sameValue(count, 2); + break; + default: + throw new Error(); + } + ++assertionCount; + return v; +}, initialValue); + +assert.sameValue(result, 'c'); +assert.sameValue(assertionCount, 3); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/reduce/reducer-args-no-initial-value.js b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/reducer-args-no-initial-value.js new file mode 100644 index 000000000000..c1dfc6c24230 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/reducer-args-no-initial-value.js @@ -0,0 +1,41 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.reduce +description: > + Iterator.prototype.reduce reducer is passed the yielded value and a counter as arguments +info: | + %Iterator.prototype%.reduce ( reducer ) + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + yield 'a'; + yield 'b'; + yield 'c'; +} + +let iter = g(); + +let assertionCount = 0; +let result = iter.reduce((memo, v, count) => { + switch (v) { + case 'b': + assert.sameValue(memo, 'a'); + assert.sameValue(count, 1); + break; + case 'c': + assert.sameValue(memo, 'b'); + assert.sameValue(count, 2); + break; + case 'a': + default: + throw new Error(); + } + ++assertionCount; + return v; +}); + +assert.sameValue(result, 'c'); +assert.sameValue(assertionCount, 2); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/reduce/reducer-memo-can-be-any-type.js b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/reducer-memo-can-be-any-type.js new file mode 100644 index 000000000000..35a84a2152fc --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/reducer-memo-can-be-any-type.js @@ -0,0 +1,31 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.reduce +description: > + Iterator.prototype.reduce reducer can return any ECMAScript language value +info: | + %Iterator.prototype%.reduce ( reducer ) + +features: [iterator-helpers] +flags: [] +---*/ + +const values = [undefined, null, true, false, 0, -0, 1, NaN, Infinity, "string", Symbol(), 0n, {}, [], () => {}]; + +let iter = values[Symbol.iterator](); + +let assertionCount = 0; +let initialValue = {}; +let result = iter.reduce((memo, v, count) => { + if (count == 0) { + assert.sameValue(memo, initialValue); + } else { + assert.sameValue(memo, values[count - 1]); + } + ++assertionCount; + return v; +}, initialValue); + +assert.sameValue(result, values[values.length - 1]); +assert.sameValue(assertionCount, values.length); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/reduce/reducer-this.js b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/reducer-this.js new file mode 100644 index 000000000000..9932713b0a47 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/reducer-this.js @@ -0,0 +1,32 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.reduce +description: > + Iterator.prototype.reduce reducer this value is undefined +info: | + %Iterator.prototype%.reduce ( reducer ) + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + yield 0; + yield 1; +} + +let iter = g(); + +let expectedThis = function () { + return this; +}.call(undefined); + +let assertionCount = 0; +let result = iter.reduce(function (memo, v, count) { + assert.sameValue(this, expectedThis); + ++assertionCount; + return memo; +}); + +assert.sameValue(result, 0); +assert.sameValue(assertionCount, 1); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/reduce/reducer-throws-then-closing-iterator-also-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/reducer-throws-then-closing-iterator-also-throws.js new file mode 100644 index 000000000000..0eef70fa7535 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/reducer-throws-then-closing-iterator-also-throws.js @@ -0,0 +1,36 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.reduce +description: > + Attempts to close iterator when reducer throws, but that throws +info: | + %Iterator.prototype%.reduce ( reducer ) + +features: [iterator-helpers] +flags: [] +---*/ +let returnCalls = 0; + +class TestIterator extends Iterator { + next() { + return { + done: false, + value: 1, + }; + } + return() { + ++returnCalls; + throw new Error(); + } +} + +let iterator = new TestIterator(); + +assert.throws(Test262Error, function () { + iterator.reduce(() => { + throw new Test262Error(); + }); +}); + +assert.sameValue(returnCalls, 1); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/reduce/reducer-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/reducer-throws.js new file mode 100644 index 000000000000..d1cd088241ac --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/reducer-throws.js @@ -0,0 +1,40 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.reduce +description: > + Closes iterator and throws when reducer throws +info: | + %Iterator.prototype%.reduce ( reducer ) + +features: [iterator-helpers] +flags: [] +---*/ +let returnCalls = 0; + +class TestIterator extends Iterator { + next() { + return { + done: false, + value: 1, + }; + } + return() { + ++returnCalls; + return {}; + } +} + +let iterator = new TestIterator(); + +let callbackCalls = 0; + +assert.throws(Test262Error, function () { + iterator.reduce(() => { + ++callbackCalls; + throw new Test262Error(); + }); +}); + +assert.sameValue(callbackCalls, 1); +assert.sameValue(returnCalls, 1); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/reduce/this-non-callable-next.js b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/this-non-callable-next.js new file mode 100644 index 000000000000..48611726a201 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/this-non-callable-next.js @@ -0,0 +1,15 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.reduce +description: > + Iterator.prototype.reduce throws TypeError when its this value is an object with a non-callable next +info: | + %Iterator.prototype%.reduce ( reducer ) + +features: [iterator-helpers] +flags: [] +---*/ +assert.throws(TypeError, function () { + Iterator.prototype.reduce.call({ next: 0 }, () => {}, 0); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/reduce/this-non-object.js b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/this-non-object.js new file mode 100644 index 000000000000..5d9143e6752b --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/this-non-object.js @@ -0,0 +1,33 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.reduce +description: > + Iterator.prototype.reduce throws TypeError when its this value is a non-object +info: | + %Iterator.prototype%.reduce ( reducer ) + +features: [iterator-helpers] +flags: [] +---*/ +assert.throws(TypeError, function () { + Iterator.prototype.reduce.call(null, () => {}); +}); + +assert.throws(TypeError, function () { + Iterator.prototype.reduce.call(null, () => {}, 0); +}); + +Object.defineProperty(Number.prototype, 'next', { + get: function () { + throw new Test262Error(); + }, +}); + +assert.throws(TypeError, function () { + Iterator.prototype.reduce.call(0, () => {}); +}); + +assert.throws(TypeError, function () { + Iterator.prototype.reduce.call(0, () => {}, 0); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/reduce/this-plain-iterator.js b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/this-plain-iterator.js new file mode 100644 index 000000000000..2eddf1098a20 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/reduce/this-plain-iterator.js @@ -0,0 +1,32 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.reduce +description: > + Iterator.prototype.reduce supports a this value that does not inherit from Iterator.prototype but implements the iterator protocol +info: | + %Iterator.prototype%.reduce ( reducer ) + +includes: [compareArray.js] +features: [iterator-helpers] +flags: [] +---*/ +let iter = { + get next() { + let count = 3; + return function () { + --count; + return count >= 0 ? { done: false, value: count } : { done: true, value: undefined }; + }; + }, +}; + +let reducerCalls = 0; +let result = Iterator.prototype.reduce.call(iter, function (memo, v) { + ++reducerCalls; + memo.push(v); + return memo; +}, []); + +assert.compareArray(result, [2, 1, 0]); +assert.sameValue(reducerCalls, 3); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/some/argument-effect-order.js b/JSTests/test262/test/built-ins/Iterator/prototype/some/argument-effect-order.js new file mode 100644 index 000000000000..d45acefd848a --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/some/argument-effect-order.js @@ -0,0 +1,30 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.some +description: > + Arguments and this value are evaluated in the correct order +info: | + %Iterator.prototype%.some ( predicate ) + +includes: [compareArray.js] +features: [iterator-helpers] +flags: [] +---*/ +let effects = []; + +assert.throws(TypeError, function () { + Iterator.prototype.some.call( + { + get next() { + effects.push('get next'); + return function () { + return { done: true, value: undefined }; + }; + }, + }, + null + ); +}); + +assert.compareArray(effects, []); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/some/callable.js b/JSTests/test262/test/built-ins/Iterator/prototype/some/callable.js new file mode 100644 index 000000000000..568bb60aff36 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/some/callable.js @@ -0,0 +1,13 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.some +description: > + Iterator.prototype.some is callable +features: [iterator-helpers] +---*/ +function* g() {} +Iterator.prototype.some.call(g(), () => {}); + +let iter = g(); +iter.some(() => {}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/some/get-next-method-only-once.js b/JSTests/test262/test/built-ins/Iterator/prototype/some/get-next-method-only-once.js new file mode 100644 index 000000000000..9a0c94018638 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/some/get-next-method-only-once.js @@ -0,0 +1,36 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.some +description: > + Gets the next method from the iterator only once +info: | + %Iterator.prototype%.some ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +let nextGets = 0; + +class TestIterator extends Iterator { + get next() { + ++nextGets; + let counter = 5; + return function () { + if (counter < 0) { + return { done: true, value: undefined }; + } else { + return { done: false, value: --counter }; + } + }; + } +} + +let iterator = new TestIterator(); + +assert.sameValue(nextGets, 0); +assert.sameValue( + iterator.some(() => true), + true +); +assert.sameValue(nextGets, 1); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/some/get-next-method-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/some/get-next-method-throws.js new file mode 100644 index 000000000000..6617aa659d99 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/some/get-next-method-throws.js @@ -0,0 +1,23 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.some +description: > + Iterator has throwing next getter +info: | + %Iterator.prototype%.some ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +class IteratorThrows extends Iterator { + get next() { + throw new Test262Error(); + } +} + +let iterator = new IteratorThrows(); + +assert.throws(Test262Error, function () { + iterator.some(() => {}); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/some/get-return-method-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/some/get-return-method-throws.js new file mode 100644 index 000000000000..cce312d59c47 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/some/get-return-method-throws.js @@ -0,0 +1,29 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.some +description: > + Iterator has throwing return getter +info: | + %Iterator.prototype%.some ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +class IteratorThrows extends Iterator { + next() { + return { + done: false, + value: 0, + }; + } + get return() { + throw new Test262Error(); + } +} + +let iterator = new IteratorThrows([1, 2]); + +assert.throws(Test262Error, function () { + iterator.some(() => true); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/some/is-function.js b/JSTests/test262/test/built-ins/Iterator/prototype/some/is-function.js new file mode 100644 index 000000000000..47de2a93399a --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/some/is-function.js @@ -0,0 +1,10 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.some +description: > + Iterator.prototype.some is a built-in function +features: [iterator-helpers] +---*/ + +assert.sameValue(typeof Iterator.prototype.some, 'function'); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/some/iterator-already-exhausted.js b/JSTests/test262/test/built-ins/Iterator/prototype/some/iterator-already-exhausted.js new file mode 100644 index 000000000000..d1172dfab932 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/some/iterator-already-exhausted.js @@ -0,0 +1,23 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.some +description: > + Iterator.prototype.some returns true when the iterator has already been exhausted +info: | + %Iterator.prototype%.some ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +let iterator = (function* () {})(); + +let { value, done } = iterator.next(); +assert.sameValue(value, undefined); +assert.sameValue(done, true); + +let result = iterator.some(() => true); +assert.sameValue(result, false); + +result = iterator.some(() => false); +assert.sameValue(result, false); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/some/iterator-has-no-return.js b/JSTests/test262/test/built-ins/Iterator/prototype/some/iterator-has-no-return.js new file mode 100644 index 000000000000..28ed4c41b617 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/some/iterator-has-no-return.js @@ -0,0 +1,27 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.some +description: > + The underlying iterator is sometimes unable to be closed (has no return method) +info: | + %Iterator.prototype%.some ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +let iterator = [1, 2, 3, 4, 5][Symbol.iterator](); + +assert.sameValue(iterator.return, undefined); + +let ret = iterator.some(v => v > 3); + +assert.sameValue(ret, true); + +let { done, value } = iterator.next(); +assert.sameValue(done, false); +assert.sameValue(value, 5); + +({ done, value } = iterator.next()); +assert.sameValue(done, true); +assert.sameValue(value, undefined); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/some/iterator-return-method-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/some/iterator-return-method-throws.js new file mode 100644 index 000000000000..d15240ebbf4c --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/some/iterator-return-method-throws.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.some +description: > + Iterator has throwing return +info: | + %Iterator.prototype%.some ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +class IteratorThrows extends Iterator { + next() { + return { + done: false, + value: 0, + }; + } + return() { + throw new Test262Error(); + } +} + +let iterator = new IteratorThrows(); + +assert.throws(Test262Error, function () { + iterator.some(() => true); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/some/length.js b/JSTests/test262/test/built-ins/Iterator/prototype/some/length.js new file mode 100644 index 000000000000..8a790b22ca8d --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/some/length.js @@ -0,0 +1,22 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.some +description: > + Iterator.prototype.some has a "length" property whose value is 1. +info: | + ECMAScript Standard Built-in Objects + + Unless otherwise specified, the length property of a built-in + Function object has the attributes { [[Writable]]: false, [[Enumerable]]: + false, [[Configurable]]: true }. +features: [iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Iterator.prototype.some, 'length', { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/some/name.js b/JSTests/test262/test/built-ins/Iterator/prototype/some/name.js new file mode 100644 index 000000000000..6cd820c5c403 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/some/name.js @@ -0,0 +1,29 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.some +description: > + The "name" property of Iterator.prototype.some +info: | + 17 ECMAScript Standard Built-in Objects + + Every built-in Function object, including constructors, that is not + identified as an anonymous function has a name property whose value is a + String. Unless otherwise specified, this value is the name that is given to + the function in this specification. + + ... + + Unless otherwise specified, the name property of a built-in Function + object, if it exists, has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +features: [iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Iterator.prototype.some, 'name', { + value: 'some', + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/some/next-method-returns-non-object.js b/JSTests/test262/test/built-ins/Iterator/prototype/some/next-method-returns-non-object.js new file mode 100644 index 000000000000..6d1655a22d74 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/some/next-method-returns-non-object.js @@ -0,0 +1,23 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.some +description: > + Underlying iterator next returns non-object +info: | + %Iterator.prototype%.some ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +class NonObjectIterator extends Iterator { + next() { + return null; + } +} + +let iterator = new NonObjectIterator(); + +assert.throws(TypeError, function () { + iterator.some(() => {}); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/some/next-method-returns-throwing-done.js b/JSTests/test262/test/built-ins/Iterator/prototype/some/next-method-returns-throwing-done.js new file mode 100644 index 000000000000..a87f60929d25 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/some/next-method-returns-throwing-done.js @@ -0,0 +1,31 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.some +description: > + Underlying iterator next returns object with throwing done getter +info: | + %Iterator.prototype%.some ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + return { + get done() { + throw new Test262Error(); + }, + value: 1, + }; + } + return() { + throw new Error(); + } +} + +let iterator = new ThrowingIterator(); + +assert.throws(Test262Error, function () { + iterator.some(() => {}); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/some/next-method-returns-throwing-value-done.js b/JSTests/test262/test/built-ins/Iterator/prototype/some/next-method-returns-throwing-value-done.js new file mode 100644 index 000000000000..29cbded93509 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/some/next-method-returns-throwing-value-done.js @@ -0,0 +1,28 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.some +description: > + Underlying iterator next returns object with throwing value getter, but is already done +info: | + %Iterator.prototype%.some ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + return { + done: true, + get value() { + throw new Test262Error(); + }, + }; + } + return() { + throw new Error(); + } +} + +let iterator = new ThrowingIterator(); +iterator.some(() => {}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/some/next-method-returns-throwing-value.js b/JSTests/test262/test/built-ins/Iterator/prototype/some/next-method-returns-throwing-value.js new file mode 100644 index 000000000000..6293c1d5be1e --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/some/next-method-returns-throwing-value.js @@ -0,0 +1,31 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.some +description: > + Underlying iterator next returns object with throwing value getter +info: | + %Iterator.prototype%.some ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + return { + done: false, + get value() { + throw new Test262Error(); + }, + }; + } + return() { + throw new Error(); + } +} + +let iterator = new ThrowingIterator(); + +assert.throws(Test262Error, function () { + iterator.some(() => {}); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/some/next-method-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/some/next-method-throws.js new file mode 100644 index 000000000000..26b9623de9ba --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/some/next-method-throws.js @@ -0,0 +1,23 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.some +description: > + Underlying iterator has throwing next method +info: | + %Iterator.prototype%.some ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + throw new Test262Error(); + } +} + +let iterator = new ThrowingIterator(); + +assert.throws(Test262Error, function () { + iterator.some(() => {}); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/some/non-callable-predicate.js b/JSTests/test262/test/built-ins/Iterator/prototype/some/non-callable-predicate.js new file mode 100644 index 000000000000..3b9cf32fe6cb --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/some/non-callable-predicate.js @@ -0,0 +1,20 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.some +description: > + Iterator.prototype.some expects to be called with a callable argument. +info: | + %Iterator.prototype%.some ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +let nonCallable = {}; +let iterator = (function* () { + yield 1; +})(); + +assert.throws(TypeError, function () { + iterator.some(nonCallable); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/some/non-constructible.js b/JSTests/test262/test/built-ins/Iterator/prototype/some/non-constructible.js new file mode 100644 index 000000000000..ca15f4909592 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/some/non-constructible.js @@ -0,0 +1,28 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.some +description: > + Iterator.prototype.some is not constructible. + + Built-in function objects that are not identified as constructors do not implement the [[Construct]] internal method unless otherwise specified in the description of a particular function. +features: [iterator-helpers] +---*/ +function* g() {} +let iter = g(); + +assert.throws(TypeError, () => { + new iter.some(); +}); + +assert.throws(TypeError, () => { + new iter.some(() => {}); +}); + +assert.throws(TypeError, () => { + new Iterator.prototype.some(() => {}); +}); + +assert.throws(TypeError, () => { + new class extends Iterator {}.some(() => {}); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/some/predicate-args.js b/JSTests/test262/test/built-ins/Iterator/prototype/some/predicate-args.js new file mode 100644 index 000000000000..5868b375b5df --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/some/predicate-args.js @@ -0,0 +1,41 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.some +description: > + Iterator.prototype.some predicate is passed the yielded value and a counter as arguments +info: | + %Iterator.prototype%.some ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + yield 'a'; + yield 'b'; + yield 'c'; +} + +let iter = g(); + +let assertionCount = 0; +let result = iter.some((v, count) => { + switch (v) { + case 'a': + assert.sameValue(count, 0); + break; + case 'b': + assert.sameValue(count, 1); + break; + case 'c': + assert.sameValue(count, 2); + break; + default: + throw new Error(); + } + ++assertionCount; + return false; +}); + +assert.sameValue(result, false); +assert.sameValue(assertionCount, 3); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/some/predicate-returns-falsey-then-truthy.js b/JSTests/test262/test/built-ins/Iterator/prototype/some/predicate-returns-falsey-then-truthy.js new file mode 100644 index 000000000000..de62627f43a2 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/some/predicate-returns-falsey-then-truthy.js @@ -0,0 +1,32 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.some +description: > + Iterator.prototype.some returns true and closes the iterator when the predicate returns falsey for some iterated values and truthy for others +info: | + %Iterator.prototype%.some ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + for (let i = 0; i < 5; ++i) { + yield i; + } +} + +let iter = g(); + +let predicateCalls = 0; +let result = iter.some(v => { + ++predicateCalls; + return v > 2; +}); + +assert.sameValue(result, true); +assert.sameValue(predicateCalls, 4); + +let { done, value } = iter.next(); +assert.sameValue(done, true); +assert.sameValue(value, undefined); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/some/predicate-returns-falsey.js b/JSTests/test262/test/built-ins/Iterator/prototype/some/predicate-returns-falsey.js new file mode 100644 index 000000000000..69f0b42e4d6b --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/some/predicate-returns-falsey.js @@ -0,0 +1,21 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.some +description: > + Iterator.prototype.some returns false when the predicate returns falsey for all iterated values +info: | + %Iterator.prototype%.some ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + yield 0; + yield 1; + yield 2; + yield 3; +} + +let result = g().some(() => false); +assert.sameValue(result, false); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/some/predicate-returns-non-boolean.js b/JSTests/test262/test/built-ins/Iterator/prototype/some/predicate-returns-non-boolean.js new file mode 100644 index 000000000000..bd4e1d37c29b --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/some/predicate-returns-non-boolean.js @@ -0,0 +1,32 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.some +description: > + Iterator.prototype.some coerces predicate return value to boolean +info: | + %Iterator.prototype%.some ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + yield ''; + yield null; + yield undefined; + yield 0; + yield 1; + yield 2; + yield 3; +} + +let iter = g(); + +let predicateCalls = 0; +let result = iter.some(v => { + ++predicateCalls; + return v; +}); + +assert.sameValue(result, true); +assert.sameValue(predicateCalls, 5); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/some/predicate-returns-truthy.js b/JSTests/test262/test/built-ins/Iterator/prototype/some/predicate-returns-truthy.js new file mode 100644 index 000000000000..26484864c9bf --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/some/predicate-returns-truthy.js @@ -0,0 +1,32 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.some +description: > + Iterator.prototype.some returns true and closes the iterator when the predicate returns truthy immediately +info: | + %Iterator.prototype%.some ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + yield 0; + yield 1; + yield 2; +} + +let iter = g(); + +let predicateCalls = 0; +let result = iter.some(v => { + ++predicateCalls; + return true; +}); + +assert.sameValue(result, true); +assert.sameValue(predicateCalls, 1); + +let { done, value } = iter.next(); +assert.sameValue(done, true); +assert.sameValue(value, undefined); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/some/predicate-this.js b/JSTests/test262/test/built-ins/Iterator/prototype/some/predicate-this.js new file mode 100644 index 000000000000..0574184fe0a9 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/some/predicate-this.js @@ -0,0 +1,31 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.some +description: > + Iterator.prototype.some predicate this value is undefined +info: | + %Iterator.prototype%.some ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + yield 0; +} + +let iter = g(); + +let expectedThis = function () { + return this; +}.call(undefined); + +let assertionCount = 0; +let result = iter.some(function (v, count) { + assert.sameValue(this, expectedThis); + ++assertionCount; + return true; +}); + +assert.sameValue(result, true); +assert.sameValue(assertionCount, 1); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/some/predicate-throws-then-closing-iterator-also-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/some/predicate-throws-then-closing-iterator-also-throws.js new file mode 100644 index 000000000000..92bbda696f5f --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/some/predicate-throws-then-closing-iterator-also-throws.js @@ -0,0 +1,36 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.some +description: > + Attempts to close iterator when predicate throws, but that throws +info: | + %Iterator.prototype%.some ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +let returnCalls = 0; + +class TestIterator extends Iterator { + next() { + return { + done: false, + value: 1, + }; + } + return() { + ++returnCalls; + throw new Error(); + } +} + +let iterator = new TestIterator(); + +assert.throws(Test262Error, function () { + iterator.some(() => { + throw new Test262Error(); + }); +}); + +assert.sameValue(returnCalls, 1); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/some/predicate-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/some/predicate-throws.js new file mode 100644 index 000000000000..91cdd170baec --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/some/predicate-throws.js @@ -0,0 +1,40 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.some +description: > + Closes iterator and throws when predicate throws +info: | + %Iterator.prototype%.some ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +let returnCalls = 0; + +class TestIterator extends Iterator { + next() { + return { + done: false, + value: 1, + }; + } + return() { + ++returnCalls; + return {}; + } +} + +let iterator = new TestIterator(); + +let callbackCalls = 0; + +assert.throws(Test262Error, function () { + iterator.some(() => { + ++callbackCalls; + throw new Test262Error(); + }); +}); + +assert.sameValue(callbackCalls, 1); +assert.sameValue(returnCalls, 1); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/some/prop-desc.js b/JSTests/test262/test/built-ins/Iterator/prototype/some/prop-desc.js new file mode 100644 index 000000000000..80733f8f24d2 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/some/prop-desc.js @@ -0,0 +1,25 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.some +description: > + Property descriptor of Iterator.prototype.some +info: | + Iterator.prototype.some + + * is the initial value of the Iterator.prototype.some property of the global object. + + 17 ECMAScript Standard Built-in Objects + + every other data property described in clauses 18 through 26 and in Annex B.2 + has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +features: [globalThis, iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Iterator.prototype, 'some', { + writable: true, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/some/proto.js b/JSTests/test262/test/built-ins/Iterator/prototype/some/proto.js new file mode 100644 index 000000000000..d32cc0cbe14d --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/some/proto.js @@ -0,0 +1,11 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.some +description: > + The value of the [[Prototype]] internal slot of Iterator.prototype.some is the + intrinsic object %Function%. +features: [iterator-helpers] +---*/ + +assert.sameValue(Object.getPrototypeOf(Iterator.prototype.some), Function.prototype); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/some/result-is-boolean.js b/JSTests/test262/test/built-ins/Iterator/prototype/some/result-is-boolean.js new file mode 100644 index 000000000000..f4ae3566418a --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/some/result-is-boolean.js @@ -0,0 +1,11 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.some +description: > + Iterator.prototype.some returns a boolean +features: [iterator-helpers] +---*/ +function* g() {} +let iter = g(); +assert.sameValue(typeof iter.some(() => {}), 'boolean'); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/some/this-non-callable-next.js b/JSTests/test262/test/built-ins/Iterator/prototype/some/this-non-callable-next.js new file mode 100644 index 000000000000..ad46eafd16b0 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/some/this-non-callable-next.js @@ -0,0 +1,15 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.some +description: > + Iterator.prototype.some throws TypeError when its this value is an object with a non-callable next +info: | + %Iterator.prototype%.some ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +assert.throws(TypeError, function () { + Iterator.prototype.some.call({ next: 0 }, () => true); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/some/this-non-object.js b/JSTests/test262/test/built-ins/Iterator/prototype/some/this-non-object.js new file mode 100644 index 000000000000..8ae3b60c7817 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/some/this-non-object.js @@ -0,0 +1,24 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.some +description: > + Iterator.prototype.some throws TypeError when its this value is a non-object +info: | + %Iterator.prototype%.some ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +assert.throws(TypeError, function () { + Iterator.prototype.some.call(null, () => {}); +}); + +Object.defineProperty(Number.prototype, 'next', { + get: function () { + throw new Test262Error(); + }, +}); +assert.throws(TypeError, function () { + Iterator.prototype.some.call(0, () => {}); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/some/this-plain-iterator.js b/JSTests/test262/test/built-ins/Iterator/prototype/some/this-plain-iterator.js new file mode 100644 index 000000000000..40038d4e4b19 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/some/this-plain-iterator.js @@ -0,0 +1,30 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.some +description: > + Iterator.prototype.some supports a this value that does not inherit from Iterator.prototype but implements the iterator protocol +info: | + %Iterator.prototype%.some ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ +let iter = { + get next() { + let count = 3; + return function () { + --count; + return count >= 0 ? { done: false, value: count } : { done: true, value: undefined }; + }; + }, +}; + +let predicateCalls = 0; +let result = Iterator.prototype.some.call(iter, function (v) { + ++predicateCalls; + return v === 0; +}); + +assert.sameValue(result, true); +assert.sameValue(predicateCalls, 3); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/take/argument-effect-order.js b/JSTests/test262/test/built-ins/Iterator/prototype/take/argument-effect-order.js new file mode 100644 index 000000000000..d37557cd7393 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/take/argument-effect-order.js @@ -0,0 +1,72 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.take +description: > + Arguments and this value are evaluated in the correct order +info: | + %Iterator.prototype%.take ( limit ) + + 1. Let O be the this value. + 2. If O is not an Object, throw a TypeError exception. + 3. Let numLimit be ? ToNumber(limit). + 4. If numLimit is NaN, throw a RangeError exception. + 5. Let integerLimit be ! ToIntegerOrInfinity(numLimit). + 6. If integerLimit < 0, throw a RangeError exception. + 7. Let iterated be ? GetIteratorDirect(O). + +includes: [compareArray.js] +features: [iterator-helpers] +flags: [] +---*/ +let effects = []; + +Iterator.prototype.take.call( + { + get next() { + effects.push('get next'); + return function () { + return { done: true, value: undefined }; + }; + }, + }, + { + valueOf() { + effects.push('ToNumber limit'); + return 0; + }, + } +); + +assert.compareArray(effects, ['ToNumber limit', 'get next']); + +effects = []; + +assert.throws(TypeError, function () { + Iterator.prototype.take.call(null, { + valueOf() { + effects.push('ToNumber limit'); + return 0; + }, + }); +}); + +assert.compareArray(effects, []); + +effects = []; + +assert.throws(RangeError, function () { + Iterator.prototype.take.call( + { + get next() { + effects.push('get next'); + return function () { + return { done: true, value: undefined }; + }; + }, + }, + NaN + ); +}); + +assert.compareArray(effects, []); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/take/callable.js b/JSTests/test262/test/built-ins/Iterator/prototype/take/callable.js new file mode 100644 index 000000000000..75b1517a9533 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/take/callable.js @@ -0,0 +1,13 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.take +description: > + Iterator.prototype.take is callable +features: [iterator-helpers] +---*/ +function* g() {} +Iterator.prototype.take.call(g(), 0); + +let iter = g(); +iter.take(0); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/take/exhaustion-calls-return.js b/JSTests/test262/test/built-ins/Iterator/prototype/take/exhaustion-calls-return.js new file mode 100644 index 000000000000..ae50a2a7dd08 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/take/exhaustion-calls-return.js @@ -0,0 +1,68 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.take +description: > + Underlying iterator return is called when result iterator is exhausted +info: | + %Iterator.prototype%.take ( limit ) + + 8.b.i. If remaining is 0, then + 8.b.i.1. Return ? IteratorClose(iterated, NormalCompletion(undefined)). + +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + yield 0; + yield 1; + yield 2; +} + +class TestIterator extends Iterator { + get next() { + let n = g(); + return function() { + return n.next(); + }; + } + return() { + throw new Test262Error(); + } +} + +let iterator = new TestIterator(); +iterator = iterator.take(0); +assert.throws(Test262Error, function () { + iterator.next(); +}); +iterator.next(); +iterator.next(); + +iterator = new TestIterator(); +iterator = iterator.take(1); +iterator.next(); +assert.throws(Test262Error, function () { + iterator.next(); +}); +iterator.next(); +iterator.next(); + +iterator = new TestIterator(); +iterator = iterator.take(1).take(1).take(1).take(1).take(1); +iterator.next(); +assert.throws(Test262Error, function () { + iterator.next(); +}); +iterator.next(); +iterator.next(); + +iterator = new TestIterator(); +iterator = iterator.take(5); +iterator.next(); +iterator.next(); +iterator.next(); +iterator.next(); +iterator.next(); +iterator.next(); +iterator.next(); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/take/get-next-method-only-once.js b/JSTests/test262/test/built-ins/Iterator/prototype/take/get-next-method-only-once.js new file mode 100644 index 000000000000..8a9b8ae33503 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/take/get-next-method-only-once.js @@ -0,0 +1,41 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.take +description: > + Gets the next method from the underlying iterator only once +info: | + %Iterator.prototype%.take ( limit ) + + 7. Let iterated be ? GetIteratorDirect(this value). + +features: [iterator-helpers] +flags: [] +---*/ +let nextGets = 0; +let nextCalls = 0; + +class CountingIterator extends Iterator { + get next() { + ++nextGets; + let iter = (function* () { + for (let i = 1; i < 5; ++i) { + yield i; + } + })(); + return function () { + ++nextCalls; + return iter.next(); + }; + } +} + +let iterator = new CountingIterator(); + +assert.sameValue(nextGets, 0); +assert.sameValue(nextCalls, 0); + +for (const value of iterator.take(2)); + +assert.sameValue(nextGets, 1); +assert.sameValue(nextCalls, 2); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/take/get-next-method-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/take/get-next-method-throws.js new file mode 100644 index 000000000000..0a0abc9df7e0 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/take/get-next-method-throws.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.take +description: > + Underlying iterator has throwing next getter +info: | + %Iterator.prototype%.take ( limit ) + + 7. Let iterated be ? GetIteratorDirect(this value). + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + get next() { + throw new Test262Error(); + } +} + +let iterator = new ThrowingIterator(); + +assert.throws(Test262Error, function () { + iterator.take(0); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/take/get-return-method-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/take/get-return-method-throws.js new file mode 100644 index 000000000000..291a25beb63e --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/take/get-return-method-throws.js @@ -0,0 +1,30 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.take +description: > + Underlying iterator return is throwing getter +info: | + %Iterator.prototype%.take ( limit ) + +features: [iterator-helpers] +flags: [] +---*/ +class TestIterator extends Iterator { + next() { + return { + done: false, + value: 1, + }; + } + get return() { + throw new Test262Error(); + } +} + +let iterator = new TestIterator().take(1); +iterator.next(); + +assert.throws(Test262Error, function () { + iterator.return(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/take/is-function.js b/JSTests/test262/test/built-ins/Iterator/prototype/take/is-function.js new file mode 100644 index 000000000000..5e3cacfc8e75 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/take/is-function.js @@ -0,0 +1,10 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.take +description: > + Iterator.prototype.take is a built-in function +features: [iterator-helpers] +---*/ + +assert.sameValue(typeof Iterator.prototype.take, 'function'); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/take/length.js b/JSTests/test262/test/built-ins/Iterator/prototype/take/length.js new file mode 100644 index 000000000000..b7a0e2993984 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/take/length.js @@ -0,0 +1,22 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.take +description: > + Iterator.prototype.take has a "length" property whose value is 1. +info: | + ECMAScript Standard Built-in Objects + + Unless otherwise specified, the length property of a built-in + Function object has the attributes { [[Writable]]: false, [[Enumerable]]: + false, [[Configurable]]: true }. +features: [iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Iterator.prototype.take, 'length', { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/take/limit-greater-than-or-equal-to-total.js b/JSTests/test262/test/built-ins/Iterator/prototype/take/limit-greater-than-or-equal-to-total.js new file mode 100644 index 000000000000..2fe3e77bf898 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/take/limit-greater-than-or-equal-to-total.js @@ -0,0 +1,27 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.take +description: > + Takes entries from this iterator until it is exhausted or the limit is reached. +info: | + %Iterator.prototype%.take ( limit ) + + 8.b.iii. Let next be ? IteratorStep(iterated). + 8.b.iv. If next is false, return undefined. + +includes: [compareArray.js] +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + yield 0; + yield 1; + yield 2; +} + +assert.compareArray(Array.from(g().take(3)), [0, 1, 2]); +assert.compareArray(Array.from(g().take(4)), [0, 1, 2]); +assert.compareArray(Array.from(g().take(5)), [0, 1, 2]); +assert.compareArray(Array.from(g().take(Number.MAX_SAFE_INTEGER)), [0, 1, 2]); +assert.compareArray(Array.from(g().take(Infinity)), [0, 1, 2]); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/take/limit-less-than-total.js b/JSTests/test262/test/built-ins/Iterator/prototype/take/limit-less-than-total.js new file mode 100644 index 000000000000..d9a868997854 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/take/limit-less-than-total.js @@ -0,0 +1,28 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.take +description: > + Takes entries from this iterator until the limit is reached. +info: | + %Iterator.prototype%.take ( limit ) + + 8.b.i If remaining is 0, then + 8.b.i.1. Return ? IteratorClose(iterated, NormalCompletion(undefined)). + +includes: [compareArray.js] +features: [iterator-helpers] +flags: [] +---*/ +function* g() { + let i = 0; + while (true) { + yield i; + ++i; + } +} + +assert.compareArray(Array.from(g().take(0)), []); +assert.compareArray(Array.from(g().take(1)), [0]); +assert.compareArray(Array.from(g().take(2)), [0, 1]); +assert.compareArray(Array.from(g().take(3)), [0, 1, 2]); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/take/limit-rangeerror.js b/JSTests/test262/test/built-ins/Iterator/prototype/take/limit-rangeerror.js new file mode 100644 index 000000000000..f303d192d747 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/take/limit-rangeerror.js @@ -0,0 +1,36 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.take +description: > + Throws a RangeError exception when limit argument is NaN or less than 0. +info: | + %Iterator.prototype%.take ( limit ) + + 4. If numLimit is NaN, throw a RangeError exception. + 5. Let integerLimit be ! ToIntegerOrInfinity(numLimit). + 6. If integerLimit < 0, throw a RangeError exception. + +features: [iterator-helpers] +---*/ +let iterator = (function* () {})(); + +iterator.take(0); +iterator.take(-0.5); +iterator.take(null); + +assert.throws(RangeError, () => { + iterator.take(-1); +}); + +assert.throws(RangeError, () => { + iterator.take(); +}); + +assert.throws(RangeError, () => { + iterator.take(undefined); +}); + +assert.throws(RangeError, () => { + iterator.take(NaN); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/take/limit-tonumber-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/take/limit-tonumber-throws.js new file mode 100644 index 000000000000..1859590deabb --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/take/limit-tonumber-throws.js @@ -0,0 +1,22 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.take +description: > + Throws a RangeError exception when limit argument valueOf throws. +info: | + %Iterator.prototype%.take ( limit ) + + 3. Let numLimit be ? ToNumber(limit). + +features: [iterator-helpers] +---*/ +let iterator = (function* () {})(); + +assert.throws(Test262Error, () => { + iterator.take({ + valueOf: function () { + throw new Test262Error(); + }, + }); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/take/limit-tonumber.js b/JSTests/test262/test/built-ins/Iterator/prototype/take/limit-tonumber.js new file mode 100644 index 000000000000..ad870abb630b --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/take/limit-tonumber.js @@ -0,0 +1,61 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.take +description: > + Converts the limit argument to a Number using ToNumber and valueOf/toString. +info: | + %Iterator.prototype%.take ( limit ) + + 3. Let numLimit be ? ToNumber(limit). + +includes: [compareArray.js] +features: [iterator-helpers] +---*/ +function* g() { + yield 0; + yield 1; + yield 2; +} + +assert.compareArray( + Array.from( + g().take({ + valueOf: function () { + return 0; + }, + }) + ), + [] +); +assert.compareArray( + Array.from( + g().take({ + valueOf: function () { + return 1; + }, + }) + ), + [0] +); +assert.compareArray( + Array.from( + g().take({ + valueOf: function () { + return 2; + }, + }) + ), + [0, 1] +); +assert.compareArray(Array.from(g().take([1])), [0]); +assert.compareArray( + Array.from( + g().take({ + toString: function () { + return '1'; + }, + }) + ), + [0] +); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/take/name.js b/JSTests/test262/test/built-ins/Iterator/prototype/take/name.js new file mode 100644 index 000000000000..9b3dfe65eb0c --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/take/name.js @@ -0,0 +1,29 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.take +description: > + The "name" property of Iterator.prototype.take +info: | + 17 ECMAScript Standard Built-in Objects + + Every built-in Function object, including constructors, that is not + identified as an anonymous function has a name property whose value is a + String. Unless otherwise specified, this value is the name that is given to + the function in this specification. + + ... + + Unless otherwise specified, the name property of a built-in Function + object, if it exists, has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +features: [iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Iterator.prototype.take, 'name', { + value: 'take', + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/take/next-method-returns-non-object.js b/JSTests/test262/test/built-ins/Iterator/prototype/take/next-method-returns-non-object.js new file mode 100644 index 000000000000..d3535d6816a3 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/take/next-method-returns-non-object.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.take +description: > + Underlying iterator next returns non-object +info: | + %Iterator.prototype%.take ( limit ) + + 8.b.iii. Let next be ? IteratorStep(iterated). + +features: [iterator-helpers] +flags: [] +---*/ +class NonObjectIterator extends Iterator { + next() { + return null; + } +} + +let iterator = new NonObjectIterator().take(0); + +iterator.next(); + +iterator = new NonObjectIterator().take(1); + +assert.throws(TypeError, function () { + iterator.next(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/take/next-method-returns-throwing-done.js b/JSTests/test262/test/built-ins/Iterator/prototype/take/next-method-returns-throwing-done.js new file mode 100644 index 000000000000..aedc2236674e --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/take/next-method-returns-throwing-done.js @@ -0,0 +1,42 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.take +description: > + Underlying iterator next returns object with throwing done getter +info: | + %Iterator.prototype%.take ( limit ) + + 8.b.iii. Let next be ? IteratorStep(iterated). + +features: [iterator-helpers] +flags: [] +---*/ +class ReturnCalledError extends Error {} +class DoneGetterError extends Error {} + +class ThrowingIterator extends Iterator { + next() { + return { + get done() { + throw new DoneGetterError(); + }, + value: 1, + }; + } + return() { + throw new ReturnCalledError(); + } +} + +let iterator = new ThrowingIterator().take(0); + +assert.throws(ReturnCalledError, function () { + iterator.next(); +}); + +iterator = new ThrowingIterator().take(1); + +assert.throws(DoneGetterError, function () { + iterator.next(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/take/next-method-returns-throwing-value-done.js b/JSTests/test262/test/built-ins/Iterator/prototype/take/next-method-returns-throwing-value-done.js new file mode 100644 index 000000000000..b464442756df --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/take/next-method-returns-throwing-value-done.js @@ -0,0 +1,36 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.take +description: > + Underlying iterator next returns object with throwing value getter, but is already done +info: | + %Iterator.prototype%.take ( limit ) + +features: [iterator-helpers] +flags: [] +---*/ +class ReturnCalledError extends Error {} +class ValueGetterError extends Error {} + +class ThrowingIterator extends Iterator { + next() { + return { + done: true, + get value() { + throw new ValueGetterError(); + }, + }; + } + return() { + throw new ReturnCalledError(); + } +} + +let iterator = new ThrowingIterator().take(0); +assert.throws(ReturnCalledError, function () { + iterator.next(); +}); + +iterator = new ThrowingIterator().take(1); +iterator.next(); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/take/next-method-returns-throwing-value.js b/JSTests/test262/test/built-ins/Iterator/prototype/take/next-method-returns-throwing-value.js new file mode 100644 index 000000000000..60d9509a3ddb --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/take/next-method-returns-throwing-value.js @@ -0,0 +1,42 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.take +description: > + Underlying iterator next returns object with throwing value getter +info: | + %Iterator.prototype%.take ( limit ) + + 8.b.v. Let completion be Completion(Yield(? IteratorValue(next))). + +features: [iterator-helpers] +flags: [] +---*/ +class ReturnCalledError extends Error {} +class ValueGetterError extends Error {} + +class ThrowingIterator extends Iterator { + next() { + return { + done: false, + get value() { + throw new ValueGetterError(); + }, + }; + } + return() { + throw new ReturnCalledError(); + } +} + +let iterator = new ThrowingIterator().take(0); + +assert.throws(ReturnCalledError, function () { + iterator.next(); +}); + +iterator = new ThrowingIterator().take(1); + +assert.throws(ValueGetterError, function () { + iterator.next(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/take/next-method-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/take/next-method-throws.js new file mode 100644 index 000000000000..8556583de031 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/take/next-method-throws.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.take +description: > + Underlying iterator has throwing next method +info: | + %Iterator.prototype%.take ( limit ) + + 8.b.iii. Let next be ? IteratorStep(iterated). + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + throw new Test262Error(); + } +} + +let iterator = new ThrowingIterator().take(0); + +iterator.next(); + +iterator = new ThrowingIterator().take(1); + +assert.throws(Test262Error, function () { + iterator.next(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/take/non-constructible.js b/JSTests/test262/test/built-ins/Iterator/prototype/take/non-constructible.js new file mode 100644 index 000000000000..6fb0a43e72c6 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/take/non-constructible.js @@ -0,0 +1,28 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.take +description: > + Iterator.prototype.take is not constructible. + + Built-in function objects that are not identified as constructors do not implement the [[Construct]] internal method unless otherwise specified in the description of a particular function. +features: [iterator-helpers] +---*/ +function* g() {} +let iter = g(); + +assert.throws(TypeError, () => { + new iter.take(); +}); + +assert.throws(TypeError, () => { + new iter.take(0); +}); + +assert.throws(TypeError, () => { + new Iterator.prototype.take(0); +}); + +assert.throws(TypeError, () => { + new class extends Iterator {}.take(0); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/take/prop-desc.js b/JSTests/test262/test/built-ins/Iterator/prototype/take/prop-desc.js new file mode 100644 index 000000000000..cd8f19f174ae --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/take/prop-desc.js @@ -0,0 +1,25 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.take +description: > + Property descriptor of Iterator.prototype.take +info: | + Iterator.prototype.take + + * is the initial value of the Iterator.prototype.take property of the global object. + + 17 ECMAScript Standard Built-in Objects + + Every other data property described in clauses 18 through 26 and in Annex B.2 + has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +features: [globalThis, iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Iterator.prototype, 'take', { + writable: true, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/take/proto.js b/JSTests/test262/test/built-ins/Iterator/prototype/take/proto.js new file mode 100644 index 000000000000..6e1e63dcce6d --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/take/proto.js @@ -0,0 +1,11 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.take +description: > + The value of the [[Prototype]] internal slot of Iterator.prototype.take is the + intrinsic object %FunctionPrototype%. +features: [iterator-helpers] +---*/ + +assert.sameValue(Object.getPrototypeOf(Iterator.prototype.take), Function.prototype); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/take/result-is-iterator.js b/JSTests/test262/test/built-ins/Iterator/prototype/take/result-is-iterator.js new file mode 100644 index 000000000000..bc5cd4bf99d5 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/take/result-is-iterator.js @@ -0,0 +1,11 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.take +description: > + The value of the [[Prototype]] internal slot of the return value of Iterator.prototype.take is the + intrinsic object %IteratorHelperPrototype%. +features: [iterator-helpers] +---*/ + +assert((function* () {})().take(0) instanceof Iterator, 'function*(){}().take(0) must return an Iterator'); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/take/return-is-forwarded.js b/JSTests/test262/test/built-ins/Iterator/prototype/take/return-is-forwarded.js new file mode 100644 index 000000000000..08e2506f1f8b --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/take/return-is-forwarded.js @@ -0,0 +1,51 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.take +description: > + Underlying iterator return is called when result iterator is closed +info: | + %Iterator.prototype%.take ( limit ) + +features: [iterator-helpers] +flags: [] +---*/ +let returnCount = 0; + +class TestIterator extends Iterator { + next() { + return { + done: false, + value: 1, + }; + } + return() { + ++returnCount; + return {}; + } +} + +let iterator = new TestIterator().take(0); +assert.sameValue(returnCount, 0); +iterator.return(); +assert.sameValue(returnCount, 1); +iterator.return(); +assert.sameValue(returnCount, 1); + +returnCount = 0; + +iterator = new TestIterator().take(1); +assert.sameValue(returnCount, 0); +iterator.return(); +assert.sameValue(returnCount, 1); +iterator.return(); +assert.sameValue(returnCount, 1); + +returnCount = 0; + +iterator = new TestIterator().take(1).take(1).take(1).take(1).take(1); +assert.sameValue(returnCount, 0); +iterator.return(); +assert.sameValue(returnCount, 1); +iterator.return(); +assert.sameValue(returnCount, 1); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/take/return-is-not-forwarded-after-exhaustion.js b/JSTests/test262/test/built-ins/Iterator/prototype/take/return-is-not-forwarded-after-exhaustion.js new file mode 100644 index 000000000000..77192e57fd12 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/take/return-is-not-forwarded-after-exhaustion.js @@ -0,0 +1,50 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.take +description: > + Underlying iterator return is not called after result iterator observes that underlying iterator is exhausted +info: | + %Iterator.prototype%.take ( limit ) + +features: [iterator-helpers] +flags: [] +---*/ +let returnCount = 0; + +class TestIterator extends Iterator { + next() { + return { + done: true, + value: undefined, + }; + } + return() { + throw new Test262Error(); + } +} + +let iterator = new TestIterator().take(0); +assert.throws(Test262Error, function () { + iterator.return(); +}); +iterator.next(); +iterator.return(); + +iterator = new TestIterator().take(1); +iterator.next(); +iterator.return(); + +iterator = new TestIterator().take(1); +assert.throws(Test262Error, function () { + iterator.return(); +}); +iterator.next(); +iterator.return(); + +iterator = new TestIterator().take(1).take(1).take(1).take(1).take(1); +assert.throws(Test262Error, function () { + iterator.return(); +}); +iterator.next(); +iterator.return(); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/take/this-non-callable-next.js b/JSTests/test262/test/built-ins/Iterator/prototype/take/this-non-callable-next.js new file mode 100644 index 000000000000..26b655fa0167 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/take/this-non-callable-next.js @@ -0,0 +1,19 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.take +description: > + Iterator.prototype.take throws TypeError when its this value is an object with a non-callable next +info: | + %Iterator.prototype%.take ( limit ) + + 7. Let iterated be ? GetIteratorDirect(this value). + +features: [iterator-helpers] +flags: [] +---*/ +let iter = Iterator.prototype.take.call({ next: 0 }, 1); + +assert.throws(TypeError, function () { + iter.next(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/take/this-non-object.js b/JSTests/test262/test/built-ins/Iterator/prototype/take/this-non-object.js new file mode 100644 index 000000000000..e36b0e7bda59 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/take/this-non-object.js @@ -0,0 +1,34 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.take +description: > + Iterator.prototype.take throws TypeError when its this value is a non-object +info: | + %Iterator.prototype%.take ( limit ) + + 7. Let iterated be ? GetIteratorDirect(this value). + +features: [iterator-helpers] +flags: [] +---*/ +assert.throws(TypeError, function () { + Iterator.prototype.take.call(null, 1); +}); + +assert.throws(TypeError, function () { + Iterator.prototype.take.call(null, { + valueOf: function () { + throw new Test262Error(); + }, + }); +}); + +Object.defineProperty(Number.prototype, 'next', { + get: function () { + throw new Test262Error(); + }, +}); +assert.throws(TypeError, function () { + Iterator.prototype.take.call(0, 1); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/take/this-plain-iterator.js b/JSTests/test262/test/built-ins/Iterator/prototype/take/this-plain-iterator.js new file mode 100644 index 000000000000..b494b3d5eb7a --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/take/this-plain-iterator.js @@ -0,0 +1,30 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.take +description: > + Iterator.prototype.take supports a this value that does not inherit from Iterator.prototype but implements the iterator protocol +info: | + %Iterator.prototype%.take ( limit ) + + 7. Let iterated be ? GetIteratorDirect(this value). + +features: [iterator-helpers] +flags: [] +---*/ +let iter = { + get next() { + let count = 3; + return function () { + --count; + return count >= 0 ? { done: false, value: count } : { done: true, value: undefined }; + }; + }, +}; + +let takeIter = Iterator.prototype.take.call(iter, 1); + +let { done, value } = takeIter.next(); + +assert.sameValue(done, false); +assert.sameValue(value, 2); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/take/underlying-iterator-advanced-in-parallel.js b/JSTests/test262/test/built-ins/Iterator/prototype/take/underlying-iterator-advanced-in-parallel.js new file mode 100644 index 000000000000..2ef2a4dc3a45 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/take/underlying-iterator-advanced-in-parallel.js @@ -0,0 +1,39 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.take +description: > + Underlying iterator is advanced after calling take +info: | + %Iterator.prototype%.take ( limit ) + +features: [iterator-helpers] +flags: [] +---*/ +let iterator = (function* () { + for (let i = 0; i < 5; ++i) { + yield i; + } +})(); + +let taken = iterator.take(2); + +let { value, done } = iterator.next(); + +assert.sameValue(value, 0); +assert.sameValue(done, false); + +({ value, done } = taken.next()); + +assert.sameValue(value, 1); +assert.sameValue(done, false); + +({ value, done } = taken.next()); + +assert.sameValue(value, 2); +assert.sameValue(done, false); + +({ value, done } = taken.next()); + +assert.sameValue(value, undefined); +assert.sameValue(done, true); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/take/underlying-iterator-closed-in-parallel.js b/JSTests/test262/test/built-ins/Iterator/prototype/take/underlying-iterator-closed-in-parallel.js new file mode 100644 index 000000000000..fc412d40132f --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/take/underlying-iterator-closed-in-parallel.js @@ -0,0 +1,26 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.take +description: > + Underlying iterator is closed after calling take +info: | + %Iterator.prototype%.take ( limit ) + +features: [iterator-helpers] +flags: [] +---*/ +let iterator = (function* () { + for (let i = 0; i < 5; ++i) { + yield i; + } +})(); + +let taken = iterator.take(2); + +iterator.return(); + +let { value, done } = taken.next(); + +assert.sameValue(value, undefined); +assert.sameValue(done, true); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/take/underlying-iterator-closed.js b/JSTests/test262/test/built-ins/Iterator/prototype/take/underlying-iterator-closed.js new file mode 100644 index 000000000000..dc3837bf8660 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/take/underlying-iterator-closed.js @@ -0,0 +1,26 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.take +description: > + Underlying iterator is closed before calling take +info: | + %Iterator.prototype%.take ( limit ) + +features: [iterator-helpers] +flags: [] +---*/ +let iterator = (function* () { + for (let i = 0; i < 5; ++i) { + yield i; + } +})(); + +iterator.return(); + +let taken = iterator.take(2); + +let { value, done } = taken.next(); + +assert.sameValue(value, undefined); +assert.sameValue(done, true); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/toArray/callable.js b/JSTests/test262/test/built-ins/Iterator/prototype/toArray/callable.js new file mode 100644 index 000000000000..819b92132eea --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/toArray/callable.js @@ -0,0 +1,13 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.toArray +description: > + Iterator.prototype.toArray is callable +features: [iterator-helpers] +---*/ +function* g() {} +Iterator.prototype.toArray.call(g()); + +let iter = g(); +iter.toArray(); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/toArray/get-next-method-only-once.js b/JSTests/test262/test/built-ins/Iterator/prototype/toArray/get-next-method-only-once.js new file mode 100644 index 000000000000..15362c96d3cc --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/toArray/get-next-method-only-once.js @@ -0,0 +1,34 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.toArray +description: > + Gets the next method from the iterator only once +info: | + %Iterator.prototype%.toArray ( ) + +includes: [compareArray.js] +features: [iterator-helpers] +flags: [] +---*/ +let nextGets = 0; + +class TestIterator extends Iterator { + get next() { + ++nextGets; + let counter = 5; + return function () { + if (counter <= 0) { + return { done: true, value: undefined }; + } else { + return { done: false, value: --counter }; + } + }; + } +} + +let iterator = new TestIterator(); + +assert.sameValue(nextGets, 0); +assert.compareArray(iterator.toArray(), [4, 3, 2, 1, 0]); +assert.sameValue(nextGets, 1); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/toArray/get-next-method-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/toArray/get-next-method-throws.js new file mode 100644 index 000000000000..06d7320638e9 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/toArray/get-next-method-throws.js @@ -0,0 +1,23 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.toArray +description: > + Iterator has throwing next getter +info: | + %Iterator.prototype%.toArray ( ) + +features: [iterator-helpers] +flags: [] +---*/ +class IteratorThrows extends Iterator { + get next() { + throw new Test262Error(); + } +} + +let iterator = new IteratorThrows(); + +assert.throws(Test262Error, function () { + iterator.toArray(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/toArray/is-function.js b/JSTests/test262/test/built-ins/Iterator/prototype/toArray/is-function.js new file mode 100644 index 000000000000..0bede61973bb --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/toArray/is-function.js @@ -0,0 +1,10 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.toArray +description: > + Iterator.prototype.toArray is a built-in function +features: [iterator-helpers] +---*/ + +assert.sameValue(typeof Iterator.prototype.toArray, 'function'); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/toArray/iterator-already-exhausted.js b/JSTests/test262/test/built-ins/Iterator/prototype/toArray/iterator-already-exhausted.js new file mode 100644 index 000000000000..9db33a71acaa --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/toArray/iterator-already-exhausted.js @@ -0,0 +1,24 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.toArray +description: > + Iterator.prototype.toArray returns an empty array when the iterator has already been exhausted +info: | + %Iterator.prototype%.toArray ( ) + +includes: [compareArray.js] +features: [iterator-helpers] +flags: [] +---*/ +let iterator = (function* () {})(); + +let { value, done } = iterator.next(); +assert.sameValue(value, undefined); +assert.sameValue(done, true); + +let result = iterator.toArray(); +assert.compareArray(result, []); + +result = iterator.toArray(); +assert.compareArray(result, []); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/toArray/length.js b/JSTests/test262/test/built-ins/Iterator/prototype/toArray/length.js new file mode 100644 index 000000000000..dadd069c5b4f --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/toArray/length.js @@ -0,0 +1,22 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.toArray +description: > + Iterator.prototype.toArray has a "length" property whose value is 0. +info: | + ECMAScript Standard Built-in Objects + + Unless otherwise specified, the length property of a built-in + Function object has the attributes { [[Writable]]: false, [[Enumerable]]: + false, [[Configurable]]: true }. +features: [iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Iterator.prototype.toArray, 'length', { + value: 0, + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/toArray/name.js b/JSTests/test262/test/built-ins/Iterator/prototype/toArray/name.js new file mode 100644 index 000000000000..fd970f676f62 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/toArray/name.js @@ -0,0 +1,29 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.toArray +description: > + The "name" property of Iterator.prototype.toArray +info: | + 17 ECMAScript Standard Built-in Objects + + Every built-in Function object, including constructors, that is not + identified as an anonymous function has a name property whose value is a + String. Unless otherwise specified, this value is the name that is given to + the function in this specification. + + ... + + Unless otherwise specified, the name property of a built-in Function + object, if it exists, has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +features: [iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Iterator.prototype.toArray, 'name', { + value: 'toArray', + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/toArray/next-method-returns-non-object.js b/JSTests/test262/test/built-ins/Iterator/prototype/toArray/next-method-returns-non-object.js new file mode 100644 index 000000000000..22d08140f1b5 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/toArray/next-method-returns-non-object.js @@ -0,0 +1,23 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.toArray +description: > + Underlying iterator next returns non-object +info: | + %Iterator.prototype%.toArray ( ) + +features: [iterator-helpers] +flags: [] +---*/ +class NonObjectIterator extends Iterator { + next() { + return null; + } +} + +let iterator = new NonObjectIterator(); + +assert.throws(TypeError, function () { + iterator.toArray(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/toArray/next-method-returns-throwing-done.js b/JSTests/test262/test/built-ins/Iterator/prototype/toArray/next-method-returns-throwing-done.js new file mode 100644 index 000000000000..e725cf4049d3 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/toArray/next-method-returns-throwing-done.js @@ -0,0 +1,31 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.toArray +description: > + Underlying iterator next returns object with throwing done getter +info: | + %Iterator.prototype%.toArray ( ) + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + return { + get done() { + throw new Test262Error(); + }, + value: 1, + }; + } + return() { + throw new Error(); + } +} + +let iterator = new ThrowingIterator(); + +assert.throws(Test262Error, function () { + iterator.toArray(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/toArray/next-method-returns-throwing-value-done.js b/JSTests/test262/test/built-ins/Iterator/prototype/toArray/next-method-returns-throwing-value-done.js new file mode 100644 index 000000000000..15ca5ab33407 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/toArray/next-method-returns-throwing-value-done.js @@ -0,0 +1,28 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.toArray +description: > + Underlying iterator next returns object with throwing value getter, but is already done +info: | + %Iterator.prototype%.toArray ( ) + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + return { + done: true, + get value() { + throw new Test262Error(); + }, + }; + } + return() { + throw new Error(); + } +} + +let iterator = new ThrowingIterator(); +iterator.toArray(); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/toArray/next-method-returns-throwing-value.js b/JSTests/test262/test/built-ins/Iterator/prototype/toArray/next-method-returns-throwing-value.js new file mode 100644 index 000000000000..084158ddbda0 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/toArray/next-method-returns-throwing-value.js @@ -0,0 +1,31 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.toArray +description: > + Underlying iterator next returns object with throwing value getter +info: | + %Iterator.prototype%.toArray ( ) + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + return { + done: false, + get value() { + throw new Test262Error(); + }, + }; + } + return() { + throw new Error(); + } +} + +let iterator = new ThrowingIterator(); + +assert.throws(Test262Error, function () { + iterator.toArray(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/toArray/next-method-throws.js b/JSTests/test262/test/built-ins/Iterator/prototype/toArray/next-method-throws.js new file mode 100644 index 000000000000..6473e8bb507f --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/toArray/next-method-throws.js @@ -0,0 +1,23 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.toArray +description: > + Underlying iterator has throwing next method +info: | + %Iterator.prototype%.toArray ( ) + +features: [iterator-helpers] +flags: [] +---*/ +class ThrowingIterator extends Iterator { + next() { + throw new Test262Error(); + } +} + +let iterator = new ThrowingIterator(); + +assert.throws(Test262Error, function () { + iterator.toArray(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/toArray/non-constructible.js b/JSTests/test262/test/built-ins/Iterator/prototype/toArray/non-constructible.js new file mode 100644 index 000000000000..536deebdc9e4 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/toArray/non-constructible.js @@ -0,0 +1,24 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.toArray +description: > + Iterator.prototype.toArray is not constructible. + + Built-in function objects that are not identified as constructors do not implement the [[Construct]] internal method unless otherwise specified in the description of a particular function. +features: [iterator-helpers] +---*/ +function* g() {} +let iter = g(); + +assert.throws(TypeError, () => { + new iter.toArray(); +}); + +assert.throws(TypeError, () => { + new Iterator.prototype.toArray(); +}); + +assert.throws(TypeError, () => { + new class extends Iterator {}.toArray(); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/toArray/prop-desc.js b/JSTests/test262/test/built-ins/Iterator/prototype/toArray/prop-desc.js new file mode 100644 index 000000000000..e6c487a3f2d2 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/toArray/prop-desc.js @@ -0,0 +1,25 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.toArray +description: > + Property descriptor of Iterator.prototype.toArray +info: | + Iterator.prototype.toArray + + * is the initial value of the Iterator.prototype.toArray property of the global object. + + 17 ECMAScript Standard Built-in Objects + + every other data property described in clauses 18 through 26 and in Annex B.2 + has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +features: [globalThis, iterator-helpers] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Iterator.prototype, 'toArray', { + writable: true, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/toArray/proto.js b/JSTests/test262/test/built-ins/Iterator/prototype/toArray/proto.js new file mode 100644 index 000000000000..142a82b4ae72 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/toArray/proto.js @@ -0,0 +1,11 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.toArray +description: > + The value of the [[Prototype]] internal slot of Iterator.prototype.toArray is the + intrinsic object %Function%. +features: [iterator-helpers] +---*/ + +assert.sameValue(Object.getPrototypeOf(Iterator.prototype.toArray), Function.prototype); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/toArray/this-non-callable-next.js b/JSTests/test262/test/built-ins/Iterator/prototype/toArray/this-non-callable-next.js new file mode 100644 index 000000000000..f0b2a5686869 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/toArray/this-non-callable-next.js @@ -0,0 +1,15 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.toArray +description: > + Iterator.prototype.toArray throws TypeError when its this value is an object with a non-callable next +info: | + %Iterator.prototype%.toArray ( ) + +features: [iterator-helpers] +flags: [] +---*/ +assert.throws(TypeError, function () { + Iterator.prototype.toArray.call({ next: 0 }); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/toArray/this-non-object.js b/JSTests/test262/test/built-ins/Iterator/prototype/toArray/this-non-object.js new file mode 100644 index 000000000000..d21723e98e7e --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/toArray/this-non-object.js @@ -0,0 +1,24 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.toArray +description: > + Iterator.prototype.toArray throws TypeError when its this value is a non-object +info: | + %Iterator.prototype%.toArray ( ) + +features: [iterator-helpers] +flags: [] +---*/ +assert.throws(TypeError, function () { + Iterator.prototype.toArray.call(null); +}); + +Object.defineProperty(Number.prototype, 'next', { + get: function () { + throw new Test262Error(); + }, +}); +assert.throws(TypeError, function () { + Iterator.prototype.toArray.call(0); +}); diff --git a/JSTests/test262/test/built-ins/Iterator/prototype/toArray/this-plain-iterator.js b/JSTests/test262/test/built-ins/Iterator/prototype/toArray/this-plain-iterator.js new file mode 100644 index 000000000000..765bc1e913d4 --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/prototype/toArray/this-plain-iterator.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.toArray +description: > + Iterator.prototype.toArray supports a this value that does not inherit from Iterator.prototype but implements the iterator protocol +info: | + %Iterator.prototype%.toArray ( ) + +includes: [compareArray.js] +features: [iterator-helpers] +flags: [] +---*/ +let iter = { + get next() { + let count = 3; + return function () { + --count; + return count >= 0 ? { done: false, value: count } : { done: true, value: undefined }; + }; + }, +}; + +let result = Iterator.prototype.toArray.call(iter); +assert.compareArray(result, [2, 1, 0]); diff --git a/JSTests/test262/test/built-ins/Iterator/subclassable.js b/JSTests/test262/test/built-ins/Iterator/subclassable.js new file mode 100644 index 000000000000..4a07db8c041f --- /dev/null +++ b/JSTests/test262/test/built-ins/Iterator/subclassable.js @@ -0,0 +1,27 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-iterator-constructor +description: > + The Iterator constructor is designed to be subclassable. +info: | + The Iterator constructor + + - is designed to be subclassable. It may be used as the value of an extends clause of a class defintion. + +features: [iterator-helpers] +---*/ + +class SubIterator extends Iterator {} + +assert.sameValue( + new SubIterator() instanceof SubIterator, + true, + 'The result of `(new SubIterator() instanceof SubIterator)` is true' +); +assert.sameValue( + new SubIterator() instanceof Iterator, + true, + 'The result of `(new SubIterator() instanceof Iterator)` is true' +); diff --git a/JSTests/test262/test/built-ins/IteratorPrototype/Symbol.iterator/length.js b/JSTests/test262/test/built-ins/IteratorPrototype/Symbol.iterator/length.js deleted file mode 100644 index 7c69aec54abe..000000000000 --- a/JSTests/test262/test/built-ins/IteratorPrototype/Symbol.iterator/length.js +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2015 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -es6id: 25.1.2.1 -description: Length of IteratorPrototype[ @@iterator ] -info: | - ES6 Section 17: - Every built-in Function object, including constructors, has a length - property whose value is an integer. Unless otherwise specified, this value - is equal to the largest number of named arguments shown in the subclause - headings for the function description, including optional parameters. - - [...] - - Unless otherwise specified, the length property of a built-in Function - object has the attributes { [[Writable]]: false, [[Enumerable]]: false, - [[Configurable]]: true }. -features: [Symbol.iterator] -includes: [propertyHelper.js] ----*/ - -var IteratorPrototype = Object.getPrototypeOf( - Object.getPrototypeOf([][Symbol.iterator]()) -); - -assert.sameValue(IteratorPrototype[Symbol.iterator].length, 0); - -verifyNotEnumerable(IteratorPrototype[Symbol.iterator], 'length'); -verifyNotWritable(IteratorPrototype[Symbol.iterator], 'length'); -verifyConfigurable(IteratorPrototype[Symbol.iterator], 'length'); diff --git a/JSTests/test262/test/built-ins/IteratorPrototype/Symbol.iterator/name.js b/JSTests/test262/test/built-ins/IteratorPrototype/Symbol.iterator/name.js deleted file mode 100644 index 06132f5af221..000000000000 --- a/JSTests/test262/test/built-ins/IteratorPrototype/Symbol.iterator/name.js +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (C) 2015 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -es6id: 25.1.2.1 -description: Descriptor for `name` property -info: | - The value of the name property of this function is "[Symbol.iterator]". - - ES6 Section 17: ECMAScript Standard Built-in Objects - - Every built-in Function object, including constructors, that is not - identified as an anonymous function has a name property whose value is a - String. Unless otherwise specified, this value is the name that is given to - the function in this specification. - - [...] - - Unless otherwise specified, the name property of a built-in Function - object, if it exists, has the attributes { [[Writable]]: false, - [[Enumerable]]: false, [[Configurable]]: true }. -features: [Symbol.iterator] -includes: [propertyHelper.js] ----*/ - -var IteratorPrototype = Object.getPrototypeOf( - Object.getPrototypeOf([][Symbol.iterator]()) -); - -assert.sameValue(IteratorPrototype[Symbol.iterator].name, '[Symbol.iterator]'); - -verifyNotEnumerable(IteratorPrototype[Symbol.iterator], 'name'); -verifyNotWritable(IteratorPrototype[Symbol.iterator], 'name'); -verifyConfigurable(IteratorPrototype[Symbol.iterator], 'name'); diff --git a/JSTests/test262/test/built-ins/IteratorPrototype/Symbol.iterator/prop-desc.js b/JSTests/test262/test/built-ins/IteratorPrototype/Symbol.iterator/prop-desc.js deleted file mode 100644 index 1395c32d2253..000000000000 --- a/JSTests/test262/test/built-ins/IteratorPrototype/Symbol.iterator/prop-desc.js +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (C) 2015 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -es6id: 25.1.2.1 -description: Property descriptor -info: | - ES6 Section 17 - - Every other data property described in clauses 18 through 26 and in Annex - B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false, - [[Configurable]]: true } unless otherwise specified. -features: [Symbol.iterator] -includes: [propertyHelper.js] ----*/ - -var IteratorPrototype = Object.getPrototypeOf( - Object.getPrototypeOf([][Symbol.iterator]()) -); - -assert.sameValue(typeof IteratorPrototype[Symbol.iterator], 'function'); -verifyNotEnumerable(IteratorPrototype, Symbol.iterator); -verifyWritable(IteratorPrototype, Symbol.iterator); -verifyConfigurable(IteratorPrototype, Symbol.iterator); diff --git a/JSTests/test262/test/built-ins/IteratorPrototype/Symbol.iterator/return-val.js b/JSTests/test262/test/built-ins/IteratorPrototype/Symbol.iterator/return-val.js deleted file mode 100644 index d9bc41752f78..000000000000 --- a/JSTests/test262/test/built-ins/IteratorPrototype/Symbol.iterator/return-val.js +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (C) 2015 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-%iteratorprototype%-@@iterator -description: Return value of @@iterator on IteratorPrototype -info: | - %IteratorPrototype% [ @@iterator ] ( ) - 1. Return the this value. -features: [Symbol.iterator] ----*/ - -const IteratorPrototype = Object.getPrototypeOf( - Object.getPrototypeOf([][Symbol.iterator]()) -); -const getIterator = IteratorPrototype[Symbol.iterator]; - -const thisValues = [ - {}, - Symbol(), - 4, - 4n, - true, - undefined, - null, -]; - -for (const thisValue of thisValues) { - assert.sameValue( - getIterator.call(thisValue), - thisValue - ); -} diff --git a/JSTests/test262/test/built-ins/Map/groupBy/callback-arg.js b/JSTests/test262/test/built-ins/Map/groupBy/callback-arg.js new file mode 100644 index 000000000000..7b01aa50ba08 --- /dev/null +++ b/JSTests/test262/test/built-ins/Map/groupBy/callback-arg.js @@ -0,0 +1,32 @@ +// Copyright (c) 2023 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-map.groupby +description: Map.groupBy calls function with correct arguments +info: | + Map.groupBy ( items, callbackfn ) + + ... + GroupBy ( items, callbackfn, coercion ) + + 6. Repeat, + + e. Let key be Completion(Call(callbackfn, undefined, « value, 𝔽(k) »)). + ... +features: [array-grouping, Map] +---*/ + + +const arr = [-0, 0, 1, 2, 3]; + +let calls = 0; + +Map.groupBy(arr, function (n, i) { + calls++; + assert.sameValue(n, arr[i], "selected element aligns with index"); + assert.sameValue(arguments.length, 2, "only two arguments are passed"); + return null; +}); + +assert.sameValue(calls, 5, 'called for all 5 elements'); diff --git a/JSTests/test262/test/built-ins/Map/groupBy/callback-throws.js b/JSTests/test262/test/built-ins/Map/groupBy/callback-throws.js new file mode 100644 index 000000000000..5f586e841ece --- /dev/null +++ b/JSTests/test262/test/built-ins/Map/groupBy/callback-throws.js @@ -0,0 +1,25 @@ +// Copyright (c) 2023 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-map.groupby +description: Map.groupBy throws when callback throws +info: | + Map.groupBy ( items, callbackfn ) + + ... + GroupBy ( items, callbackfn, coercion ) + + 6. Repeat, + e. Let key be Completion(Call(callbackfn, undefined, « value, 𝔽(k) »)). + f. IfAbruptCloseIterator(key, iteratorRecord). + ... +features: [array-grouping, Map] +---*/ + +assert.throws(Test262Error, function() { + const array = [1]; + Map.groupBy(array, function() { + throw new Test262Error('throw in callback'); + }) +}); diff --git a/JSTests/test262/test/built-ins/Map/groupBy/emptyList.js b/JSTests/test262/test/built-ins/Map/groupBy/emptyList.js new file mode 100644 index 000000000000..cff59207a705 --- /dev/null +++ b/JSTests/test262/test/built-ins/Map/groupBy/emptyList.js @@ -0,0 +1,27 @@ +// Copyright (c) 2023 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-map.groupby +description: Callback is not called and object is not populated if the iterable is empty +info: | + Map.groupBy ( items, callbackfn ) + + ... + GroupBy ( items, callbackfn, coercion ) + + 6. Repeat, + c. If next is false, then + i. Return groups. + ... +features: [array-grouping, Map] +---*/ + +const original = []; + +const map = Map.groupBy(original, function () { + throw new Test262Error('callback function should not be called') +}); + +assert.notSameValue(original, map, 'Map.groupBy returns a map'); +assert.sameValue(map.size, 0); diff --git a/JSTests/test262/test/built-ins/Map/groupBy/evenOdd.js b/JSTests/test262/test/built-ins/Map/groupBy/evenOdd.js new file mode 100644 index 000000000000..965bfe4101a2 --- /dev/null +++ b/JSTests/test262/test/built-ins/Map/groupBy/evenOdd.js @@ -0,0 +1,22 @@ +// Copyright (c) 2023 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-map.groupby +description: Map.groupBy populates Map with correct keys and values +info: | + Map.groupBy ( items, callbackfn ) + ... +includes: [compareArray.js] +features: [array-grouping, Map] +---*/ + +const array = [1, 2, 3]; + +const map = Map.groupBy(array, function (i) { + return i % 2 === 0 ? 'even' : 'odd'; +}); + +assert.compareArray(Array.from(map.keys()), ['odd', 'even']); +assert.compareArray(map.get('even'), [2]); +assert.compareArray(map.get('odd'), [1, 3]); diff --git a/JSTests/test262/test/built-ins/Map/groupBy/groupLength.js b/JSTests/test262/test/built-ins/Map/groupBy/groupLength.js new file mode 100644 index 000000000000..a00df19ce05c --- /dev/null +++ b/JSTests/test262/test/built-ins/Map/groupBy/groupLength.js @@ -0,0 +1,21 @@ +// Copyright (c) 2023 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-map.groupby +description: Map.groupBy populates Map with correct keys and values +info: | + Map.groupBy ( items, callbackfn ) + + ... +includes: [compareArray.js] +features: [array-grouping, Map, Symbol.iterator] +---*/ + +const arr = ['hello', 'test', 'world']; + +const map = Map.groupBy(arr, function (i) { return i.length; }); + +assert.compareArray(Array.from(map.keys()), [5, 4]); +assert.compareArray(map.get(5), ['hello', 'world']); +assert.compareArray(map.get(4), ['test']); diff --git a/JSTests/test262/test/built-ins/Map/groupBy/invalid-callback.js b/JSTests/test262/test/built-ins/Map/groupBy/invalid-callback.js new file mode 100644 index 000000000000..b6cd835d6c66 --- /dev/null +++ b/JSTests/test262/test/built-ins/Map/groupBy/invalid-callback.js @@ -0,0 +1,29 @@ +// Copyright (c) 2023 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-map.groupby +description: Map.groupBy called with non-callable throws TypeError +info: | + Map.groupBy ( items, callbackfn ) + + ... + GroupBy ( items, callbackfn, coercion ) + + 2. If IsCallable(callbackfn) is false, throw a TypeError exception. + ... +features: [array-grouping, Map] +---*/ + + +assert.throws(TypeError, function() { + Map.groupBy([], null) +}, "null callback throws TypeError"); + +assert.throws(TypeError, function() { + Map.groupBy([], undefined) +}, "undefined callback throws TypeError"); + +assert.throws(TypeError, function() { + Map.groupBy([], {}) +}, "object callback throws TypeError"); diff --git a/JSTests/test262/test/built-ins/Map/groupBy/invalid-iterable.js b/JSTests/test262/test/built-ins/Map/groupBy/invalid-iterable.js new file mode 100644 index 000000000000..51031fbe5779 --- /dev/null +++ b/JSTests/test262/test/built-ins/Map/groupBy/invalid-iterable.js @@ -0,0 +1,34 @@ +// Copyright (c) 2023 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-map.groupby +description: Map.groupBy with a nullish Symbol.iterator throws +info: | + Map.groupBy ( items, callbackfn ) + + ... + GroupBy ( items, callbackfn, coercion ) + + 4. Let iteratorRecord be ? GetIterator(items). + + ... +features: [array-grouping, Map] +---*/ + +const throws = function () { + throw new Test262Error('callback function should not be called') +}; + +function makeIterable(obj, iteratorFn) { + obj[Symbol.iterator] = iteratorFn; + return obj; +} + +assert.throws(TypeError, function () { + Map.groupBy(makeIterable({}, undefined), throws); +}, 'undefined Symbol.iterator'); + +assert.throws(TypeError, function () { + Map.groupBy(makeIterable({}, null), throws); +}, 'null Symbol.iterator'); diff --git a/JSTests/test262/test/built-ins/Map/groupBy/iterator-next-throws.js b/JSTests/test262/test/built-ins/Map/groupBy/iterator-next-throws.js new file mode 100644 index 000000000000..0f4dce713cec --- /dev/null +++ b/JSTests/test262/test/built-ins/Map/groupBy/iterator-next-throws.js @@ -0,0 +1,34 @@ +// Copyright (c) 2023 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-map.groupby +description: Map.groupBy throws when iterator next throws +info: | + Map.groupBy ( items, callbackfn ) + + ... + + GroupBy ( items, callbackfn, coercion ) + + 6. Repeat, + b. Let next be ? IteratorStep(iteratorRecord). + + ... +features: [array-grouping, Map, Symbol.iterator] +---*/ + +const throwingIterator = { + [Symbol.iterator]: function () { + return this; + }, + next: function next() { + throw new Test262Error('next() method was called'); + } +}; + +assert.throws(Test262Error, function () { + Map.groupBy(throwingIterator, function () { + return 'key'; + }); +}); diff --git a/JSTests/test262/test/built-ins/Map/groupBy/length.js b/JSTests/test262/test/built-ins/Map/groupBy/length.js new file mode 100644 index 000000000000..a4c83bd090ae --- /dev/null +++ b/JSTests/test262/test/built-ins/Map/groupBy/length.js @@ -0,0 +1,25 @@ +// Copyright (c) 2023 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-map.groupby +description: Map.groupBy property length descriptor +info: | + Map.groupBy ( items, callbackfn ) + + ... + + 17 ECMAScript Standard Built-in Objects + + ... + +includes: [propertyHelper.js] +features: [array-grouping, Map] +---*/ + +verifyProperty(Map.groupBy, "length", { + value: 2, + enumerable: false, + writable: false, + configurable: true +}); diff --git a/JSTests/test262/test/built-ins/Map/groupBy/map-instance.js b/JSTests/test262/test/built-ins/Map/groupBy/map-instance.js new file mode 100644 index 000000000000..d871b3c355cc --- /dev/null +++ b/JSTests/test262/test/built-ins/Map/groupBy/map-instance.js @@ -0,0 +1,26 @@ +// Copyright (c) 2023 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-map.groupby +description: Map.groupBy returns a Map instance +info: | + Map.groupBy ( items, callbackfn ) + + ... + + 2. Let map be ! Construct(%Map%). + ... + 4. Return map. + + ... +features: [array-grouping, Map] +---*/ + +const array = [1, 2, 3]; + +const map = Map.groupBy(array, function (i) { + return i % 2 === 0 ? 'even' : 'odd'; +}); + +assert.sameValue(map instanceof Map, true); diff --git a/JSTests/test262/test/built-ins/Map/groupBy/name.js b/JSTests/test262/test/built-ins/Map/groupBy/name.js new file mode 100644 index 000000000000..d2dd26034c35 --- /dev/null +++ b/JSTests/test262/test/built-ins/Map/groupBy/name.js @@ -0,0 +1,25 @@ +// Copyright (c) 2023 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-map.groupby +description: Map.groupBy property name descriptor +info: | + Map.groupBy ( items, callbackfn ) + + ... + + 17 ECMAScript Standard Built-in Objects + + ... + +includes: [propertyHelper.js] +features: [array-grouping, Map] +---*/ + +verifyProperty(Map.groupBy, "name", { + value: "groupBy", + enumerable: false, + writable: false, + configurable: true +}); diff --git a/JSTests/test262/test/built-ins/Map/groupBy/negativeZero.js b/JSTests/test262/test/built-ins/Map/groupBy/negativeZero.js new file mode 100644 index 000000000000..f73f474a7b94 --- /dev/null +++ b/JSTests/test262/test/built-ins/Map/groupBy/negativeZero.js @@ -0,0 +1,30 @@ +// Copyright (c) 2023 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-map.groupby +description: Map.groupBy normalizes 0 for Map key +info: | + Map.groupBy ( items, callbackfn ) + + ... + + GroupBy ( items, callbackfn, coercion ) + + 6. Repeat, + h. Else, + i. Assert: coercion is zero. + ii. If key is -0𝔽, set key to +0𝔽. + + ... +includes: [compareArray.js] +features: [array-grouping, Map] +---*/ + + +const arr = [-0, +0]; + +const map = Map.groupBy(arr, function (i) { return i; }); + +assert.sameValue(map.size, 1); +assert.compareArray(map.get(0), [-0, 0]); diff --git a/JSTests/test262/test/built-ins/Map/groupBy/toPropertyKey.js b/JSTests/test262/test/built-ins/Map/groupBy/toPropertyKey.js new file mode 100644 index 000000000000..f162f1ea43df --- /dev/null +++ b/JSTests/test262/test/built-ins/Map/groupBy/toPropertyKey.js @@ -0,0 +1,29 @@ +// Copyright (c) 2023 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-map.groupby +description: Map.groupBy does not coerce return value with ToPropertyKey +info: | + Map.groupBy ( items, callbackfn ) + + ... +includes: [compareArray.js] +features: [array-grouping, Map] +---*/ + +let calls = 0; +const stringable = { + toString: function toString() { + return 1; + } +}; + +const array = [1, '1', stringable]; + +const map = Map.groupBy(array, function (v) { return v; }); + +assert.compareArray(Array.from(map.keys()), [1, '1', stringable]); +assert.compareArray(map.get('1'), ['1']); +assert.compareArray(map.get(1), [1]); +assert.compareArray(map.get(stringable), [stringable]); diff --git a/JSTests/test262/test/built-ins/Map/valid-keys.js b/JSTests/test262/test/built-ins/Map/valid-keys.js index 3d417b67140c..29908ffa925f 100644 --- a/JSTests/test262/test/built-ins/Map/valid-keys.js +++ b/JSTests/test262/test/built-ins/Map/valid-keys.js @@ -11,7 +11,7 @@ info: | Append p as the last element of entries. ... -features: [BigInt, Symbol, TypedArray, WeakRef] +features: [BigInt, Symbol, TypedArray, WeakRef, exponentiation] ---*/ diff --git a/JSTests/test262/test/built-ins/Number/bigint-conversion.js b/JSTests/test262/test/built-ins/Number/bigint-conversion.js index 0397fb0266c1..c4dd8513c2d8 100644 --- a/JSTests/test262/test/built-ins/Number/bigint-conversion.js +++ b/JSTests/test262/test/built-ins/Number/bigint-conversion.js @@ -4,7 +4,7 @@ /*--- description: BigInt to Number conversion esid: pending -features: [BigInt] +features: [BigInt, exponentiation] ---*/ assert.sameValue(Number(0n), 0); diff --git a/JSTests/test262/test/built-ins/Object/groupBy/callback-arg.js b/JSTests/test262/test/built-ins/Object/groupBy/callback-arg.js new file mode 100644 index 000000000000..b6fd2c6bbead --- /dev/null +++ b/JSTests/test262/test/built-ins/Object/groupBy/callback-arg.js @@ -0,0 +1,32 @@ +// Copyright (c) 2023 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-object.groupby +description: Object.groupBy calls function with correct arguments +info: | + Object.groupBy ( items, callbackfn ) + + ... + GroupBy ( items, callbackfn, coercion ) + + 6. Repeat, + + e. Let key be Completion(Call(callbackfn, undefined, « value, 𝔽(k) »)). + ... +features: [array-grouping] +---*/ + + +const arr = [-0, 0, 1, 2, 3]; + +let calls = 0; + +Object.groupBy(arr, function (n, i) { + calls++; + assert.sameValue(n, arr[i], "selected element aligns with index"); + assert.sameValue(arguments.length, 2, "only two arguments are passed"); + return null; +}); + +assert.sameValue(calls, 5, 'called for all 5 elements'); diff --git a/JSTests/test262/test/built-ins/Object/groupBy/callback-throws.js b/JSTests/test262/test/built-ins/Object/groupBy/callback-throws.js new file mode 100644 index 000000000000..8430b8f98d12 --- /dev/null +++ b/JSTests/test262/test/built-ins/Object/groupBy/callback-throws.js @@ -0,0 +1,25 @@ +// Copyright (c) 2023 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-object.groupby +description: Object.groupBy throws when callback throws +info: | + Object.groupBy ( items, callbackfn ) + + ... + GroupBy ( items, callbackfn, coercion ) + + 6. Repeat, + e. Let key be Completion(Call(callbackfn, undefined, « value, 𝔽(k) »)). + f. IfAbruptCloseIterator(key, iteratorRecord). + ... +features: [array-grouping] +---*/ + +assert.throws(Test262Error, function() { + const array = [1]; + Object.groupBy(array, function() { + throw new Test262Error('throw in callback'); + }) +}); diff --git a/JSTests/test262/test/built-ins/Object/groupBy/emptyList.js b/JSTests/test262/test/built-ins/Object/groupBy/emptyList.js new file mode 100644 index 000000000000..52e2d093c93f --- /dev/null +++ b/JSTests/test262/test/built-ins/Object/groupBy/emptyList.js @@ -0,0 +1,27 @@ +// Copyright (c) 2023 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-object.groupby +description: Callback is not called and object is not populated if the iterable is empty +info: | + Object.groupBy ( items, callbackfn ) + + ... + GroupBy ( items, callbackfn, coercion ) + + 6. Repeat, + c. If next is false, then + i. Return groups. + ... +features: [array-grouping] +---*/ + +const original = []; + +const obj = Object.groupBy(original, function () { + throw new Test262Error('callback function should not be called') +}); + +assert.notSameValue(original, obj, 'Object.groupBy returns an object'); +assert.sameValue(Object.keys(obj).length, 0); diff --git a/JSTests/test262/test/built-ins/Object/groupBy/evenOdd.js b/JSTests/test262/test/built-ins/Object/groupBy/evenOdd.js new file mode 100644 index 000000000000..f884b2a3ce9f --- /dev/null +++ b/JSTests/test262/test/built-ins/Object/groupBy/evenOdd.js @@ -0,0 +1,22 @@ +// Copyright (c) 2023 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-object.groupby +description: Object.groupBy populates object with correct keys and values +info: | + Object.groupBy ( items, callbackfn ) + ... +includes: [compareArray.js] +features: [array-grouping] +---*/ + +const array = [1, 2, 3]; + +const obj = Object.groupBy(array, function (i) { + return i % 2 === 0 ? 'even' : 'odd'; +}); + +assert.compareArray(Object.keys(obj), ['odd', 'even']); +assert.compareArray(obj['even'], [2]); +assert.compareArray(obj['odd'], [1, 3]); diff --git a/JSTests/test262/test/built-ins/Object/groupBy/groupLength.js b/JSTests/test262/test/built-ins/Object/groupBy/groupLength.js new file mode 100644 index 000000000000..9be21a39686b --- /dev/null +++ b/JSTests/test262/test/built-ins/Object/groupBy/groupLength.js @@ -0,0 +1,27 @@ +// Copyright (c) 2023 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-object.groupby +description: Callback can return numbers that are converted to property keys +info: | + Object.groupBy ( items, callbackfn ) + + ... + GroupBy ( items, callbackfn, coercion ) + + 6. Repeat, + c. If next is false, then + i. Return groups. + ... +includes: [compareArray.js] +features: [array-grouping] +---*/ + +const arr = ['hello', 'test', 'world']; + +const obj = Object.groupBy(arr, function (i) { return i.length; }); + +assert.compareArray(Object.keys(obj), ['4', '5']); +assert.compareArray(obj['5'], ['hello', 'world']); +assert.compareArray(obj['4'], ['test']); diff --git a/JSTests/test262/test/built-ins/Object/groupBy/invalid-callback.js b/JSTests/test262/test/built-ins/Object/groupBy/invalid-callback.js new file mode 100644 index 000000000000..f5348e4ff20c --- /dev/null +++ b/JSTests/test262/test/built-ins/Object/groupBy/invalid-callback.js @@ -0,0 +1,29 @@ +// Copyright (c) 2023 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-object.groupby +description: Object.groupBy called with non-callable throws TypeError +info: | + Object.groupBy ( items, callbackfn ) + + ... + GroupBy ( items, callbackfn, coercion ) + + 2. If IsCallable(callbackfn) is false, throw a TypeError exception. + ... +features: [array-grouping] +---*/ + + +assert.throws(TypeError, function() { + Object.groupBy([], null) +}, "null callback throws TypeError"); + +assert.throws(TypeError, function() { + Object.groupBy([], undefined) +}, "undefined callback throws TypeError"); + +assert.throws(TypeError, function() { + Object.groupBy([], {}) +}, "object callback throws TypeError"); diff --git a/JSTests/test262/test/built-ins/Object/groupBy/invalid-iterable.js b/JSTests/test262/test/built-ins/Object/groupBy/invalid-iterable.js new file mode 100644 index 000000000000..1f984a0f652f --- /dev/null +++ b/JSTests/test262/test/built-ins/Object/groupBy/invalid-iterable.js @@ -0,0 +1,34 @@ +// Copyright (c) 2023 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-object.groupby +description: Object.groupBy with a nullish Symbol.iterator throws +info: | + Object.groupBy ( items, callbackfn ) + + ... + GroupBy ( items, callbackfn, coercion ) + + 4. Let iteratorRecord be ? GetIterator(items). + + ... +features: [array-grouping] +---*/ + +const throws = function () { + throw new Test262Error('callback function should not be called') +}; + +function makeIterable(obj, iteratorFn) { + obj[Symbol.iterator] = iteratorFn; + return obj; +} + +assert.throws(TypeError, function () { + Object.groupBy(makeIterable({}, undefined), throws); +}, 'undefined Symbol.iterator'); + +assert.throws(TypeError, function () { + Object.groupBy(makeIterable({}, null), throws); +}, 'null Symbol.iterator'); diff --git a/JSTests/test262/test/built-ins/Object/groupBy/invalid-property-key.js b/JSTests/test262/test/built-ins/Object/groupBy/invalid-property-key.js new file mode 100644 index 000000000000..47d21f935f3e --- /dev/null +++ b/JSTests/test262/test/built-ins/Object/groupBy/invalid-property-key.js @@ -0,0 +1,31 @@ +// Copyright (c) 2023 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-object.groupby +description: Object.groupBy errors when callback return value cannot be converted to a property key. +info: | + Object.groupBy ( items, callbackfn ) + + ... + GroupBy ( items, callbackfn, coercion ) + + 6. Repeat, + g. If coercion is property, then + i. Set key to Completion(ToPropertyKey(key)). + ii. IfAbruptCloseIterator(key, iteratorRecord). + + ... +features: [array-grouping] +---*/ + +assert.throws(Test262Error, function () { + const array = [1]; + Object.groupBy(array, function () { + return { + toString() { + throw new Test262Error('not a property key'); + } + }; + }) +}); diff --git a/JSTests/test262/test/built-ins/Object/groupBy/iterator-next-throws.js b/JSTests/test262/test/built-ins/Object/groupBy/iterator-next-throws.js new file mode 100644 index 000000000000..587e2bce1661 --- /dev/null +++ b/JSTests/test262/test/built-ins/Object/groupBy/iterator-next-throws.js @@ -0,0 +1,34 @@ +// Copyright (c) 2023 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-object.groupby +description: Object.groupBy throws when iterator next throws +info: | + Object.groupBy ( items, callbackfn ) + + ... + + GroupBy ( items, callbackfn, coercion ) + + 6. Repeat, + b. Let next be ? IteratorStep(iteratorRecord). + + ... +features: [array-grouping, Symbol.iterator] +---*/ + +const throwingIterator = { + [Symbol.iterator]: function () { + return this; + }, + next: function next() { + throw new Test262Error('next() method was called'); + } +}; + +assert.throws(Test262Error, function () { + Object.groupBy(throwingIterator, function () { + return 'key'; + }); +}); diff --git a/JSTests/test262/test/built-ins/Object/groupBy/length.js b/JSTests/test262/test/built-ins/Object/groupBy/length.js new file mode 100644 index 000000000000..6d7c1ff6d576 --- /dev/null +++ b/JSTests/test262/test/built-ins/Object/groupBy/length.js @@ -0,0 +1,25 @@ +// Copyright (c) 2023 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-object.groupby +description: Object.groupBy property length descriptor +info: | + Object.groupBy ( items, callbackfn ) + + ... + + 17 ECMAScript Standard Built-in Objects + + ... + +includes: [propertyHelper.js] +features: [array-grouping] +---*/ + +verifyProperty(Object.groupBy, "length", { + value: 2, + enumerable: false, + writable: false, + configurable: true +}); diff --git a/JSTests/test262/test/built-ins/Object/groupBy/name.js b/JSTests/test262/test/built-ins/Object/groupBy/name.js new file mode 100644 index 000000000000..6e4a96df67a9 --- /dev/null +++ b/JSTests/test262/test/built-ins/Object/groupBy/name.js @@ -0,0 +1,25 @@ +// Copyright (c) 2023 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-object.groupby +description: Object.groupBy property name descriptor +info: | + Object.groupBy ( items, callbackfn ) + + ... + + 17 ECMAScript Standard Built-in Objects + + ... + +includes: [propertyHelper.js] +features: [array-grouping] +---*/ + +verifyProperty(Object.groupBy, "name", { + value: "groupBy", + enumerable: false, + writable: false, + configurable: true +}); diff --git a/JSTests/test262/test/built-ins/Object/groupBy/null-prototype.js b/JSTests/test262/test/built-ins/Object/groupBy/null-prototype.js new file mode 100644 index 000000000000..d37fcb039970 --- /dev/null +++ b/JSTests/test262/test/built-ins/Object/groupBy/null-prototype.js @@ -0,0 +1,27 @@ +// Copyright (c) 2023 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-object.groupby +description: Object.groupBy returns a null prototype object +info: | + Object.groupBy ( items, callbackfn ) + + ... + + 2. Let obj be OrdinaryObjectCreate(null). + ... + 4. Return obj. + + ... +features: [array-grouping] +---*/ + +const array = [1, 2, 3]; + +const obj = Object.groupBy(array, function (i) { + return i % 2 === 0 ? 'even' : 'odd'; +}); + +assert.sameValue(Object.getPrototypeOf(obj), null); +assert.sameValue(obj.hasOwnProperty, undefined); diff --git a/JSTests/test262/test/built-ins/Object/groupBy/toPropertyKey.js b/JSTests/test262/test/built-ins/Object/groupBy/toPropertyKey.js new file mode 100644 index 000000000000..df3734fc0ca2 --- /dev/null +++ b/JSTests/test262/test/built-ins/Object/groupBy/toPropertyKey.js @@ -0,0 +1,36 @@ +// Copyright (c) 2023 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-object.groupby +description: Object.groupBy coerces return value with ToPropertyKey +info: | + Object.groupBy ( items, callbackfn ) + + ... + + GroupBy ( items, callbackfn, coercion ) + + 6. Repeat, + g. If coercion is property, then + i. Set key to Completion(ToPropertyKey(key)). + ii. IfAbruptCloseIterator(key, iteratorRecord). + + ... +includes: [compareArray.js] +features: [array-grouping] +---*/ + +let calls = 0; +const stringable = { + toString: function toString() { + return 1; + } +} + +const array = [1, '1', stringable]; + +const obj = Object.groupBy(array, function (v) { return v; }); + +assert.compareArray(Object.keys(obj), ['1']); +assert.compareArray(obj['1'], [1, '1', stringable]); diff --git a/JSTests/test262/test/built-ins/Object/prototype/toString/symbol-tag-non-str-builtin.js b/JSTests/test262/test/built-ins/Object/prototype/toString/symbol-tag-non-str-builtin.js index 7f636149a6fa..086b063e85c3 100644 --- a/JSTests/test262/test/built-ins/Object/prototype/toString/symbol-tag-non-str-builtin.js +++ b/JSTests/test262/test/built-ins/Object/prototype/toString/symbol-tag-non-str-builtin.js @@ -11,66 +11,69 @@ info: | 15. Let tag be ? Get(O, @@toStringTag). 16. If Type(tag) is not String, set tag to builtinTag. 17. Return the string-concatenation of "[object ", tag, and "]". -features: [Symbol.toStringTag, Symbol.iterator, generators, WeakMap] +features: [Symbol.toStringTag, Symbol.iterator, generators, WeakMap, iterator-helpers] ---*/ var toString = Object.prototype.toString; -var defaultTag = '[object Object]'; delete Symbol.prototype[Symbol.toStringTag]; -assert.sameValue(toString.call(Symbol('desc')), defaultTag); +assert.sameValue(toString.call(Symbol('desc')), '[object Object]'); Object.defineProperty(Math, Symbol.toStringTag, {value: Symbol()}); -assert.sameValue(toString.call(Math), defaultTag); +assert.sameValue(toString.call(Math), '[object Object]'); var strIter = ''[Symbol.iterator](); var strIterProto = Object.getPrototypeOf(strIter); +assert.sameValue(toString.call(strIter), '[object String Iterator]'); delete strIterProto[Symbol.toStringTag]; -assert.sameValue(toString.call(strIter), defaultTag); +assert.sameValue(toString.call(strIter), '[object Iterator]'); var arrIter = [][Symbol.iterator](); var arrIterProto = Object.getPrototypeOf(arrIter) +assert.sameValue(toString.call(arrIter), '[object Array Iterator]'); Object.defineProperty(arrIterProto, Symbol.toStringTag, {value: null}); -assert.sameValue(toString.call(arrIter), defaultTag); +assert.sameValue(toString.call(arrIter), '[object Object]'); var map = new Map(); delete Map.prototype[Symbol.toStringTag]; -assert.sameValue(toString.call(map), defaultTag); +assert.sameValue(toString.call(map), '[object Object]'); var mapIter = map[Symbol.iterator](); var mapIterProto = Object.getPrototypeOf(mapIter); +assert.sameValue(toString.call(mapIter), '[object Map Iterator]'); Object.defineProperty(mapIterProto, Symbol.toStringTag, { get: function() { return new String('ShouldNotBeUnwrapped'); }, }); -assert.sameValue(toString.call(mapIter), defaultTag); +assert.sameValue(toString.call(mapIter), '[object Object]'); var set = new Set(); delete Set.prototype[Symbol.toStringTag]; -assert.sameValue(toString.call(set), defaultTag); +assert.sameValue(toString.call(set), '[object Object]'); var setIter = set[Symbol.iterator](); var setIterProto = Object.getPrototypeOf(setIter); +assert.sameValue(toString.call(setIter), '[object Set Iterator]'); Object.defineProperty(setIterProto, Symbol.toStringTag, {value: false}); -assert.sameValue(toString.call(setIter), defaultTag); +assert.sameValue(toString.call(setIter), '[object Object]'); var wm = new WeakMap(); delete WeakMap.prototype[Symbol.toStringTag]; -assert.sameValue(toString.call(wm), defaultTag); +assert.sameValue(toString.call(wm), '[object Object]'); var ws = new WeakSet(); Object.defineProperty(WeakSet.prototype, Symbol.toStringTag, {value: 0}); -assert.sameValue(toString.call(ws), defaultTag); +assert.sameValue(toString.call(ws), '[object Object]'); delete JSON[Symbol.toStringTag]; -assert.sameValue(toString.call(JSON), defaultTag); +assert.sameValue(toString.call(JSON), '[object Object]'); var gen = (function* () {})(); var genProto = Object.getPrototypeOf(gen); Object.defineProperty(genProto, Symbol.toStringTag, { get: function() { return {}; }, }); -assert.sameValue(toString.call(gen), defaultTag); +assert.sameValue(toString.call(gen), '[object Object]'); var promise = new Promise(function() {}); delete Promise.prototype[Symbol.toStringTag]; -assert.sameValue(toString.call(promise), defaultTag); +assert.sameValue(toString.call(promise), '[object Object]'); diff --git a/JSTests/test262/test/built-ins/Proxy/has/trap-is-null-target-is-proxy.js b/JSTests/test262/test/built-ins/Proxy/has/trap-is-null-target-is-proxy.js index cce9fb9d5f58..a87eee65b1e9 100644 --- a/JSTests/test262/test/built-ins/Proxy/has/trap-is-null-target-is-proxy.js +++ b/JSTests/test262/test/built-ins/Proxy/has/trap-is-null-target-is-proxy.js @@ -14,7 +14,7 @@ info: | 6. Let trap be ? GetMethod(handler, "has"). 7. If trap is undefined, then a. Return ? target.[[HasProperty]](P). -features: [Proxy, Symbol, Reflect] +features: [Proxy, Symbol, Reflect, Array.prototype.includes] ---*/ var stringTarget = new Proxy(new String("str"), {}); diff --git a/JSTests/test262/test/built-ins/RegExp/prototype/exec/failure-lastindex-set.js b/JSTests/test262/test/built-ins/RegExp/prototype/exec/failure-lastindex-set.js index 41f08e330b74..b543c81207fa 100644 --- a/JSTests/test262/test/built-ins/RegExp/prototype/exec/failure-lastindex-set.js +++ b/JSTests/test262/test/built-ins/RegExp/prototype/exec/failure-lastindex-set.js @@ -23,6 +23,7 @@ info: | i. If _global_ is *true* or _sticky_ is *true*, then 1. Perform ? Set(_R_, *"lastIndex"*, *+0*𝔽, *true*). ii. Return *null*. +features: [exponentiation] ---*/ var R_g = /./g, R_y = /./y, R_gy = /./gy; diff --git a/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-01.js b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-01.js new file mode 100644 index 000000000000..056d772473d6 --- /dev/null +++ b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-01.js @@ -0,0 +1,19 @@ +// Copyright 2023 Mathias Bynens. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +author: Mathias Bynens +description: > + Some previously valid patterns with the `u` flag are now expected to + throw an early SyntaxError with the `v` flag. + https://github.com/tc39/proposal-regexp-v-flag#how-is-the-v-flag-different-from-the-u-flag +esid: sec-parsepattern +negative: + phase: parse + type: SyntaxError +features: [regexp-v-flag] +---*/ + +$DONOTEVALUATE(); + +/[(]/v; diff --git a/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-02.js b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-02.js new file mode 100644 index 000000000000..188f07451552 --- /dev/null +++ b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-02.js @@ -0,0 +1,19 @@ +// Copyright 2023 Mathias Bynens. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +author: Mathias Bynens +description: > + Some previously valid patterns with the `u` flag are now expected to + throw an early SyntaxError with the `v` flag. + https://github.com/tc39/proposal-regexp-v-flag#how-is-the-v-flag-different-from-the-u-flag +esid: sec-parsepattern +negative: + phase: parse + type: SyntaxError +features: [regexp-v-flag] +---*/ + +$DONOTEVALUATE(); + +/[)]/v; diff --git a/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-03.js b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-03.js new file mode 100644 index 000000000000..a0609ca7bac6 --- /dev/null +++ b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-03.js @@ -0,0 +1,19 @@ +// Copyright 2023 Mathias Bynens. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +author: Mathias Bynens +description: > + Some previously valid patterns with the `u` flag are now expected to + throw an early SyntaxError with the `v` flag. + https://github.com/tc39/proposal-regexp-v-flag#how-is-the-v-flag-different-from-the-u-flag +esid: sec-parsepattern +negative: + phase: parse + type: SyntaxError +features: [regexp-v-flag] +---*/ + +$DONOTEVALUATE(); + +/[[]/v; diff --git a/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-04.js b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-04.js new file mode 100644 index 000000000000..13788ae3e366 --- /dev/null +++ b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-04.js @@ -0,0 +1,19 @@ +// Copyright 2023 Mathias Bynens. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +author: Mathias Bynens +description: > + Some previously valid patterns with the `u` flag are now expected to + throw an early SyntaxError with the `v` flag. + https://github.com/tc39/proposal-regexp-v-flag#how-is-the-v-flag-different-from-the-u-flag +esid: sec-parsepattern +negative: + phase: parse + type: SyntaxError +features: [regexp-v-flag] +---*/ + +$DONOTEVALUATE(); + +/[{]/v; diff --git a/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-05.js b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-05.js new file mode 100644 index 000000000000..e71eaa618843 --- /dev/null +++ b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-05.js @@ -0,0 +1,19 @@ +// Copyright 2023 Mathias Bynens. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +author: Mathias Bynens +description: > + Some previously valid patterns with the `u` flag are now expected to + throw an early SyntaxError with the `v` flag. + https://github.com/tc39/proposal-regexp-v-flag#how-is-the-v-flag-different-from-the-u-flag +esid: sec-parsepattern +negative: + phase: parse + type: SyntaxError +features: [regexp-v-flag] +---*/ + +$DONOTEVALUATE(); + +/[}]/v; diff --git a/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-06.js b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-06.js new file mode 100644 index 000000000000..a87709359f7f --- /dev/null +++ b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-06.js @@ -0,0 +1,19 @@ +// Copyright 2023 Mathias Bynens. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +author: Mathias Bynens +description: > + Some previously valid patterns with the `u` flag are now expected to + throw an early SyntaxError with the `v` flag. + https://github.com/tc39/proposal-regexp-v-flag#how-is-the-v-flag-different-from-the-u-flag +esid: sec-parsepattern +negative: + phase: parse + type: SyntaxError +features: [regexp-v-flag] +---*/ + +$DONOTEVALUATE(); + +/[/]/v; diff --git a/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-07.js b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-07.js new file mode 100644 index 000000000000..1c1eb55b4d87 --- /dev/null +++ b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-07.js @@ -0,0 +1,19 @@ +// Copyright 2023 Mathias Bynens. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +author: Mathias Bynens +description: > + Some previously valid patterns with the `u` flag are now expected to + throw an early SyntaxError with the `v` flag. + https://github.com/tc39/proposal-regexp-v-flag#how-is-the-v-flag-different-from-the-u-flag +esid: sec-parsepattern +negative: + phase: parse + type: SyntaxError +features: [regexp-v-flag] +---*/ + +$DONOTEVALUATE(); + +/[-]/v; diff --git a/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-08.js b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-08.js new file mode 100644 index 000000000000..2713238ae68c --- /dev/null +++ b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-08.js @@ -0,0 +1,19 @@ +// Copyright 2023 Mathias Bynens. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +author: Mathias Bynens +description: > + Some previously valid patterns with the `u` flag are now expected to + throw an early SyntaxError with the `v` flag. + https://github.com/tc39/proposal-regexp-v-flag#how-is-the-v-flag-different-from-the-u-flag +esid: sec-parsepattern +negative: + phase: parse + type: SyntaxError +features: [regexp-v-flag] +---*/ + +$DONOTEVALUATE(); + +/[|]/v; diff --git a/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-09.js b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-09.js new file mode 100644 index 000000000000..ac3b30947e0d --- /dev/null +++ b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-09.js @@ -0,0 +1,19 @@ +// Copyright 2023 Mathias Bynens. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +author: Mathias Bynens +description: > + Some previously valid patterns with the `u` flag are now expected to + throw an early SyntaxError with the `v` flag. + https://github.com/tc39/proposal-regexp-v-flag#how-is-the-v-flag-different-from-the-u-flag +esid: sec-parsepattern +negative: + phase: parse + type: SyntaxError +features: [regexp-v-flag] +---*/ + +$DONOTEVALUATE(); + +/[&&]/v; diff --git a/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-10.js b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-10.js new file mode 100644 index 000000000000..2601ab0c356b --- /dev/null +++ b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-10.js @@ -0,0 +1,19 @@ +// Copyright 2023 Mathias Bynens. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +author: Mathias Bynens +description: > + Some previously valid patterns with the `u` flag are now expected to + throw an early SyntaxError with the `v` flag. + https://github.com/tc39/proposal-regexp-v-flag#how-is-the-v-flag-different-from-the-u-flag +esid: sec-parsepattern +negative: + phase: parse + type: SyntaxError +features: [regexp-v-flag] +---*/ + +$DONOTEVALUATE(); + +/[!!]/v; diff --git a/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-11.js b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-11.js new file mode 100644 index 000000000000..e7e9d1934c5e --- /dev/null +++ b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-11.js @@ -0,0 +1,19 @@ +// Copyright 2023 Mathias Bynens. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +author: Mathias Bynens +description: > + Some previously valid patterns with the `u` flag are now expected to + throw an early SyntaxError with the `v` flag. + https://github.com/tc39/proposal-regexp-v-flag#how-is-the-v-flag-different-from-the-u-flag +esid: sec-parsepattern +negative: + phase: parse + type: SyntaxError +features: [regexp-v-flag] +---*/ + +$DONOTEVALUATE(); + +/[##]/v; diff --git a/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-12.js b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-12.js new file mode 100644 index 000000000000..3a5706e748f3 --- /dev/null +++ b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-12.js @@ -0,0 +1,19 @@ +// Copyright 2023 Mathias Bynens. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +author: Mathias Bynens +description: > + Some previously valid patterns with the `u` flag are now expected to + throw an early SyntaxError with the `v` flag. + https://github.com/tc39/proposal-regexp-v-flag#how-is-the-v-flag-different-from-the-u-flag +esid: sec-parsepattern +negative: + phase: parse + type: SyntaxError +features: [regexp-v-flag] +---*/ + +$DONOTEVALUATE(); + +/[$$]/v; diff --git a/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-13.js b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-13.js new file mode 100644 index 000000000000..0694111a1baa --- /dev/null +++ b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-13.js @@ -0,0 +1,19 @@ +// Copyright 2023 Mathias Bynens. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +author: Mathias Bynens +description: > + Some previously valid patterns with the `u` flag are now expected to + throw an early SyntaxError with the `v` flag. + https://github.com/tc39/proposal-regexp-v-flag#how-is-the-v-flag-different-from-the-u-flag +esid: sec-parsepattern +negative: + phase: parse + type: SyntaxError +features: [regexp-v-flag] +---*/ + +$DONOTEVALUATE(); + +/[%%]/v; diff --git a/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-14.js b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-14.js new file mode 100644 index 000000000000..8e2c28a11cf5 --- /dev/null +++ b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-14.js @@ -0,0 +1,19 @@ +// Copyright 2023 Mathias Bynens. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +author: Mathias Bynens +description: > + Some previously valid patterns with the `u` flag are now expected to + throw an early SyntaxError with the `v` flag. + https://github.com/tc39/proposal-regexp-v-flag#how-is-the-v-flag-different-from-the-u-flag +esid: sec-parsepattern +negative: + phase: parse + type: SyntaxError +features: [regexp-v-flag] +---*/ + +$DONOTEVALUATE(); + +/[**]/v; diff --git a/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-15.js b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-15.js new file mode 100644 index 000000000000..9dfa5464456c --- /dev/null +++ b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-15.js @@ -0,0 +1,19 @@ +// Copyright 2023 Mathias Bynens. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +author: Mathias Bynens +description: > + Some previously valid patterns with the `u` flag are now expected to + throw an early SyntaxError with the `v` flag. + https://github.com/tc39/proposal-regexp-v-flag#how-is-the-v-flag-different-from-the-u-flag +esid: sec-parsepattern +negative: + phase: parse + type: SyntaxError +features: [regexp-v-flag] +---*/ + +$DONOTEVALUATE(); + +/[++]/v; diff --git a/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-16.js b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-16.js new file mode 100644 index 000000000000..8f8e42e76920 --- /dev/null +++ b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-16.js @@ -0,0 +1,19 @@ +// Copyright 2023 Mathias Bynens. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +author: Mathias Bynens +description: > + Some previously valid patterns with the `u` flag are now expected to + throw an early SyntaxError with the `v` flag. + https://github.com/tc39/proposal-regexp-v-flag#how-is-the-v-flag-different-from-the-u-flag +esid: sec-parsepattern +negative: + phase: parse + type: SyntaxError +features: [regexp-v-flag] +---*/ + +$DONOTEVALUATE(); + +/[,,]/v; diff --git a/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-17.js b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-17.js new file mode 100644 index 000000000000..e3b8baefaa07 --- /dev/null +++ b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-17.js @@ -0,0 +1,19 @@ +// Copyright 2023 Mathias Bynens. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +author: Mathias Bynens +description: > + Some previously valid patterns with the `u` flag are now expected to + throw an early SyntaxError with the `v` flag. + https://github.com/tc39/proposal-regexp-v-flag#how-is-the-v-flag-different-from-the-u-flag +esid: sec-parsepattern +negative: + phase: parse + type: SyntaxError +features: [regexp-v-flag] +---*/ + +$DONOTEVALUATE(); + +/[..]/v; diff --git a/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-18.js b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-18.js new file mode 100644 index 000000000000..229ac0d71db8 --- /dev/null +++ b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-18.js @@ -0,0 +1,19 @@ +// Copyright 2023 Mathias Bynens. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +author: Mathias Bynens +description: > + Some previously valid patterns with the `u` flag are now expected to + throw an early SyntaxError with the `v` flag. + https://github.com/tc39/proposal-regexp-v-flag#how-is-the-v-flag-different-from-the-u-flag +esid: sec-parsepattern +negative: + phase: parse + type: SyntaxError +features: [regexp-v-flag] +---*/ + +$DONOTEVALUATE(); + +/[::]/v; diff --git a/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-19.js b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-19.js new file mode 100644 index 000000000000..459b24b56676 --- /dev/null +++ b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-19.js @@ -0,0 +1,19 @@ +// Copyright 2023 Mathias Bynens. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +author: Mathias Bynens +description: > + Some previously valid patterns with the `u` flag are now expected to + throw an early SyntaxError with the `v` flag. + https://github.com/tc39/proposal-regexp-v-flag#how-is-the-v-flag-different-from-the-u-flag +esid: sec-parsepattern +negative: + phase: parse + type: SyntaxError +features: [regexp-v-flag] +---*/ + +$DONOTEVALUATE(); + +/[;;]/v; diff --git a/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-20.js b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-20.js new file mode 100644 index 000000000000..30256f724cac --- /dev/null +++ b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-20.js @@ -0,0 +1,19 @@ +// Copyright 2023 Mathias Bynens. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +author: Mathias Bynens +description: > + Some previously valid patterns with the `u` flag are now expected to + throw an early SyntaxError with the `v` flag. + https://github.com/tc39/proposal-regexp-v-flag#how-is-the-v-flag-different-from-the-u-flag +esid: sec-parsepattern +negative: + phase: parse + type: SyntaxError +features: [regexp-v-flag] +---*/ + +$DONOTEVALUATE(); + +/[<<]/v; diff --git a/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-21.js b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-21.js new file mode 100644 index 000000000000..48c1d9c4d655 --- /dev/null +++ b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-21.js @@ -0,0 +1,19 @@ +// Copyright 2023 Mathias Bynens. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +author: Mathias Bynens +description: > + Some previously valid patterns with the `u` flag are now expected to + throw an early SyntaxError with the `v` flag. + https://github.com/tc39/proposal-regexp-v-flag#how-is-the-v-flag-different-from-the-u-flag +esid: sec-parsepattern +negative: + phase: parse + type: SyntaxError +features: [regexp-v-flag] +---*/ + +$DONOTEVALUATE(); + +/[==]/v; diff --git a/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-22.js b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-22.js new file mode 100644 index 000000000000..93e103a242da --- /dev/null +++ b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-22.js @@ -0,0 +1,19 @@ +// Copyright 2023 Mathias Bynens. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +author: Mathias Bynens +description: > + Some previously valid patterns with the `u` flag are now expected to + throw an early SyntaxError with the `v` flag. + https://github.com/tc39/proposal-regexp-v-flag#how-is-the-v-flag-different-from-the-u-flag +esid: sec-parsepattern +negative: + phase: parse + type: SyntaxError +features: [regexp-v-flag] +---*/ + +$DONOTEVALUATE(); + +/[>>]/v; diff --git a/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-23.js b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-23.js new file mode 100644 index 000000000000..79ef3b45da8d --- /dev/null +++ b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-23.js @@ -0,0 +1,19 @@ +// Copyright 2023 Mathias Bynens. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +author: Mathias Bynens +description: > + Some previously valid patterns with the `u` flag are now expected to + throw an early SyntaxError with the `v` flag. + https://github.com/tc39/proposal-regexp-v-flag#how-is-the-v-flag-different-from-the-u-flag +esid: sec-parsepattern +negative: + phase: parse + type: SyntaxError +features: [regexp-v-flag] +---*/ + +$DONOTEVALUATE(); + +/[??]/v; diff --git a/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-24.js b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-24.js new file mode 100644 index 000000000000..018f9bb90923 --- /dev/null +++ b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-24.js @@ -0,0 +1,19 @@ +// Copyright 2023 Mathias Bynens. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +author: Mathias Bynens +description: > + Some previously valid patterns with the `u` flag are now expected to + throw an early SyntaxError with the `v` flag. + https://github.com/tc39/proposal-regexp-v-flag#how-is-the-v-flag-different-from-the-u-flag +esid: sec-parsepattern +negative: + phase: parse + type: SyntaxError +features: [regexp-v-flag] +---*/ + +$DONOTEVALUATE(); + +/[@@]/v; diff --git a/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-25.js b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-25.js new file mode 100644 index 000000000000..a4d71ca91c53 --- /dev/null +++ b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-25.js @@ -0,0 +1,19 @@ +// Copyright 2023 Mathias Bynens. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +author: Mathias Bynens +description: > + Some previously valid patterns with the `u` flag are now expected to + throw an early SyntaxError with the `v` flag. + https://github.com/tc39/proposal-regexp-v-flag#how-is-the-v-flag-different-from-the-u-flag +esid: sec-parsepattern +negative: + phase: parse + type: SyntaxError +features: [regexp-v-flag] +---*/ + +$DONOTEVALUATE(); + +/[``]/v; diff --git a/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-26.js b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-26.js new file mode 100644 index 000000000000..c6b159f14461 --- /dev/null +++ b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-26.js @@ -0,0 +1,19 @@ +// Copyright 2023 Mathias Bynens. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +author: Mathias Bynens +description: > + Some previously valid patterns with the `u` flag are now expected to + throw an early SyntaxError with the `v` flag. + https://github.com/tc39/proposal-regexp-v-flag#how-is-the-v-flag-different-from-the-u-flag +esid: sec-parsepattern +negative: + phase: parse + type: SyntaxError +features: [regexp-v-flag] +---*/ + +$DONOTEVALUATE(); + +/[~~]/v; diff --git a/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-27.js b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-27.js new file mode 100644 index 000000000000..09f02ac44da2 --- /dev/null +++ b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-27.js @@ -0,0 +1,19 @@ +// Copyright 2023 Mathias Bynens. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +author: Mathias Bynens +description: > + Some previously valid patterns with the `u` flag are now expected to + throw an early SyntaxError with the `v` flag. + https://github.com/tc39/proposal-regexp-v-flag#how-is-the-v-flag-different-from-the-u-flag +esid: sec-parsepattern +negative: + phase: parse + type: SyntaxError +features: [regexp-v-flag] +---*/ + +$DONOTEVALUATE(); + +/[^^^]/v; diff --git a/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-28.js b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-28.js new file mode 100644 index 000000000000..7f84741a6fd8 --- /dev/null +++ b/JSTests/test262/test/built-ins/RegExp/prototype/unicodeSets/breaking-change-from-u-to-v-28.js @@ -0,0 +1,19 @@ +// Copyright 2023 Mathias Bynens. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +author: Mathias Bynens +description: > + Some previously valid patterns with the `u` flag are now expected to + throw an early SyntaxError with the `v` flag. + https://github.com/tc39/proposal-regexp-v-flag#how-is-the-v-flag-different-from-the-u-flag +esid: sec-parsepattern +negative: + phase: parse + type: SyntaxError +features: [regexp-v-flag] +---*/ + +$DONOTEVALUATE(); + +/[_^^]/v; diff --git a/JSTests/test262/test/built-ins/Set/valid-values.js b/JSTests/test262/test/built-ins/Set/valid-values.js index 2f7e6a33c69f..9f93ba0ad52c 100644 --- a/JSTests/test262/test/built-ins/Set/valid-values.js +++ b/JSTests/test262/test/built-ins/Set/valid-values.js @@ -14,7 +14,7 @@ info: | Append value as the last element of entries. ... -features: [BigInt, Symbol, TypedArray, WeakRef] +features: [BigInt, Symbol, TypedArray, WeakRef, exponentiation] ---*/ diff --git a/JSTests/test262/test/built-ins/ShadowRealm/prototype/evaluate/globalthis-config-only-properties.js b/JSTests/test262/test/built-ins/ShadowRealm/prototype/evaluate/globalthis-config-only-properties.js index 6b6857f6c1ae..d630ddb43f67 100644 --- a/JSTests/test262/test/built-ins/ShadowRealm/prototype/evaluate/globalthis-config-only-properties.js +++ b/JSTests/test262/test/built-ins/ShadowRealm/prototype/evaluate/globalthis-config-only-properties.js @@ -25,7 +25,7 @@ info: | The host may use this hook to add properties to the ShadowRealm's global object. Those properties must be configurable. -features: [ShadowRealm] +features: [ShadowRealm, Array.prototype.includes] ---*/ assert.sameValue( diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/from/calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/Calendar/from/calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 2559b7772446..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/from/calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,20 +0,0 @@ -// 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.from -description: > - A Temporal.Calendar instance passed to from() does not have its - 'calendar' property observably checked -features: [Temporal] ----*/ - -const arg = new Temporal.Calendar("iso8601"); -Object.defineProperty(arg, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -Temporal.Calendar.from(arg); -Temporal.Calendar.from({ calendar: arg }); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/from/calendar-object-invalid.js b/JSTests/test262/test/built-ins/Temporal/Calendar/from/calendar-object-invalid.js deleted file mode 100644 index fe70acdc985d..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/from/calendar-object-invalid.js +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.calendar.from -description: Converting objects to Temporal.Calendar -features: [Temporal] ----*/ - -assert.throws(RangeError, () => Temporal.Calendar.from({ calendar: "local" })); -assert.throws(RangeError, () => Temporal.Calendar.from({ calendar: { calendar: "iso8601" } })); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/from/calendar-object-operations.js b/JSTests/test262/test/built-ins/Temporal/Calendar/from/calendar-object-operations.js deleted file mode 100644 index 00033b768e6e..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/from/calendar-object-operations.js +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.calendar.from -description: Converting objects to Temporal.Calendar -includes: [compareArray.js, temporalHelpers.js] -features: [Temporal] ----*/ - -const expected = [ - "has outer.calendar", - "get outer.calendar", - "has inner.calendar", - "get inner.toString", - "call inner.toString", -]; -const actual = []; -const calendar = TemporalHelpers.propertyBagObserver(actual, { - calendar: new Proxy(TemporalHelpers.toPrimitiveObserver(actual, "iso8601", "inner"), { - has(t, p) { - actual.push(`has inner.${p}`); - return true; - }, - get(t, p) { - return t[p]; - }, - }), -}, "outer"); -const result = Temporal.Calendar.from(calendar); -assert.sameValue(result.id, "iso8601"); -assert.compareArray(actual, expected); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/from/calendar-object.js b/JSTests/test262/test/built-ins/Temporal/Calendar/from/calendar-object.js index cb680a26d8c1..c63e94ebc2be 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/from/calendar-object.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/from/calendar-object.js @@ -3,19 +3,33 @@ /*--- esid: sec-temporal.calendar.from -description: Converting objects to Temporal.Calendar +description: > + Converting an object implementing the Calendar protocol to Temporal.Calendar + gives the same object features: [Temporal] ---*/ -const cal = new Temporal.Calendar("iso8601"); -const calFromObject = Temporal.Calendar.from({ calendar: cal }); -assert(calFromObject instanceof Temporal.Calendar); -assert.sameValue(calFromObject.id, "iso8601"); - -const calFromString = Temporal.Calendar.from({ calendar: "iso8601" }); -assert(calFromString instanceof Temporal.Calendar); -assert.sameValue(calFromString.id, "iso8601"); - -const custom = { id: "custom-calendar" }; -assert.sameValue(Temporal.Calendar.from({ calendar: custom }), custom); +const custom = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "custom-calendar", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; assert.sameValue(Temporal.Calendar.from(custom), custom); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/from/calendar-string-leap-second.js b/JSTests/test262/test/built-ins/Temporal/Calendar/from/calendar-string-leap-second.js index 88ec4b5ac8d7..4164b0c8abfc 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/from/calendar-string-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/from/calendar-string-leap-second.js @@ -7,18 +7,10 @@ description: Leap second is a valid ISO string for Calendar features: [Temporal] ---*/ -let arg = "2016-12-31T23:59:60"; -const result1 = Temporal.Calendar.from(arg); +const arg = "2016-12-31T23:59:60"; +const result = Temporal.Calendar.from(arg); assert.sameValue( - result1.id, + result.id, "iso8601", "leap second is a valid ISO string for Calendar" ); - -arg = { calendar: "2016-12-31T23:59:60" }; -const result2 = Temporal.Calendar.from(arg); -assert.sameValue( - result2.id, - "iso8601", - "leap second is a valid ISO string for Calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/from/calendar-temporal-object.js b/JSTests/test262/test/built-ins/Temporal/Calendar/from/calendar-temporal-object.js index 49415f97d199..10c09d3c4861 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/from/calendar-temporal-object.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/from/calendar-temporal-object.js @@ -6,7 +6,7 @@ esid: sec-temporal.calendar.from description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots info: | sec-temporal-totemporalcalendar step 1.b: - b. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then + b. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then i. Return _temporalCalendarLike_.[[Calendar]]. includes: [compareArray.js] features: [Temporal] @@ -14,12 +14,11 @@ features: [Temporal] const plainDate = new Temporal.PlainDate(2000, 5, 2); const plainDateTime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); -const plainTime = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); const plainMonthDay = new Temporal.PlainMonthDay(5, 2); const plainYearMonth = new Temporal.PlainYearMonth(2000, 5); const zonedDateTime = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); -[plainDate, plainDateTime, plainTime, plainMonthDay, plainYearMonth, zonedDateTime].forEach((arg) => { +[plainDate, plainDateTime, plainMonthDay, plainYearMonth, zonedDateTime].forEach((arg) => { const actual = []; const expected = []; @@ -33,7 +32,7 @@ const zonedDateTime = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UT }); const result = Temporal.Calendar.from(arg); - assert.sameValue(result, calendar, "Temporal object coerced to calendar"); + assert.sameValue(result.id, calendar, "Temporal object coerced to calendar"); assert.compareArray(actual, expected, "calendar getter not called"); }); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/from/calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/Calendar/from/calendar-wrong-type.js index e97e4d905d3a..6a5586988541 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/from/calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/from/calendar-wrong-type.js @@ -15,19 +15,19 @@ const rangeErrorTests = [ ["", "empty string"], [1, "number that doesn't convert to a valid ISO string"], [1n, "bigint"], - [new Temporal.TimeZone("UTC"), "time zone instance"], ]; for (const [arg, description] of rangeErrorTests) { assert.throws(RangeError, () => Temporal.Calendar.from(arg), `${description} does not convert to a valid ISO string`); - assert.throws(RangeError, () => Temporal.Calendar.from({ calendar: arg }), `${description} does not convert to a valid ISO string (in property bag)`); } const typeErrorTests = [ [Symbol(), "symbol"], + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], ]; for (const [arg, description] of typeErrorTests) { assert.throws(TypeError, () => Temporal.Calendar.from(arg), `${description} is not a valid object and does not convert to a string`); - assert.throws(TypeError, () => Temporal.Calendar.from({ calendar: arg }), `${description} is not a valid object and does not convert to a string (in property bag)`); } diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-case-insensitive.js index 57c535a19d75..4f84deeef4b9 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-case-insensitive.js @@ -12,10 +12,6 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = "IsO8601"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.dateAdd(arg, new Temporal.Duration()); -TemporalHelpers.assertPlainDate(result1, 1976, 11, "M11", 18, "Calendar is case-insensitive"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.dateAdd(arg, new Temporal.Duration()); -TemporalHelpers.assertPlainDate(result2, 1976, 11, "M11", 18, "Calendar is case-insensitive (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.dateAdd(arg, new Temporal.Duration()); +TemporalHelpers.assertPlainDate(result, 1976, 11, "M11", 18, "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 83226348d627..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,25 +0,0 @@ -// 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: > - A Temporal.Calendar instance passed to dateAdd() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.Calendar("iso8601"); - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -instance.dateAdd(arg, new Temporal.Duration()); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -instance.dateAdd(arg, new Temporal.Duration()); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-leap-second.js index e310aaeac9f1..1813e3082f30 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-leap-second.js @@ -12,18 +12,10 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = "2016-12-31T23:59:60"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.dateAdd(arg, new Temporal.Duration()); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.dateAdd(arg, new Temporal.Duration()); TemporalHelpers.assertPlainDate( - result1, + result, 1976, 11, "M11", 18, "leap second is a valid ISO string for calendar" ); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.dateAdd(arg, new Temporal.Duration()); -TemporalHelpers.assertPlainDate( - result2, - 1976, 11, "M11", 18, - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-number.js index 4d585142dcec..ca13276933bc 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-number.js @@ -12,13 +12,9 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = 19970327; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.dateAdd(arg, new Temporal.Duration()); -TemporalHelpers.assertPlainDate(result1, 1976, 11, "M11", 18, "19970327 is a valid ISO string for calendar"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.dateAdd(arg, new Temporal.Duration()); -TemporalHelpers.assertPlainDate(result2, 1976, 11, "M11", 18, "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.dateAdd(arg, new Temporal.Duration()); +TemporalHelpers.assertPlainDate(result, 1976, 11, "M11", 18, "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -27,16 +23,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; assert.throws( RangeError, () => instance.dateAdd(arg, new Temporal.Duration()), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.dateAdd(arg, new Temporal.Duration()), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-wrong-type.js index a868f5578c65..c0632bc6d10d 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-wrong-type.js @@ -21,27 +21,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.dateAdd(arg, new Temporal.Duration()), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.dateAdd(arg, new Temporal.Duration()), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.dateAdd(arg, new Temporal.Duration()), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.dateAdd(arg, new Temporal.Duration()), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.dateAdd(arg, new Temporal.Duration()), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-calendar-annotation.js index 90decf88f54f..f1410a3bec44 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-calendar-annotation.js @@ -16,7 +16,6 @@ const tests = [ ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const instance = new Temporal.Calendar("iso8601"); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..a379e8440b49 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 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: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.dateAdd(arg, new Temporal.Duration()), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateAdd/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateAdd/order-of-operations.js index fccca03befea..4a8d9c7d41cb 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateAdd/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateAdd/order-of-operations.js @@ -9,9 +9,29 @@ features: [Temporal] ---*/ const expected = [ - // ToTemporalDate → GetTemporalCalendarWithISODefault + // ToTemporalDate → GetTemporalCalendarSlotValueWithISODefault "get date.calendar", - "has date.calendar.calendar", + "has date.calendar.dateAdd", + "has date.calendar.dateFromFields", + "has date.calendar.dateUntil", + "has date.calendar.day", + "has date.calendar.dayOfWeek", + "has date.calendar.dayOfYear", + "has date.calendar.daysInMonth", + "has date.calendar.daysInWeek", + "has date.calendar.daysInYear", + "has date.calendar.fields", + "has date.calendar.id", + "has date.calendar.inLeapYear", + "has date.calendar.mergeFields", + "has date.calendar.month", + "has date.calendar.monthCode", + "has date.calendar.monthDayFromFields", + "has date.calendar.monthsInYear", + "has date.calendar.weekOfYear", + "has date.calendar.year", + "has date.calendar.yearMonthFromFields", + "has date.calendar.yearOfWeek", // ToTemporalDate → CalendarFields "get date.calendar.fields", "call date.calendar.fields", diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateFromFields/one-of-era-erayear-undefined.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateFromFields/one-of-era-erayear-undefined.js new file mode 100644 index 000000000000..4d36b89c8186 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateFromFields/one-of-era-erayear-undefined.js @@ -0,0 +1,16 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.datefromfields +description: Does not throw a RangeError if only one of era/eraYear fields is present +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const base = { year: 2000, month: 5, day: 2, era: 'ce' }; +const instance = new Temporal.Calendar('iso8601'); +TemporalHelpers.assertPlainDate(instance.dateFromFields({ ...base }), 2000, 5, 'M05', 2); + +const base2 = { year: 2000, month: 5, day: 2, eraYear: 1 }; +TemporalHelpers.assertPlainDate(instance.dateFromFields({ ...base }), 2000, 5, 'M05', 2); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateFromFields/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateFromFields/order-of-operations.js index 60b0540938d1..e28b27c28130 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateFromFields/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateFromFields/order-of-operations.js @@ -42,5 +42,5 @@ const options = TemporalHelpers.propertyBagObserver(actual, { const result = instance.dateFromFields(fields, options); TemporalHelpers.assertPlainDate(result, 1, 1, "M01", 1, "date result"); -assert.sameValue(result.calendar, instance, "calendar result"); +assert.sameValue(result.getISOFields().calendar, "iso8601", "calendar slot should store a string"); assert.compareArray(actual, expected, "order of operations"); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-case-insensitive.js index 214d04f70250..0055d3b8bf3e 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-case-insensitive.js @@ -12,14 +12,8 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = "IsO8601"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; const result1 = instance.dateUntil(arg, new Temporal.PlainDate(1976, 11, 19)); TemporalHelpers.assertDuration(result1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "Calendar is case-insensitive (first argument)"); const result2 = instance.dateUntil(new Temporal.PlainDate(1976, 11, 19), arg); TemporalHelpers.assertDuration(result2, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "Calendar is case-insensitive (second argument)"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result3 = instance.dateUntil(arg, new Temporal.PlainDate(1976, 11, 19)); -TemporalHelpers.assertDuration(result3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "Calendar is case-insensitive (nested property, first argument)"); -const result4 = instance.dateUntil(new Temporal.PlainDate(1976, 11, 19), arg); -TemporalHelpers.assertDuration(result4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "Calendar is case-insensitive (nested property, second argument)"); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 645c5583d4f1..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,22 +0,0 @@ -// 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: > - A Temporal.Calendar instance passed to dateUntil() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.Calendar("iso8601"); - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -instance.dateUntil(arg, arg); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-leap-second.js index ba6e4372f1f5..daf2fe1e66ef 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-leap-second.js @@ -12,14 +12,8 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = "2016-12-31T23:59:60"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; const result1 = instance.dateUntil(arg, new Temporal.PlainDate(1976, 11, 19)); TemporalHelpers.assertDuration(result1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "leap second is a valid ISO string for calendar (first argument)"); const result2 = instance.dateUntil(new Temporal.PlainDate(1976, 11, 19), arg); TemporalHelpers.assertDuration(result2, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "leap second is a valid ISO string for calendar (second argument)"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result3 = instance.dateUntil(arg, new Temporal.PlainDate(1976, 11, 19)); -TemporalHelpers.assertDuration(result3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "leap second is a valid ISO string for calendar (nested property, first argument)"); -const result4 = instance.dateUntil(new Temporal.PlainDate(1976, 11, 19), arg); -TemporalHelpers.assertDuration(result4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "leap second is a valid ISO string for calendar (nested property, second argument)"); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-number.js index a9fd22361634..9efada773e74 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-number.js @@ -12,18 +12,12 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = 19970327; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; const result1 = instance.dateUntil(arg, new Temporal.PlainDate(1976, 11, 19)); TemporalHelpers.assertDuration(result1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar (first argument)"); const result2 = instance.dateUntil(new Temporal.PlainDate(1976, 11, 19), arg); TemporalHelpers.assertDuration(result2, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar (second argument)"); -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result3 = instance.dateUntil(arg, new Temporal.PlainDate(1976, 11, 19)); -TemporalHelpers.assertDuration(result3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar (nested property, first argument)"); -const result4 = instance.dateUntil(new Temporal.PlainDate(1976, 11, 19), arg); -TemporalHelpers.assertDuration(result4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar (nested property, second argument)"); - const numbers = [ 1, -19970327, @@ -31,7 +25,7 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; assert.throws( RangeError, () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)), @@ -42,15 +36,4 @@ for (const calendar of numbers) { () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg), `Number ${calendar} does not convert to a valid ISO string for calendar (second argument)` ); - arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property, first argument)` - ); - assert.throws( - RangeError, - () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property, second argument)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-string.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-string.js index 30aa19220c6f..77dc4a82b503 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-string.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-string.js @@ -9,6 +9,13 @@ features: [Temporal] ---*/ const instance = new Temporal.Calendar("iso8601"); +Object.defineProperty(instance, "dateFromFields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("dateFromFields should not be looked up on receiver"); + }, +}); const calendar = "iso8601"; diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-wrong-type.js index 5a974bbb173a..2ed2dbc256f9 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-wrong-type.js @@ -18,36 +18,24 @@ const rangeErrorTests = [ ["", "empty string"], [1, "number that doesn't convert to a valid ISO string"], [1n, "bigint"], - [new Temporal.TimeZone("UTC"), "time zone instance"], ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)), `${description} does not convert to a valid ISO string (first argument)`); assert.throws(RangeError, () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg), `${description} does not convert to a valid ISO string (second argument)`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)), `${description} does not convert to a valid ISO string (nested property, first argument)`); - assert.throws(RangeError, () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg), `${description} does not convert to a valid ISO string (nested property, second argument)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)), `${description} is not a valid property bag and does not convert to a string (first argument)`); assert.throws(TypeError, () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg), `${description} is not a valid property bag and does not convert to a string (second argument)`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)), `${description} is not a valid property bag and does not convert to a string (nested property, first argument)`); - assert.throws(TypeError, () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg), `${description} is not a valid property bag and does not convert to a string (nested property, second argument)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)), `nested undefined calendar property is always a RangeError (first argument)`); -assert.throws(RangeError, () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg), `nested undefined calendar property is always a RangeError (second argument)`); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-calendar-annotation.js index 0817c8e16bf7..12548196effb 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-calendar-annotation.js @@ -16,7 +16,6 @@ const tests = [ ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const instance = new Temporal.Calendar("iso8601"); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..59ecbccad7cd --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-multiple-calendar.js @@ -0,0 +1,34 @@ +// Copyright (C) 2023 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: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)), + `reject more than one calendar annotation if any critical: ${arg} (first argument)` + ); + assert.throws( + RangeError, + () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg), + `reject more than one calendar annotation if any critical: ${arg} (second argument)` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateUntil/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateUntil/order-of-operations.js index b15bf8bc367b..0f0adbf439bf 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateUntil/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dateUntil/order-of-operations.js @@ -9,9 +9,29 @@ features: [Temporal] ---*/ const expected = [ - // ToTemporalDate 1 → GetTemporalCalendarWithISODefault + // ToTemporalDate 1 → GetTemporalCalendarSlotValueWithISODefault "get one.calendar", - "has one.calendar.calendar", + "has one.calendar.dateAdd", + "has one.calendar.dateFromFields", + "has one.calendar.dateUntil", + "has one.calendar.day", + "has one.calendar.dayOfWeek", + "has one.calendar.dayOfYear", + "has one.calendar.daysInMonth", + "has one.calendar.daysInWeek", + "has one.calendar.daysInYear", + "has one.calendar.fields", + "has one.calendar.id", + "has one.calendar.inLeapYear", + "has one.calendar.mergeFields", + "has one.calendar.month", + "has one.calendar.monthCode", + "has one.calendar.monthDayFromFields", + "has one.calendar.monthsInYear", + "has one.calendar.weekOfYear", + "has one.calendar.year", + "has one.calendar.yearMonthFromFields", + "has one.calendar.yearOfWeek", // ToTemporalDate 1 → CalendarFields "get one.calendar.fields", "call one.calendar.fields", @@ -31,9 +51,29 @@ const expected = [ // ToTemporalDate 1 → CalendarDateFromFields "get one.calendar.dateFromFields", "call one.calendar.dateFromFields", - // ToTemporalDate 2 → GetTemporalCalendarWithISODefault + // ToTemporalDate 2 → GetTemporalCalendarSlotValueWithISODefault "get two.calendar", - "has two.calendar.calendar", + "has two.calendar.dateAdd", + "has two.calendar.dateFromFields", + "has two.calendar.dateUntil", + "has two.calendar.day", + "has two.calendar.dayOfWeek", + "has two.calendar.dayOfYear", + "has two.calendar.daysInMonth", + "has two.calendar.daysInWeek", + "has two.calendar.daysInYear", + "has two.calendar.fields", + "has two.calendar.id", + "has two.calendar.inLeapYear", + "has two.calendar.mergeFields", + "has two.calendar.month", + "has two.calendar.monthCode", + "has two.calendar.monthDayFromFields", + "has two.calendar.monthsInYear", + "has two.calendar.weekOfYear", + "has two.calendar.year", + "has two.calendar.yearMonthFromFields", + "has two.calendar.yearOfWeek", // ToTemporalDate 2 → CalendarFields "get two.calendar.fields", "call two.calendar.fields", diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-case-insensitive.js index 4719772acdfd..dffee306c0b6 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-case-insensitive.js @@ -11,10 +11,6 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = "IsO8601"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.day(arg); -assert.sameValue(result1, 18, "Calendar is case-insensitive"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.day(arg); -assert.sameValue(result2, 18, "Calendar is case-insensitive (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.day(arg); +assert.sameValue(result, 18, "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 3712975ec39f..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,25 +0,0 @@ -// 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.day -description: > - A Temporal.Calendar instance passed to day() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.Calendar("iso8601"); - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -instance.day(arg); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -instance.day(arg); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-leap-second.js index 2bf759b8a513..f147e6cf6264 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-leap-second.js @@ -11,18 +11,10 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = "2016-12-31T23:59:60"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.day(arg); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.day(arg); assert.sameValue( - result1, + result, 18, "leap second is a valid ISO string for calendar" ); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.day(arg); -assert.sameValue( - result2, - 18, - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-number.js index 403ca7f06d54..d269d715b75a 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-number.js @@ -11,13 +11,9 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = 19970327; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.day(arg); -assert.sameValue(result1, 18, "19970327 is a valid ISO string for calendar"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.day(arg); -assert.sameValue(result2, 18, "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.day(arg); +assert.sameValue(result, 18, "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -26,16 +22,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; assert.throws( RangeError, () => instance.day(arg), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.day(arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-wrong-type.js index 57c21e0ad9a9..60436f37507d 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-wrong-type.js @@ -21,27 +21,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.day(arg), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.day(arg), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.day(arg), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.day(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.day(arg), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/day/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/day/argument-string-calendar-annotation.js index f32c36f8e436..622017206ebf 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/day/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/day/argument-string-calendar-annotation.js @@ -15,7 +15,6 @@ const tests = [ ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const instance = new Temporal.Calendar("iso8601"); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/day/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/day/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..54c4b3fe5ef9 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/day/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.day +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.day(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-case-insensitive.js index 67139a93c1d2..1b285a463e4e 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-case-insensitive.js @@ -11,10 +11,6 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = "IsO8601"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.dayOfWeek(arg); -assert.sameValue(result1, 4, "Calendar is case-insensitive"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.dayOfWeek(arg); -assert.sameValue(result2, 4, "Calendar is case-insensitive (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.dayOfWeek(arg); +assert.sameValue(result, 4, "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index b9aad23a724c..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,25 +0,0 @@ -// 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.dayofweek -description: > - A Temporal.Calendar instance passed to dayOfWeek() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.Calendar("iso8601"); - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -instance.dayOfWeek(arg); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -instance.dayOfWeek(arg); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-leap-second.js index fcd0ca2d74d6..616fcd011815 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-leap-second.js @@ -11,18 +11,10 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = "2016-12-31T23:59:60"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.dayOfWeek(arg); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.dayOfWeek(arg); assert.sameValue( - result1, + result, 4, "leap second is a valid ISO string for calendar" ); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.dayOfWeek(arg); -assert.sameValue( - result2, - 4, - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-number.js index bc4d21ea1c3e..2f63aaac8ef0 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-number.js @@ -11,13 +11,9 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = 19970327; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.dayOfWeek(arg); -assert.sameValue(result1, 4, "19970327 is a valid ISO string for calendar"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.dayOfWeek(arg); -assert.sameValue(result2, 4, "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.dayOfWeek(arg); +assert.sameValue(result, 4, "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -26,16 +22,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; assert.throws( RangeError, () => instance.dayOfWeek(arg), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.dayOfWeek(arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-wrong-type.js index 03f9f143440f..c06e3be28dec 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-wrong-type.js @@ -21,27 +21,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.dayOfWeek(arg), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.dayOfWeek(arg), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.dayOfWeek(arg), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.dayOfWeek(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.dayOfWeek(arg), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-calendar-annotation.js index ce9230d65f5c..3f8737b22d39 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-calendar-annotation.js @@ -15,7 +15,6 @@ const tests = [ ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const instance = new Temporal.Calendar("iso8601"); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..51d52285afe8 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dayofweek +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.dayOfWeek(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-case-insensitive.js index 160354ee722f..d1d195f95406 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-case-insensitive.js @@ -11,10 +11,6 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = "IsO8601"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.dayOfYear(arg); -assert.sameValue(result1, 323, "Calendar is case-insensitive"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.dayOfYear(arg); -assert.sameValue(result2, 323, "Calendar is case-insensitive (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.dayOfYear(arg); +assert.sameValue(result, 323, "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 162a3217a7fa..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,25 +0,0 @@ -// 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.dayofyear -description: > - A Temporal.Calendar instance passed to dayOfYear() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.Calendar("iso8601"); - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -instance.dayOfYear(arg); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -instance.dayOfYear(arg); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-leap-second.js index d51b2c0dcb51..ca8263b8e193 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-leap-second.js @@ -11,18 +11,10 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = "2016-12-31T23:59:60"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.dayOfYear(arg); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.dayOfYear(arg); assert.sameValue( - result1, + result, 323, "leap second is a valid ISO string for calendar" ); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.dayOfYear(arg); -assert.sameValue( - result2, - 323, - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-number.js index f0447e0c1ce6..0e1536d43beb 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-number.js @@ -11,13 +11,9 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = 19970327; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.dayOfYear(arg); -assert.sameValue(result1, 323, "19970327 is a valid ISO string for calendar"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.dayOfYear(arg); -assert.sameValue(result2, 323, "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.dayOfYear(arg); +assert.sameValue(result, 323, "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -26,16 +22,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; assert.throws( RangeError, () => instance.dayOfYear(arg), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.dayOfYear(arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-wrong-type.js index f7ecf1684eb0..fb9ba3280588 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-wrong-type.js @@ -21,27 +21,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.dayOfYear(arg), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.dayOfYear(arg), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.dayOfYear(arg), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.dayOfYear(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.dayOfYear(arg), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-calendar-annotation.js index 0d0e1511b62d..0235ad75bee0 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-calendar-annotation.js @@ -15,7 +15,6 @@ const tests = [ ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const instance = new Temporal.Calendar("iso8601"); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..f66c4785e290 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dayofyear +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.dayOfYear(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-case-insensitive.js index c1b9ca391c68..ca24cf52ad2a 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-case-insensitive.js @@ -11,10 +11,6 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = "IsO8601"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.daysInMonth(arg); -assert.sameValue(result1, 30, "Calendar is case-insensitive"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.daysInMonth(arg); -assert.sameValue(result2, 30, "Calendar is case-insensitive (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.daysInMonth(arg); +assert.sameValue(result, 30, "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index c9a95836f3bd..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,25 +0,0 @@ -// 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.daysinmonth -description: > - A Temporal.Calendar instance passed to daysInMonth() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.Calendar("iso8601"); - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -instance.daysInMonth(arg); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -instance.daysInMonth(arg); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-leap-second.js index 763ae9c73ddf..40ce56d528ac 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-leap-second.js @@ -11,18 +11,10 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = "2016-12-31T23:59:60"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.daysInMonth(arg); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.daysInMonth(arg); assert.sameValue( - result1, + result, 30, "leap second is a valid ISO string for calendar" ); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.daysInMonth(arg); -assert.sameValue( - result2, - 30, - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-number.js index 2987dc0b11de..1f22a0391bdd 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-number.js @@ -11,13 +11,9 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = 19970327; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.daysInMonth(arg); -assert.sameValue(result1, 30, "19970327 is a valid ISO string for calendar"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.daysInMonth(arg); -assert.sameValue(result2, 30, "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.daysInMonth(arg); +assert.sameValue(result, 30, "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -26,16 +22,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; assert.throws( RangeError, () => instance.daysInMonth(arg), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.daysInMonth(arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-wrong-type.js index 9876bb18a9cc..973239dde566 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-wrong-type.js @@ -21,27 +21,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.daysInMonth(arg), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.daysInMonth(arg), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.daysInMonth(arg), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.daysInMonth(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.daysInMonth(arg), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-calendar-annotation.js index 28feba274df5..059c2aea6082 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-calendar-annotation.js @@ -15,7 +15,6 @@ const tests = [ ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const instance = new Temporal.Calendar("iso8601"); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..2738cd5d665e --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.daysinmonth +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.daysInMonth(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-case-insensitive.js index 2123e069bda8..6616112eb03c 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-case-insensitive.js @@ -11,10 +11,6 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = "IsO8601"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.daysInWeek(arg); -assert.sameValue(result1, 7, "Calendar is case-insensitive"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.daysInWeek(arg); -assert.sameValue(result2, 7, "Calendar is case-insensitive (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.daysInWeek(arg); +assert.sameValue(result, 7, "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 571b1e1c1146..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,25 +0,0 @@ -// 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.daysinweek -description: > - A Temporal.Calendar instance passed to daysInWeek() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.Calendar("iso8601"); - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -instance.daysInWeek(arg); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -instance.daysInWeek(arg); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-leap-second.js index 4d6d407a78ad..ff74cf1de1c8 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-leap-second.js @@ -11,18 +11,10 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = "2016-12-31T23:59:60"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.daysInWeek(arg); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.daysInWeek(arg); assert.sameValue( - result1, + result, 7, "leap second is a valid ISO string for calendar" ); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.daysInWeek(arg); -assert.sameValue( - result2, - 7, - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-number.js index 473cd6a4333f..59d1722bae70 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-number.js @@ -11,13 +11,9 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = 19970327; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.daysInWeek(arg); -assert.sameValue(result1, 7, "19970327 is a valid ISO string for calendar"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.daysInWeek(arg); -assert.sameValue(result2, 7, "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.daysInWeek(arg); +assert.sameValue(result, 7, "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -26,16 +22,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; assert.throws( RangeError, () => instance.daysInWeek(arg), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.daysInWeek(arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-wrong-type.js index a0179adc0391..c47752175396 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-wrong-type.js @@ -21,27 +21,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.daysInWeek(arg), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.daysInWeek(arg), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.daysInWeek(arg), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.daysInWeek(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.daysInWeek(arg), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-calendar-annotation.js index 00da31048af0..e0867649e51e 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-calendar-annotation.js @@ -15,7 +15,6 @@ const tests = [ ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const instance = new Temporal.Calendar("iso8601"); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..3b0bc93a041f --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.daysinweek +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.daysInWeek(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-case-insensitive.js index c2faf61258e0..401ba888a9e0 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-case-insensitive.js @@ -11,10 +11,6 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = "IsO8601"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.daysInYear(arg); -assert.sameValue(result1, 366, "Calendar is case-insensitive"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.daysInYear(arg); -assert.sameValue(result2, 366, "Calendar is case-insensitive (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.daysInYear(arg); +assert.sameValue(result, 366, "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 0fb3a77a0eb1..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,25 +0,0 @@ -// 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.daysinyear -description: > - A Temporal.Calendar instance passed to daysInYear() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.Calendar("iso8601"); - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -instance.daysInYear(arg); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -instance.daysInYear(arg); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-leap-second.js index 027cf9da2443..32595247a432 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-leap-second.js @@ -11,18 +11,10 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = "2016-12-31T23:59:60"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.daysInYear(arg); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.daysInYear(arg); assert.sameValue( - result1, + result, 366, "leap second is a valid ISO string for calendar" ); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.daysInYear(arg); -assert.sameValue( - result2, - 366, - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-number.js index de1bdcfccd4c..51148e0501ae 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-number.js @@ -11,13 +11,9 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = 19970327; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.daysInYear(arg); -assert.sameValue(result1, 366, "19970327 is a valid ISO string for calendar"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.daysInYear(arg); -assert.sameValue(result2, 366, "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.daysInYear(arg); +assert.sameValue(result, 366, "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -26,16 +22,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; assert.throws( RangeError, () => instance.daysInYear(arg), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.daysInYear(arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-wrong-type.js index 97283c0b3ffb..269a2b866a25 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-wrong-type.js @@ -21,27 +21,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.daysInYear(arg), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.daysInYear(arg), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.daysInYear(arg), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.daysInYear(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.daysInYear(arg), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-calendar-annotation.js index 20880a6f0650..b55d8408508f 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-calendar-annotation.js @@ -15,7 +15,6 @@ const tests = [ ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const instance = new Temporal.Calendar("iso8601"); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..fbfda521dfe4 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.daysinyear +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.daysInYear(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-case-insensitive.js index b0a6ad3f6c30..1214c1b8be97 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-case-insensitive.js @@ -11,10 +11,6 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = "IsO8601"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.inLeapYear(arg); -assert.sameValue(result1, true, "Calendar is case-insensitive"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.inLeapYear(arg); -assert.sameValue(result2, true, "Calendar is case-insensitive (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.inLeapYear(arg); +assert.sameValue(result, true, "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 676eb91e7063..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,25 +0,0 @@ -// 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.inleapyear -description: > - A Temporal.Calendar instance passed to inLeapYear() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.Calendar("iso8601"); - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -instance.inLeapYear(arg); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -instance.inLeapYear(arg); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-leap-second.js index a776948093e4..d7a4e62013be 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-leap-second.js @@ -11,18 +11,10 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = "2016-12-31T23:59:60"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.inLeapYear(arg); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.inLeapYear(arg); assert.sameValue( - result1, + result, true, "leap second is a valid ISO string for calendar" ); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.inLeapYear(arg); -assert.sameValue( - result2, - true, - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-number.js index f3ba12a322c0..22e411c99a1f 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-number.js @@ -11,13 +11,9 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = 19970327; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.inLeapYear(arg); -assert.sameValue(result1, true, "19970327 is a valid ISO string for calendar"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.inLeapYear(arg); -assert.sameValue(result2, true, "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.inLeapYear(arg); +assert.sameValue(result, true, "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -26,16 +22,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; assert.throws( RangeError, () => instance.inLeapYear(arg), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.inLeapYear(arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-wrong-type.js index 7993e2e1bfa1..10f3bd720e99 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-wrong-type.js @@ -21,27 +21,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.inLeapYear(arg), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.inLeapYear(arg), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.inLeapYear(arg), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.inLeapYear(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.inLeapYear(arg), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-calendar-annotation.js index e82961e7be43..357c21fa025c 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-calendar-annotation.js @@ -15,7 +15,6 @@ const tests = [ ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const instance = new Temporal.Calendar("iso8601"); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..5830790c2be6 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.inleapyear +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.inLeapYear(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/mergeFields/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/mergeFields/order-of-operations.js index b455b1f760ca..bcc750600ce9 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/mergeFields/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/mergeFields/order-of-operations.js @@ -21,8 +21,8 @@ const expected = [ "get fields.extra", // CopyDataProperties on additionalFields "ownKeys additionalFields", - "getOwnPropertyDescriptor additionalFields.3", - "get additionalFields.3", + "getOwnPropertyDescriptor additionalFields[3]", + "get additionalFields[3]", "getOwnPropertyDescriptor additionalFields.monthCode", "get additionalFields.monthCode", "getOwnPropertyDescriptor additionalFields[Symbol('extra')]", diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-case-insensitive.js index d45fc71c9e4b..491085743c11 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-case-insensitive.js @@ -11,10 +11,6 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = "IsO8601"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.month(arg); -assert.sameValue(result1, 11, "Calendar is case-insensitive"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.month(arg); -assert.sameValue(result2, 11, "Calendar is case-insensitive (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.month(arg); +assert.sameValue(result, 11, "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 962f839a0232..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,25 +0,0 @@ -// 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.month -description: > - A Temporal.Calendar instance passed to month() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.Calendar("iso8601"); - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -instance.month(arg); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -instance.month(arg); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-leap-second.js index 313b31f512fd..018fdf3210d9 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-leap-second.js @@ -11,18 +11,10 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = "2016-12-31T23:59:60"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.month(arg); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.month(arg); assert.sameValue( - result1, + result, 11, "leap second is a valid ISO string for calendar" ); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.month(arg); -assert.sameValue( - result2, - 11, - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-number.js index 1d8351bc8d33..fbb665756024 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-number.js @@ -11,13 +11,9 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = 19970327; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.month(arg); -assert.sameValue(result1, 11, "19970327 is a valid ISO string for calendar"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.month(arg); -assert.sameValue(result2, 11, "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.month(arg); +assert.sameValue(result, 11, "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -26,16 +22,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; assert.throws( RangeError, () => instance.month(arg), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.month(arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-wrong-type.js index 1d5ac9c40f12..fea4186a6bcd 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-wrong-type.js @@ -21,27 +21,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.month(arg), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.month(arg), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.month(arg), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.month(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.month(arg), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/month/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/month/argument-string-calendar-annotation.js index f7da6d3d504a..2bc9f9a47409 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/month/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/month/argument-string-calendar-annotation.js @@ -15,7 +15,6 @@ const tests = [ ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const instance = new Temporal.Calendar("iso8601"); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/month/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/month/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..43cf9d0e5ea1 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/month/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.month +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.month(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-case-insensitive.js index 2df095d8749f..2692a8bd3d95 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-case-insensitive.js @@ -11,10 +11,6 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = "IsO8601"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.monthCode(arg); -assert.sameValue(result1, "M11", "Calendar is case-insensitive"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.monthCode(arg); -assert.sameValue(result2, "M11", "Calendar is case-insensitive (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.monthCode(arg); +assert.sameValue(result, "M11", "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index f9c56b489ecc..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,25 +0,0 @@ -// 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.monthcode -description: > - A Temporal.Calendar instance passed to monthCode() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.Calendar("iso8601"); - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -instance.monthCode(arg); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -instance.monthCode(arg); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-leap-second.js index 7c8eb3e6cfb1..8f840d18297d 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-leap-second.js @@ -11,18 +11,10 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = "2016-12-31T23:59:60"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.monthCode(arg); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.monthCode(arg); assert.sameValue( - result1, + result, "M11", "leap second is a valid ISO string for calendar" ); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.monthCode(arg); -assert.sameValue( - result2, - "M11", - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-number.js index d7ac6bebdc88..2d44db82f795 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-number.js @@ -11,13 +11,9 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = 19970327; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.monthCode(arg); -assert.sameValue(result1, "M11", "19970327 is a valid ISO string for calendar"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.monthCode(arg); -assert.sameValue(result2, "M11", "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.monthCode(arg); +assert.sameValue(result, "M11", "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -26,16 +22,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; assert.throws( RangeError, () => instance.monthCode(arg), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.monthCode(arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-wrong-type.js index ffdeeb4269ff..9aeba9cb55fe 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-wrong-type.js @@ -21,27 +21,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.monthCode(arg), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.monthCode(arg), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.monthCode(arg), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.monthCode(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.monthCode(arg), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-calendar-annotation.js index 4505d52dbfc7..b98f969fb3cd 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-calendar-annotation.js @@ -15,7 +15,6 @@ const tests = [ ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const instance = new Temporal.Calendar("iso8601"); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..64b96901f0b5 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.monthcode +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.monthCode(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthDayFromFields/one-of-era-erayear-undefined.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthDayFromFields/one-of-era-erayear-undefined.js new file mode 100644 index 000000000000..4b7f40e22a07 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthDayFromFields/one-of-era-erayear-undefined.js @@ -0,0 +1,16 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.monthDayFromFields +description: Does not throw a RangeError if only one of era/eraYear fields is present +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const base = { year: 2000, month: 5, day: 2, era: 'ce' }; +const instance = new Temporal.Calendar('iso8601'); +TemporalHelpers.assertPlainMonthDay(instance.monthDayFromFields({ ...base }), 'M05', 2); + +const base2 = { year: 2000, month: 5, day: 2, eraYear: 1 }; +TemporalHelpers.assertPlainMonthDay(instance.monthDayFromFields({ ...base }), 'M05', 2); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthDayFromFields/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthDayFromFields/order-of-operations.js index 427f046130d9..cc61cedf609d 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthDayFromFields/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthDayFromFields/order-of-operations.js @@ -42,5 +42,5 @@ const options = TemporalHelpers.propertyBagObserver(actual, { const result = instance.monthDayFromFields(fields, options); TemporalHelpers.assertPlainMonthDay(result, "M01", 1, "monthDay result"); -assert.sameValue(result.calendar, instance, "calendar result"); +assert.sameValue(result.getISOFields().calendar, "iso8601", "calendar slot should store a string"); assert.compareArray(actual, expected, "order of operations"); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-case-insensitive.js index a4df5461ca0a..27a09872aae9 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-case-insensitive.js @@ -11,10 +11,6 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = "IsO8601"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.monthsInYear(arg); -assert.sameValue(result1, 12, "Calendar is case-insensitive"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.monthsInYear(arg); -assert.sameValue(result2, 12, "Calendar is case-insensitive (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.monthsInYear(arg); +assert.sameValue(result, 12, "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index f3e740762807..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,25 +0,0 @@ -// 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.monthsinyear -description: > - A Temporal.Calendar instance passed to monthsInYear() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.Calendar("iso8601"); - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -instance.monthsInYear(arg); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -instance.monthsInYear(arg); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-leap-second.js index 001b3cde215a..f03a83024a2d 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-leap-second.js @@ -11,18 +11,10 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = "2016-12-31T23:59:60"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.monthsInYear(arg); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.monthsInYear(arg); assert.sameValue( - result1, + result, 12, "leap second is a valid ISO string for calendar" ); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.monthsInYear(arg); -assert.sameValue( - result2, - 12, - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-number.js index b2ce9cd8d560..8790243fbe1b 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-number.js @@ -11,13 +11,9 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = 19970327; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.monthsInYear(arg); -assert.sameValue(result1, 12, "19970327 is a valid ISO string for calendar"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.monthsInYear(arg); -assert.sameValue(result2, 12, "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.monthsInYear(arg); +assert.sameValue(result, 12, "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -26,16 +22,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; assert.throws( RangeError, () => instance.monthsInYear(arg), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.monthsInYear(arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-wrong-type.js index 00d73115d29d..7e8647a1d66b 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-wrong-type.js @@ -21,27 +21,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.monthsInYear(arg), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.monthsInYear(arg), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.monthsInYear(arg), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.monthsInYear(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.monthsInYear(arg), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-calendar-annotation.js index ee88ab9824b9..c19e1d7a05be 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-calendar-annotation.js @@ -15,7 +15,6 @@ const tests = [ ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const instance = new Temporal.Calendar("iso8601"); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..9ec5f1eb753a --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.monthsinyear +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.monthsInYear(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/toJSON/returns-identifier-slot.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/toJSON/returns-identifier-slot.js new file mode 100644 index 000000000000..2bcca910d264 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/toJSON/returns-identifier-slot.js @@ -0,0 +1,23 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.tojson +description: toJSON() returns the internal slot value +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const actual = []; + +const calendar = new Temporal.Calendar("iso8601"); +TemporalHelpers.observeProperty(actual, calendar, Symbol.toPrimitive, undefined); +TemporalHelpers.observeProperty(actual, calendar, "id", "bogus"); +TemporalHelpers.observeProperty(actual, calendar, "toString", function () { + actual.push("call calendar.toString"); + return "gregory"; +}); + +const result = calendar.toJSON(); +assert.sameValue(result, "iso8601", "toJSON gets the internal slot value"); +assert.compareArray(actual, [], "should not invoke any observable operations"); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-case-insensitive.js index cab959c67085..7458eed38fa7 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-case-insensitive.js @@ -11,10 +11,6 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = "IsO8601"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.weekOfYear(arg); -assert.sameValue(result1, 47, "Calendar is case-insensitive"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.weekOfYear(arg); -assert.sameValue(result2, 47, "Calendar is case-insensitive (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.weekOfYear(arg); +assert.sameValue(result, 47, "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index db74808764c8..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,25 +0,0 @@ -// 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.weekofyear -description: > - A Temporal.Calendar instance passed to weekOfYear() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.Calendar("iso8601"); - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -instance.weekOfYear(arg); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -instance.weekOfYear(arg); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-leap-second.js index ba100b2b8c59..330cdb114a9f 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-leap-second.js @@ -11,18 +11,10 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = "2016-12-31T23:59:60"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.weekOfYear(arg); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.weekOfYear(arg); assert.sameValue( - result1, + result, 47, "leap second is a valid ISO string for calendar" ); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.weekOfYear(arg); -assert.sameValue( - result2, - 47, - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-number.js index cd5069188c72..73f81f7c8da8 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-number.js @@ -11,13 +11,9 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = 19970327; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.weekOfYear(arg); -assert.sameValue(result1, 47, "19970327 is a valid ISO string for calendar"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.weekOfYear(arg); -assert.sameValue(result2, 47, "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.weekOfYear(arg); +assert.sameValue(result, 47, "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -26,16 +22,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; assert.throws( RangeError, () => instance.weekOfYear(arg), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.weekOfYear(arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-wrong-type.js index 7dbc13193768..f3c8160d01ca 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-wrong-type.js @@ -21,27 +21,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.weekOfYear(arg), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.weekOfYear(arg), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.weekOfYear(arg), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.weekOfYear(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.weekOfYear(arg), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-calendar-annotation.js index 9bf2a295667a..d56595ab7212 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-calendar-annotation.js @@ -15,7 +15,6 @@ const tests = [ ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const instance = new Temporal.Calendar("iso8601"); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..f5261c6cbb22 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.weekofyear +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.weekOfYear(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-case-insensitive.js index c9499e0af05c..a5b6f52676af 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-case-insensitive.js @@ -11,10 +11,6 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = "IsO8601"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.year(arg); -assert.sameValue(result1, 1976, "Calendar is case-insensitive"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.year(arg); -assert.sameValue(result2, 1976, "Calendar is case-insensitive (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.year(arg); +assert.sameValue(result, 1976, "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 7e6f585cf987..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,25 +0,0 @@ -// 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.year -description: > - A Temporal.Calendar instance passed to year() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.Calendar("iso8601"); - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -instance.year(arg); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -instance.year(arg); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-leap-second.js index d821211c537d..8f8d5ef5861d 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-leap-second.js @@ -11,18 +11,10 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = "2016-12-31T23:59:60"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.year(arg); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.year(arg); assert.sameValue( - result1, + result, 1976, "leap second is a valid ISO string for calendar" ); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.year(arg); -assert.sameValue( - result2, - 1976, - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-number.js index 3030c5ed268c..bc475da624d7 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-number.js @@ -11,13 +11,9 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = 19970327; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.year(arg); -assert.sameValue(result1, 1976, "19970327 is a valid ISO string for calendar"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.year(arg); -assert.sameValue(result2, 1976, "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.year(arg); +assert.sameValue(result, 1976, "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -26,16 +22,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; assert.throws( RangeError, () => instance.year(arg), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.year(arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-wrong-type.js index b3cec2bd4da3..a06cd4c751e4 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-wrong-type.js @@ -21,27 +21,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.year(arg), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.year(arg), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.year(arg), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.year(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.year(arg), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/year/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/year/argument-string-calendar-annotation.js index 7132ec6e10ea..422ec49498f3 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/year/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/year/argument-string-calendar-annotation.js @@ -15,7 +15,6 @@ const tests = [ ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const instance = new Temporal.Calendar("iso8601"); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/year/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/year/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..da117a163edd --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/year/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.year +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.year(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/one-of-era-erayear-undefined.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/one-of-era-erayear-undefined.js new file mode 100644 index 000000000000..9cb06acd19cb --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/one-of-era-erayear-undefined.js @@ -0,0 +1,16 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.yearMonthFromFields +description: Does not throw a RangeError if only one of era/eraYear fields is present +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const base = { year: 2000, month: 5, day: 2, era: 'ce' }; +const instance = new Temporal.Calendar('iso8601'); +TemporalHelpers.assertPlainYearMonth(instance.yearMonthFromFields({ ...base }), 2000, 5, 'M05'); + +const base2 = { year: 2000, month: 5, day: 2, eraYear: 1 }; +TemporalHelpers.assertPlainYearMonth(instance.yearMonthFromFields({ ...base }), 2000, 5, 'M05'); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/order-of-operations.js index cd10b2797d57..49a214955184 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/order-of-operations.js @@ -38,5 +38,5 @@ const options = TemporalHelpers.propertyBagObserver(actual, { const result = instance.yearMonthFromFields(fields, options); TemporalHelpers.assertPlainYearMonth(result, 1, 1, "M01", "yearMonth result"); -assert.sameValue(result.calendar, instance, "calendar result"); +assert.sameValue(result.getISOFields().calendar, "iso8601", "calendar slot should store a string"); assert.compareArray(actual, expected, "order of operations"); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-case-insensitive.js index c3c513e500ad..1cd2b10757fb 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-case-insensitive.js @@ -11,10 +11,6 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = "IsO8601"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.yearOfWeek(arg); -assert.sameValue(result1, 1976, "Calendar is case-insensitive"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.yearOfWeek(arg); -assert.sameValue(result2, 1976, "Calendar is case-insensitive (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.yearOfWeek(arg); +assert.sameValue(result, 1976, "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 24d661a6ba7c..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,25 +0,0 @@ -// 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.yearofweek -description: > - A Temporal.Calendar instance passed to yearOfWeek() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.Calendar("iso8601"); - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -instance.yearOfWeek(arg); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -instance.yearOfWeek(arg); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-leap-second.js index 50d93686ee97..5a2044e8f9b8 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-leap-second.js @@ -11,18 +11,10 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = "2016-12-31T23:59:60"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.yearOfWeek(arg); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.yearOfWeek(arg); assert.sameValue( - result1, + result, 1976, "leap second is a valid ISO string for calendar" ); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.yearOfWeek(arg); -assert.sameValue( - result2, - 1976, - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-number.js index f15d75d4c85c..885f48f1202c 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-number.js @@ -11,13 +11,9 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = 19970327; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.yearOfWeek(arg); -assert.sameValue(result1, 1976, "19970327 is a valid ISO string for calendar"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.yearOfWeek(arg); -assert.sameValue(result2, 1976, "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.yearOfWeek(arg); +assert.sameValue(result, 1976, "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -26,16 +22,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; assert.throws( RangeError, () => instance.yearOfWeek(arg), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.yearOfWeek(arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-wrong-type.js index e7094a99d78b..9c8e0c113fcd 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-wrong-type.js @@ -21,27 +21,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.yearOfWeek(arg), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.yearOfWeek(arg), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.yearOfWeek(arg), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.yearOfWeek(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.yearOfWeek(arg), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-calendar-annotation.js index cefe90e1f5ea..ec3483784304 100644 --- a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-calendar-annotation.js @@ -15,7 +15,6 @@ const tests = [ ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const instance = new Temporal.Calendar("iso8601"); diff --git a/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..364a43c6d0ac --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.yearofweek +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.yearOfWeek(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/compare/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/Duration/compare/order-of-operations.js index 7b1e9a9c6471..3e500f63ddef 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/compare/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/compare/order-of-operations.js @@ -88,7 +88,27 @@ actual.splice(0); // clear const expectedOpsForPlainRelativeTo = expected.concat([ // ToRelativeTemporalObject "get options.relativeTo.calendar", - "has options.relativeTo.calendar.calendar", + "has options.relativeTo.calendar.dateAdd", + "has options.relativeTo.calendar.dateFromFields", + "has options.relativeTo.calendar.dateUntil", + "has options.relativeTo.calendar.day", + "has options.relativeTo.calendar.dayOfWeek", + "has options.relativeTo.calendar.dayOfYear", + "has options.relativeTo.calendar.daysInMonth", + "has options.relativeTo.calendar.daysInWeek", + "has options.relativeTo.calendar.daysInYear", + "has options.relativeTo.calendar.fields", + "has options.relativeTo.calendar.id", + "has options.relativeTo.calendar.inLeapYear", + "has options.relativeTo.calendar.mergeFields", + "has options.relativeTo.calendar.month", + "has options.relativeTo.calendar.monthCode", + "has options.relativeTo.calendar.monthDayFromFields", + "has options.relativeTo.calendar.monthsInYear", + "has options.relativeTo.calendar.weekOfYear", + "has options.relativeTo.calendar.year", + "has options.relativeTo.calendar.yearMonthFromFields", + "has options.relativeTo.calendar.yearOfWeek", "get options.relativeTo.calendar.fields", "call options.relativeTo.calendar.fields", "get options.relativeTo.day", @@ -151,10 +171,54 @@ Temporal.Duration.compare( assert.compareArray(actual, expectedOpsForPlainRelativeTo, "order of operations with PlainDate relativeTo and no calendar units"); actual.splice(0); // clear +// code path through UnbalanceDurationRelative that balances higher units down +// to days: +const expectedOpsForPlainDayBalancing = expectedOpsForPlainRelativeTo.concat( + [ + // UnbalanceDurationRelative + "get options.relativeTo.calendar.dateAdd", // 11.a.ii + "call options.relativeTo.calendar.dateAdd", // 11.a.iii.1 MoveRelativeDate + "call options.relativeTo.calendar.dateAdd", // 11.a.iv.1 MoveRelativeDate + "call options.relativeTo.calendar.dateAdd", // 11.a.v.1 MoveRelativeDate + // UnbalanceDurationRelative again for the second argument: + "get options.relativeTo.calendar.dateAdd", // 11.a.ii + "call options.relativeTo.calendar.dateAdd", // 11.a.iii.1 MoveRelativeDate + "call options.relativeTo.calendar.dateAdd", // 11.a.iv.1 MoveRelativeDate + "call options.relativeTo.calendar.dateAdd", // 11.a.v.1 MoveRelativeDate + ] +); +Temporal.Duration.compare( + createDurationPropertyBagObserver("one", 1, 1, 1), + createDurationPropertyBagObserver("two", 1, 1, 1, 1), + createOptionsObserver(plainRelativeTo) +); +assert.compareArray(actual, expectedOpsForPlainDayBalancing, "order of operations with PlainDate relativeTo and calendar units"); +actual.splice(0); // clear + const expectedOpsForZonedRelativeTo = expected.concat([ // ToRelativeTemporalObject "get options.relativeTo.calendar", - "has options.relativeTo.calendar.calendar", + "has options.relativeTo.calendar.dateAdd", + "has options.relativeTo.calendar.dateFromFields", + "has options.relativeTo.calendar.dateUntil", + "has options.relativeTo.calendar.day", + "has options.relativeTo.calendar.dayOfWeek", + "has options.relativeTo.calendar.dayOfYear", + "has options.relativeTo.calendar.daysInMonth", + "has options.relativeTo.calendar.daysInWeek", + "has options.relativeTo.calendar.daysInYear", + "has options.relativeTo.calendar.fields", + "has options.relativeTo.calendar.id", + "has options.relativeTo.calendar.inLeapYear", + "has options.relativeTo.calendar.mergeFields", + "has options.relativeTo.calendar.month", + "has options.relativeTo.calendar.monthCode", + "has options.relativeTo.calendar.monthDayFromFields", + "has options.relativeTo.calendar.monthsInYear", + "has options.relativeTo.calendar.weekOfYear", + "has options.relativeTo.calendar.year", + "has options.relativeTo.calendar.yearMonthFromFields", + "has options.relativeTo.calendar.yearOfWeek", "get options.relativeTo.calendar.fields", "call options.relativeTo.calendar.fields", "get options.relativeTo.day", @@ -193,11 +257,16 @@ const expectedOpsForZonedRelativeTo = expected.concat([ "call options.relativeTo.year.valueOf", "get options.relativeTo.calendar.dateFromFields", "call options.relativeTo.calendar.dateFromFields", - "has options.relativeTo.timeZone.timeZone", + "has options.relativeTo.timeZone.getOffsetNanosecondsFor", + "has options.relativeTo.timeZone.getPossibleInstantsFor", + "has options.relativeTo.timeZone.id", "get options.relativeTo.timeZone.getPossibleInstantsFor", "call options.relativeTo.timeZone.getPossibleInstantsFor", "get options.relativeTo.timeZone.getOffsetNanosecondsFor", "call options.relativeTo.timeZone.getOffsetNanosecondsFor", +]); + +const expectedOpsForCalculateOffsetShift = [ // CalculateOffsetShift on first argument "get options.relativeTo.timeZone.getOffsetNanosecondsFor", "call options.relativeTo.timeZone.getOffsetNanosecondsFor", @@ -222,7 +291,7 @@ const expectedOpsForZonedRelativeTo = expected.concat([ "call options.relativeTo.timeZone.getPossibleInstantsFor", "get options.relativeTo.timeZone.getOffsetNanosecondsFor", "call options.relativeTo.timeZone.getOffsetNanosecondsFor", -]); +]; const zonedRelativeTo = TemporalHelpers.propertyBagObserver(actual, { year: 2001, @@ -240,33 +309,66 @@ const zonedRelativeTo = TemporalHelpers.propertyBagObserver(actual, { timeZone: TemporalHelpers.timeZoneObserver(actual, "options.relativeTo.timeZone"), }, "options.relativeTo"); -// order of observable operations with zoned relativeTo and without calendar units +// order of observable operations with zoned relativeTo and without calendar units except days Temporal.Duration.compare( createDurationPropertyBagObserver("one", 0, 0, 0, 7), createDurationPropertyBagObserver("two", 0, 0, 0, 6), createOptionsObserver(zonedRelativeTo) ); -assert.compareArray(actual, expectedOpsForZonedRelativeTo, "order of operations with ZonedDateTime relativeTo and no calendar units"); +assert.compareArray( + actual, + expectedOpsForZonedRelativeTo.concat(expectedOpsForCalculateOffsetShift), + "order of operations with ZonedDateTime relativeTo and no calendar units except days" +); +actual.splice(0); // clear + +// order of observable operations with zoned relativeTo and with only time units +Temporal.Duration.compare( + createDurationPropertyBagObserver("one", 0, 0, 0, 0, 7), + createDurationPropertyBagObserver("two", 0, 0, 0, 0, 6), + createOptionsObserver(zonedRelativeTo) +); +assert.compareArray( + actual, + expectedOpsForZonedRelativeTo.concat([ + // CalculateOffsetShift on first arg + "get options.relativeTo.timeZone.getOffsetNanosecondsFor", + "call options.relativeTo.timeZone.getOffsetNanosecondsFor", + // AddZonedDateTime + "get options.relativeTo.timeZone.getOffsetNanosecondsFor", + "call options.relativeTo.timeZone.getOffsetNanosecondsFor", + // CalculateOffsetShift on second arg + "get options.relativeTo.timeZone.getOffsetNanosecondsFor", + "call options.relativeTo.timeZone.getOffsetNanosecondsFor", + // AddZonedDateTime + "get options.relativeTo.timeZone.getOffsetNanosecondsFor", + "call options.relativeTo.timeZone.getOffsetNanosecondsFor", + ]), + "order of operations with ZonedDateTime relativeTo and only time units" +); actual.splice(0); // clear // code path through UnbalanceDurationRelative that balances higher units down // to days: -const expectedOpsForDayBalancing = expectedOpsForZonedRelativeTo.concat([ - // UnbalanceDurationRelative - "get options.relativeTo.timeZone.getOffsetNanosecondsFor", // 7.a ToTemporalDate - "call options.relativeTo.timeZone.getOffsetNanosecondsFor", - "get options.relativeTo.calendar.dateAdd", // 11.a.ii - "call options.relativeTo.calendar.dateAdd", // 11.a.iii.1 MoveRelativeDate - "call options.relativeTo.calendar.dateAdd", // 11.a.iv.1 MoveRelativeDate - "call options.relativeTo.calendar.dateAdd", // 11.a.v.1 MoveRelativeDate - // UnbalanceDurationRelative again for the second argument: - "get options.relativeTo.timeZone.getOffsetNanosecondsFor", // 7.a ToTemporalDate - "call options.relativeTo.timeZone.getOffsetNanosecondsFor", - "get options.relativeTo.calendar.dateAdd", // 11.a.ii - "call options.relativeTo.calendar.dateAdd", // 11.a.iii.1 MoveRelativeDate - "call options.relativeTo.calendar.dateAdd", // 11.a.iv.1 MoveRelativeDate - "call options.relativeTo.calendar.dateAdd", // 11.a.v.1 MoveRelativeDate -]); +const expectedOpsForDayBalancing = expectedOpsForZonedRelativeTo.concat( + expectedOpsForCalculateOffsetShift, + [ + // UnbalanceDurationRelative + "get options.relativeTo.timeZone.getOffsetNanosecondsFor", // 7.a ToTemporalDate + "call options.relativeTo.timeZone.getOffsetNanosecondsFor", + "get options.relativeTo.calendar.dateAdd", // 11.a.ii + "call options.relativeTo.calendar.dateAdd", // 11.a.iii.1 MoveRelativeDate + "call options.relativeTo.calendar.dateAdd", // 11.a.iv.1 MoveRelativeDate + "call options.relativeTo.calendar.dateAdd", // 11.a.v.1 MoveRelativeDate + // UnbalanceDurationRelative again for the second argument: + "get options.relativeTo.timeZone.getOffsetNanosecondsFor", // 7.a ToTemporalDate + "call options.relativeTo.timeZone.getOffsetNanosecondsFor", + "get options.relativeTo.calendar.dateAdd", // 11.a.ii + "call options.relativeTo.calendar.dateAdd", // 11.a.iii.1 MoveRelativeDate + "call options.relativeTo.calendar.dateAdd", // 11.a.iv.1 MoveRelativeDate + "call options.relativeTo.calendar.dateAdd", // 11.a.v.1 MoveRelativeDate + ] +); Temporal.Duration.compare( createDurationPropertyBagObserver("one", 1, 1, 1), createDurationPropertyBagObserver("two", 1, 1, 1, 1), diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/compare/relativeto-propertybag-calendar-string.js b/JSTests/test262/test/built-ins/Temporal/Duration/compare/relativeto-propertybag-calendar-string.js new file mode 100644 index 000000000000..a5d0e671fd7d --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Duration/compare/relativeto-propertybag-calendar-string.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.compare +description: > + Builtin dateFromFields method is not observably called when the property bag + has a string-valued calendar property +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const dateFromFieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dateFromFields"); +Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("dateFromFields should not be looked up"); + }, +}); + +const relativeTo = { year: 2000, month: 5, day: 2, calendar: "iso8601" }; +Temporal.Duration.compare(new Temporal.Duration(), new Temporal.Duration(), { relativeTo }); + +Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", dateFromFieldsOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/compare/relativeto-propertybag-timezone-instance-does-not-get-timeZone-property.js b/JSTests/test262/test/built-ins/Temporal/Duration/compare/relativeto-propertybag-timezone-instance-does-not-get-timeZone-property.js deleted file mode 100644 index 62086da857ce..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Duration/compare/relativeto-propertybag-timezone-instance-does-not-get-timeZone-property.js +++ /dev/null @@ -1,20 +0,0 @@ -// 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.compare -description: > - A Temporal.TimeZone instance passed to compare() does not have its - 'timeZone' property observably checked -features: [Temporal] ----*/ - -const timeZone = new Temporal.TimeZone("UTC"); -Object.defineProperty(timeZone, "timeZone", { - get() { - throw new Test262Error("timeZone.timeZone should not be accessed"); - }, -}); - -Temporal.Duration.compare(new Temporal.Duration(), new Temporal.Duration(), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }); -Temporal.Duration.compare(new Temporal.Duration(), new Temporal.Duration(), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/compare/relativeto-propertybag-timezone-string-datetime.js b/JSTests/test262/test/built-ins/Temporal/Duration/compare/relativeto-propertybag-timezone-string-datetime.js index f475a24bbfd9..42267cf280f7 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/compare/relativeto-propertybag-timezone-string-datetime.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/compare/relativeto-propertybag-timezone-string-datetime.js @@ -9,7 +9,6 @@ features: [Temporal] let timeZone = "2021-08-19T17:30"; assert.throws(RangeError, () => Temporal.Duration.compare(new Temporal.Duration(), new Temporal.Duration(), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), "bare date-time string is not a time zone"); -assert.throws(RangeError, () => Temporal.Duration.compare(new Temporal.Duration(), new Temporal.Duration(), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), "bare date-time string is not a time zone"); // The following are all valid strings so should not throw: @@ -30,5 +29,4 @@ assert.throws(RangeError, () => Temporal.Duration.compare(new Temporal.Duration( "2021-08-19T1730-0700[UTC]", ].forEach((timeZone) => { Temporal.Duration.compare(new Temporal.Duration(), new Temporal.Duration(), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }); - Temporal.Duration.compare(new Temporal.Duration(), new Temporal.Duration(), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }); }); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/compare/relativeto-propertybag-timezone-string-leap-second.js b/JSTests/test262/test/built-ins/Temporal/Duration/compare/relativeto-propertybag-timezone-string-leap-second.js index 02368982a38c..4ba0cfc3eba4 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/compare/relativeto-propertybag-timezone-string-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/compare/relativeto-propertybag-timezone-string-leap-second.js @@ -9,12 +9,10 @@ features: [Temporal] let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; -// A string with a leap second is a valid ISO string, so the following two -// operations should not throw +// A string with a leap second is a valid ISO string, so the following +// operation should not throw Temporal.Duration.compare(new Temporal.Duration(), new Temporal.Duration(), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }); -Temporal.Duration.compare(new Temporal.Duration(), new Temporal.Duration(), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }); timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; assert.throws(RangeError, () => Temporal.Duration.compare(new Temporal.Duration(), new Temporal.Duration(), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), "leap second in time zone name not valid"); -assert.throws(RangeError, () => Temporal.Duration.compare(new Temporal.Duration(), new Temporal.Duration(), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), "leap second in time zone name not valid (nested property)"); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/compare/relativeto-propertybag-timezone-string-year-zero.js b/JSTests/test262/test/built-ins/Temporal/Duration/compare/relativeto-propertybag-timezone-string-year-zero.js index 0c8d50f0e26e..8ea4b40556a3 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/compare/relativeto-propertybag-timezone-string-year-zero.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/compare/relativeto-propertybag-timezone-string-year-zero.js @@ -17,9 +17,4 @@ invalidStrings.forEach((timeZone) => { () => Temporal.Duration.compare(new Temporal.Duration(), new Temporal.Duration(), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), "reject minus zero as extended year" ); - assert.throws( - RangeError, - () => Temporal.Duration.compare(new Temporal.Duration(), new Temporal.Duration(), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), - "reject minus zero as extended year (nested property)" - ); }); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/compare/relativeto-propertybag-timezone-string.js b/JSTests/test262/test/built-ins/Temporal/Duration/compare/relativeto-propertybag-timezone-string.js index fe1aa0c8a37d..40036b94a296 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/compare/relativeto-propertybag-timezone-string.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/compare/relativeto-propertybag-timezone-string.js @@ -4,11 +4,32 @@ /*--- esid: sec-temporal.duration.compare description: Time zone IDs are valid input for a time zone +includes: [temporalHelpers.js] features: [Temporal] ---*/ +const getPossibleInstantsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getPossibleInstantsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getPossibleInstantsFor should not be looked up"); + }, +}); +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + // The following are all valid strings so should not throw: ["UTC", "+01:00"].forEach((timeZone) => { Temporal.Duration.compare(new Temporal.Duration(), new Temporal.Duration(), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }); }); + +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", getPossibleInstantsForOriginal); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/compare/relativeto-propertybag-timezone-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/Duration/compare/relativeto-propertybag-timezone-wrong-type.js index cd328593c340..b37aa4e60a6f 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/compare/relativeto-propertybag-timezone-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/compare/relativeto-propertybag-timezone-wrong-type.js @@ -16,22 +16,18 @@ const rangeErrorTests = [ [1, "number that doesn't convert to a valid ISO string"], [19761118, "number that would convert to a valid ISO string in other contexts"], [1n, "bigint"], - [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of rangeErrorTests) { assert.throws(RangeError, () => Temporal.Duration.compare(new Temporal.Duration(), new Temporal.Duration(), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), `${description} does not convert to a valid ISO string`); - assert.throws(RangeError, () => Temporal.Duration.compare(new Temporal.Duration(), new Temporal.Duration(), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], + [{}, "object not implementing time zone protocol"], + [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of typeErrorTests) { assert.throws(TypeError, () => Temporal.Duration.compare(new Temporal.Duration(), new Temporal.Duration(), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), `${description} is not a valid object and does not convert to a string`); - assert.throws(TypeError, () => Temporal.Duration.compare(new Temporal.Duration(), new Temporal.Duration(), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), `${description} is not a valid object and does not convert to a string (nested property)`); } - -const timeZone = undefined; -assert.throws(RangeError, () => Temporal.Duration.compare(new Temporal.Duration(), new Temporal.Duration(), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), `undefined is always a RangeError as nested property`); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/add/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/add/order-of-operations.js index bf182ee75365..691357750e7c 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/add/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/add/order-of-operations.js @@ -71,7 +71,27 @@ actual.splice(0); // clear const expectedOpsForPlainRelativeTo = expected.concat([ // ToRelativeTemporalObject "get options.relativeTo.calendar", - "has options.relativeTo.calendar.calendar", + "has options.relativeTo.calendar.dateAdd", + "has options.relativeTo.calendar.dateFromFields", + "has options.relativeTo.calendar.dateUntil", + "has options.relativeTo.calendar.day", + "has options.relativeTo.calendar.dayOfWeek", + "has options.relativeTo.calendar.dayOfYear", + "has options.relativeTo.calendar.daysInMonth", + "has options.relativeTo.calendar.daysInWeek", + "has options.relativeTo.calendar.daysInYear", + "has options.relativeTo.calendar.fields", + "has options.relativeTo.calendar.id", + "has options.relativeTo.calendar.inLeapYear", + "has options.relativeTo.calendar.mergeFields", + "has options.relativeTo.calendar.month", + "has options.relativeTo.calendar.monthCode", + "has options.relativeTo.calendar.monthDayFromFields", + "has options.relativeTo.calendar.monthsInYear", + "has options.relativeTo.calendar.weekOfYear", + "has options.relativeTo.calendar.year", + "has options.relativeTo.calendar.yearMonthFromFields", + "has options.relativeTo.calendar.yearOfWeek", "get options.relativeTo.calendar.fields", "call options.relativeTo.calendar.fields", // PrepareTemporalFields @@ -136,7 +156,27 @@ actual.splice(0); // clear const expectedOpsForZonedRelativeTo = expected.concat([ // ToRelativeTemporalObject "get options.relativeTo.calendar", - "has options.relativeTo.calendar.calendar", + "has options.relativeTo.calendar.dateAdd", + "has options.relativeTo.calendar.dateFromFields", + "has options.relativeTo.calendar.dateUntil", + "has options.relativeTo.calendar.day", + "has options.relativeTo.calendar.dayOfWeek", + "has options.relativeTo.calendar.dayOfYear", + "has options.relativeTo.calendar.daysInMonth", + "has options.relativeTo.calendar.daysInWeek", + "has options.relativeTo.calendar.daysInYear", + "has options.relativeTo.calendar.fields", + "has options.relativeTo.calendar.id", + "has options.relativeTo.calendar.inLeapYear", + "has options.relativeTo.calendar.mergeFields", + "has options.relativeTo.calendar.month", + "has options.relativeTo.calendar.monthCode", + "has options.relativeTo.calendar.monthDayFromFields", + "has options.relativeTo.calendar.monthsInYear", + "has options.relativeTo.calendar.weekOfYear", + "has options.relativeTo.calendar.year", + "has options.relativeTo.calendar.yearMonthFromFields", + "has options.relativeTo.calendar.yearOfWeek", "get options.relativeTo.calendar.fields", "call options.relativeTo.calendar.fields", // PrepareTemporalFields @@ -178,7 +218,9 @@ const expectedOpsForZonedRelativeTo = expected.concat([ "get options.relativeTo.calendar.dateFromFields", "call options.relativeTo.calendar.dateFromFields", // ToRelativeTemporalObject again - "has options.relativeTo.timeZone.timeZone", + "has options.relativeTo.timeZone.getOffsetNanosecondsFor", + "has options.relativeTo.timeZone.getPossibleInstantsFor", + "has options.relativeTo.timeZone.id", // InterpretISODateTimeOffset "get options.relativeTo.timeZone.getPossibleInstantsFor", "call options.relativeTo.timeZone.getPossibleInstantsFor", diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-calendar-number.js index b2ff180cb587..73641f977d2b 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-calendar-number.js @@ -12,13 +12,9 @@ const instance = new Temporal.Duration(1, 0, 0, 1); const calendar = 19970327; -let relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; -const result1 = instance.add(new Temporal.Duration(0, 0, 0, 0, -24), { relativeTo }); -TemporalHelpers.assertDuration(result1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for relativeTo.calendar"); - -relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; -const result2 = instance.add(new Temporal.Duration(0, 0, 0, 0, -24), { relativeTo }); -TemporalHelpers.assertDuration(result2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for relativeTo.calendar (nested property)"); +const relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; +const result = instance.add(new Temporal.Duration(0, 0, 0, 0, -24), { relativeTo }); +TemporalHelpers.assertDuration(result, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for relativeTo.calendar"); const numbers = [ 1, @@ -27,16 +23,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; + const relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws( RangeError, () => instance.add(new Temporal.Duration(0, 0, 0, 0, -24), { relativeTo }), `Number ${calendar} does not convert to a valid ISO string for relativeTo.calendar` ); - relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.add(new Temporal.Duration(0, 0, 0, 0, -24), { relativeTo }), - `Number ${calendar} does not convert to a valid ISO string for relativeTo.calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-calendar-string.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-calendar-string.js new file mode 100644 index 000000000000..78af80446589 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-calendar-string.js @@ -0,0 +1,26 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.add +description: > + Builtin dateFromFields method is not observably called when the property bag + has a string-valued calendar property +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const dateFromFieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dateFromFields"); +Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("dateFromFields should not be looked up"); + }, +}); + +const instance = new Temporal.Duration(1, 0, 0, 1); +const relativeTo = { year: 2000, month: 5, day: 2, calendar: "iso8601" }; +instance.add(new Temporal.Duration(0, 0, 0, 0, -24), { relativeTo }); + +Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", dateFromFieldsOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-calendar-wrong-type.js index 733eee13df4d..91cc575b54c6 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-calendar-wrong-type.js @@ -18,20 +18,17 @@ const rangeErrorTests = [ ["", "empty string"], [1, "number that doesn't convert to a valid ISO string"], [1n, "bigint"], - [new Temporal.TimeZone("UTC"), "time zone instance"], ]; for (const [calendar, description] of rangeErrorTests) { - let relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; + const relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.add(new Temporal.Duration(0, 0, 0, 0, -24), { relativeTo }), `${description} does not convert to a valid ISO string`); - - relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.add(new Temporal.Duration(0, 0, 0, 0, -24), { relativeTo }), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], [Temporal.PlainDate, "Temporal.PlainDate, object"], [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], [Temporal.ZonedDateTime, "Temporal.ZonedDateTime, object"], @@ -39,12 +36,6 @@ const typeErrorTests = [ ]; for (const [calendar, description] of typeErrorTests) { - let relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; + const relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.add(new Temporal.Duration(0, 0, 0, 0, -24), { relativeTo }), `${description} is not a valid property bag and does not convert to a string`); - - relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.add(new Temporal.Duration(0, 0, 0, 0, -24), { relativeTo }), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.add(new Temporal.Duration(0, 0, 0, 0, -24), { relativeTo }), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-timezone-instance-does-not-get-timeZone-property.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-timezone-instance-does-not-get-timeZone-property.js deleted file mode 100644 index 643acc257209..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-timezone-instance-does-not-get-timeZone-property.js +++ /dev/null @@ -1,22 +0,0 @@ -// 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.add -description: > - A Temporal.TimeZone instance passed to add() does not have its - 'timeZone' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.Duration(1); - -const timeZone = new Temporal.TimeZone("UTC"); -Object.defineProperty(timeZone, "timeZone", { - get() { - throw new Test262Error("timeZone.timeZone should not be accessed"); - }, -}); - -instance.add(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }); -instance.add(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-timezone-string-datetime.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-timezone-string-datetime.js index 5f4c3968be1d..60a6cf198371 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-timezone-string-datetime.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-timezone-string-datetime.js @@ -11,7 +11,6 @@ const instance = new Temporal.Duration(1); let timeZone = "2021-08-19T17:30"; assert.throws(RangeError, () => instance.add(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), "bare date-time string is not a time zone"); -assert.throws(RangeError, () => instance.add(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), "bare date-time string is not a time zone"); // The following are all valid strings so should not throw: @@ -32,5 +31,4 @@ assert.throws(RangeError, () => instance.add(new Temporal.Duration(1), { relativ "2021-08-19T1730-0700[UTC]", ].forEach((timeZone) => { instance.add(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }); - instance.add(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }); }); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-timezone-string-leap-second.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-timezone-string-leap-second.js index a08b0dc14f2a..4571c15e21b8 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-timezone-string-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-timezone-string-leap-second.js @@ -10,12 +10,10 @@ features: [Temporal] const instance = new Temporal.Duration(1); let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; -// A string with a leap second is a valid ISO string, so the following two -// operations should not throw +// A string with a leap second is a valid ISO string, so the following +// operation should not throw instance.add(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }); -instance.add(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }); timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; assert.throws(RangeError, () => instance.add(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), "leap second in time zone name not valid"); -assert.throws(RangeError, () => instance.add(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), "leap second in time zone name not valid (nested property)"); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-timezone-string-year-zero.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-timezone-string-year-zero.js index 2f09d730ba69..75f689c30548 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-timezone-string-year-zero.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-timezone-string-year-zero.js @@ -18,9 +18,4 @@ invalidStrings.forEach((timeZone) => { () => instance.add(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), "reject minus zero as extended year" ); - assert.throws( - RangeError, - () => instance.add(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), - "reject minus zero as extended year (nested property)" - ); }); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-timezone-string.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-timezone-string.js index 44448beab8b9..3b32cf8b2450 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-timezone-string.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-timezone-string.js @@ -4,9 +4,27 @@ /*--- esid: sec-temporal.duration.prototype.add description: Time zone IDs are valid input for a time zone +includes: [temporalHelpers.js] features: [Temporal] ---*/ +const getPossibleInstantsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getPossibleInstantsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getPossibleInstantsFor should not be looked up"); + }, +}); +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + const instance = new Temporal.Duration(1); // The following are all valid strings so should not throw: @@ -14,3 +32,6 @@ const instance = new Temporal.Duration(1); ["UTC", "+01:00"].forEach((timeZone) => { instance.add(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }); }); + +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", getPossibleInstantsForOriginal); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-timezone-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-timezone-wrong-type.js index 8eafc80af2f1..3b33c578509d 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-timezone-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-timezone-wrong-type.js @@ -18,22 +18,18 @@ const rangeErrorTests = [ [1, "number that doesn't convert to a valid ISO string"], [19761118, "number that would convert to a valid ISO string in other contexts"], [1n, "bigint"], - [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of rangeErrorTests) { assert.throws(RangeError, () => instance.add(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), `${description} does not convert to a valid ISO string`); - assert.throws(RangeError, () => instance.add(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], + [{}, "object not implementing time zone protocol"], + [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of typeErrorTests) { assert.throws(TypeError, () => instance.add(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), `${description} is not a valid object and does not convert to a string`); - assert.throws(TypeError, () => instance.add(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), `${description} is not a valid object and does not convert to a string (nested property)`); } - -const timeZone = undefined; -assert.throws(RangeError, () => instance.add(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), `undefined is always a RangeError as nested property`); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/calendar-dateadd-called-with-options-undefined.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/calendar-dateadd-called-with-options-undefined.js index 2c81eabfa02a..28494a40c2f8 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/calendar-dateadd-called-with-options-undefined.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/calendar-dateadd-called-with-options-undefined.js @@ -20,17 +20,16 @@ const relativeTo = new Temporal.ZonedDateTime(0n, timeZone, calendar); // RoundDuration -> // MoveRelativeZonedDateTime -> AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() // NanosecondsToDays -> AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() -// BalanceDurationRelative -> -// MoveRelativeDate -> calendar.dateAdd() (2x) -// calendar.dateAdd() -// MoveRelativeZonedDateTime -> AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() // BalanceDuration -> // AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() // NanosecondsToDays -> AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() (2x) +// BalanceDurationRelative -> +// MoveRelativeDate -> calendar.dateAdd() (2x) +// calendar.dateAdd() const instance1 = new Temporal.Duration(1, 1, 1, 1, 1); instance1.round({ smallestUnit: "days", relativeTo }); -assert.sameValue(calendar.dateAddCallCount, 9, "rounding with calendar smallestUnit"); +assert.sameValue(calendar.dateAddCallCount, 8, "rounding with calendar smallestUnit"); // Rounding with a non-default largestUnit to cover the path in // UnbalanceDurationRelative where larger units are converted into smaller @@ -40,7 +39,6 @@ assert.sameValue(calendar.dateAddCallCount, 9, "rounding with calendar smallestU // Duration.round() -> // UnbalanceDurationRelative -> MoveRelativeDate -> calendar.dateAdd() // RoundDuration -> -// MoveRelativeZonedDateTime -> AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() // MoveRelativeDate -> calendar.dateAdd() (5x) // BalanceDurationRelative // MoveRelativeDate -> calendar.dateAdd() @@ -50,7 +48,7 @@ calendar.dateAddCallCount = 0; const instance2 = new Temporal.Duration(0, 1, 1, 1); instance2.round({ largestUnit: "weeks", smallestUnit: "weeks", relativeTo }); -assert.sameValue(calendar.dateAddCallCount, 9, "rounding with non-default largestUnit and calendar smallestUnit"); +assert.sameValue(calendar.dateAddCallCount, 8, "rounding with non-default largestUnit and calendar smallestUnit"); // Rounding with smallestUnit a non-calendar unit, and having the resulting time // difference be longer than a calendar day, covering the paths that go through diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/calendar-dateuntil-called-with-singular-largestunit.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/calendar-dateuntil-called-with-singular-largestunit.js index d0092fc8a3d0..951417a6d3fb 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/calendar-dateuntil-called-with-singular-largestunit.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/calendar-dateuntil-called-with-singular-largestunit.js @@ -5,13 +5,12 @@ esid: sec-temporal.duration.prototype.round description: The options object passed to calendar.dateUntil has a largestUnit property with its value in the singular form info: | - sec-temporal.duration.prototype.round steps 20–25: - 20. Let _unbalanceResult_ be ? UnbalanceDurationRelative(_duration_.[[Years]], _duration_.[[Months]], _duration_.[[Weeks]], _duration_.[[Days]], _largestUnit_, _relativeTo_). - 21. Let _roundResult_ be ? RoundDuration(_unbalanceResult_.[[Years]], _unbalanceResult_.[[Months]], _unbalanceResult_.[[Weeks]], _unbalanceResult_.[[Days]], _duration_.[[Hours]], _duration_.[[Minutes]], _duration_[[Seconds]], _duration_[[Milliseconds]], _duration_.[[Microseconds]], _duration_.[[Nanoseconds]], _roundingIncrement_, _smallestUnit_, _roundingMode_, _relativeTo_). - 22. Let _adjustResult_ be ? AdjustRoundedDurationDays(_roundResult_.[[Years]], _roundResult_.[[Months]], _roundResult_.[[Weeks]], _roundResult_.[[Days]], _roundResult_.[[Hours]], _roundResult_.[[Minutes]], _roundResult_.[[Seconds]], _roundResult_.[[Milliseconds]], _roundResult_.[[Microseconds]], _roundResult_.[[Nanoseconds]], _roundingIncrement_, _smallestUnit_, _roundingMode_, _relativeTo_). - 23. Let _balanceResult_ be ? BalanceDurationRelative(_adjustResult_.[[Years]], _adjustResult_.[[Months]], _adjustResult_.[[Weeks]], _adjustResult_.[[Days]], _largestUnit_, _relativeTo_). - 24. ... - 25. Let _result_ be ? BalanceDuration(_balanceResult_.[[Days]], _adjustResult_.[[Hours]], _adjustResult_.[[Minutes]], _adjustResult_.[[Seconds]], _adjustResult_.[[Milliseconds]], _adjustResult_.[[Microseconds]], _adjustResult.[[Nanoseconds]], _largestUnit_, _relativeTo_). + sec-temporal.duration.prototype.round steps 23–27: + 23. Let _unbalanceResult_ be ? UnbalanceDurationRelative(_duration_.[[Years]], _duration_.[[Months]], _duration_.[[Weeks]], _duration_.[[Days]], _largestUnit_, _relativeTo_). + 24. Let _roundResult_ be (? RoundDuration(_unbalanceResult_.[[Years]], _unbalanceResult_.[[Months]], _unbalanceResult_.[[Weeks]], _unbalanceResult_.[[Days]], _duration_.[[Hours]], _duration_.[[Minutes]], _duration_.[[Seconds]], _duration_.[[Milliseconds]], _duration_.[[Microseconds]], _duration_.[[Nanoseconds]], _roundingIncrement_, _smallestUnit_, _roundingMode_, _relativeTo_)).[[DurationRecord]]. + 25. Let _adjustResult_ be ? AdjustRoundedDurationDays(_roundResult_.[[Years]], _roundResult_.[[Months]], _roundResult_.[[Weeks]], _roundResult_.[[Days]], _roundResult_.[[Hours]], _roundResult_.[[Minutes]], _roundResult_.[[Seconds]], _roundResult_.[[Milliseconds]], _roundResult_.[[Microseconds]], _roundResult_.[[Nanoseconds]], _roundingIncrement_, _smallestUnit_, _roundingMode_, _relativeTo_). + 26. Let _balanceResult_ be ? BalanceDuration(_adjustResult_.[[Days]], _adjustResult_.[[Hours]], _adjustResult_.[[Minutes]], _adjustResult_.[[Seconds]], _adjustResult_.[[Milliseconds]], _adjustResult_.[[Microseconds]], _adjustResult_.[[Nanoseconds]], _largestUnit_, _relativeTo_). + 27. Let _result_ be ? BalanceDurationRelative(_adjustResult_.[[Years]], _adjustResult_.[[Months]], _adjustResult_.[[Weeks]], _balanceResult_.[[Days]], _largestUnit_, _relativeTo_). sec-temporal-unbalancedurationrelative steps 1 and 9.d.iii–v: 1. If _largestUnit_ is *"year"*, or _years_, _months_, _weeks_, and _days_ are all 0, then a. Return ... @@ -105,7 +104,7 @@ TemporalHelpers.checkCalendarDateUntilLargestUnitSingular( duration.round({ largestUnit, roundingIncrement: 2, roundingMode: 'ceil', relativeTo }); }, { - years: ["year", "day", "month", "day"], + years: ["year", "day", "day", "month"], months: ["month", "day", "day"], weeks: ["week", "day", "day"], days: ["day", "day", "day"], diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/largestunit-correct-rebalancing.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/largestunit-correct-rebalancing.js new file mode 100644 index 000000000000..7106936db3c3 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/largestunit-correct-rebalancing.js @@ -0,0 +1,24 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.round +description: Balancing from hours or smaller to weeks or bigger happens correctly. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const day_duration = 100; + +const tests = [ ["days", { days: day_duration }], + ["hours", { hours: day_duration * 24 }], + ["minutes", { minutes: day_duration * 24 * 60 }], + ["seconds", { seconds: day_duration * 24 * 60 * 60 }], + ["milliseconds", { milliseconds: day_duration * 24 * 60 * 60 * 1000 }], + ["microseconds", { microseconds: day_duration * 24 * 60 * 60 * 1000 * 1000 }], + ["nanoseconds", { nanoseconds: day_duration * 24 * 60 * 60 * 1000 * 1000 * 1000 }]]; + +for ([unit, duration_desc] of tests) + TemporalHelpers.assertDuration(Temporal.Duration.from(duration_desc).round({ relativeTo: '2023-02-21', largestUnit: 'month' }), + 0, 3, 0, 11, 0, 0, 0, 0, 0, 0, `rounding from ${unit}`); + diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/order-of-operations.js index 8ab04a64a1bb..732dded8584c 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/order-of-operations.js @@ -48,7 +48,27 @@ const expectedOpsForPlainRelativeTo = [ "call options.largestUnit.toString", "get options.relativeTo", "get options.relativeTo.calendar", - "has options.relativeTo.calendar.calendar", + "has options.relativeTo.calendar.dateAdd", + "has options.relativeTo.calendar.dateFromFields", + "has options.relativeTo.calendar.dateUntil", + "has options.relativeTo.calendar.day", + "has options.relativeTo.calendar.dayOfWeek", + "has options.relativeTo.calendar.dayOfYear", + "has options.relativeTo.calendar.daysInMonth", + "has options.relativeTo.calendar.daysInWeek", + "has options.relativeTo.calendar.daysInYear", + "has options.relativeTo.calendar.fields", + "has options.relativeTo.calendar.id", + "has options.relativeTo.calendar.inLeapYear", + "has options.relativeTo.calendar.mergeFields", + "has options.relativeTo.calendar.month", + "has options.relativeTo.calendar.monthCode", + "has options.relativeTo.calendar.monthDayFromFields", + "has options.relativeTo.calendar.monthsInYear", + "has options.relativeTo.calendar.weekOfYear", + "has options.relativeTo.calendar.year", + "has options.relativeTo.calendar.yearMonthFromFields", + "has options.relativeTo.calendar.yearOfWeek", "get options.relativeTo.calendar.fields", "call options.relativeTo.calendar.fields", "get options.relativeTo.day", @@ -231,7 +251,27 @@ const expectedOpsForZonedRelativeTo = [ "call options.largestUnit.toString", "get options.relativeTo", "get options.relativeTo.calendar", - "has options.relativeTo.calendar.calendar", + "has options.relativeTo.calendar.dateAdd", + "has options.relativeTo.calendar.dateFromFields", + "has options.relativeTo.calendar.dateUntil", + "has options.relativeTo.calendar.day", + "has options.relativeTo.calendar.dayOfWeek", + "has options.relativeTo.calendar.dayOfYear", + "has options.relativeTo.calendar.daysInMonth", + "has options.relativeTo.calendar.daysInWeek", + "has options.relativeTo.calendar.daysInYear", + "has options.relativeTo.calendar.fields", + "has options.relativeTo.calendar.id", + "has options.relativeTo.calendar.inLeapYear", + "has options.relativeTo.calendar.mergeFields", + "has options.relativeTo.calendar.month", + "has options.relativeTo.calendar.monthCode", + "has options.relativeTo.calendar.monthDayFromFields", + "has options.relativeTo.calendar.monthsInYear", + "has options.relativeTo.calendar.weekOfYear", + "has options.relativeTo.calendar.year", + "has options.relativeTo.calendar.yearMonthFromFields", + "has options.relativeTo.calendar.yearOfWeek", "get options.relativeTo.calendar.fields", "call options.relativeTo.calendar.fields", "get options.relativeTo.day", @@ -270,7 +310,9 @@ const expectedOpsForZonedRelativeTo = [ "call options.relativeTo.year.valueOf", "get options.relativeTo.calendar.dateFromFields", "call options.relativeTo.calendar.dateFromFields", - "has options.relativeTo.timeZone.timeZone", + "has options.relativeTo.timeZone.getOffsetNanosecondsFor", + "has options.relativeTo.timeZone.getPossibleInstantsFor", + "has options.relativeTo.timeZone.id", // InterpretISODateTimeOffset "get options.relativeTo.timeZone.getPossibleInstantsFor", "call options.relativeTo.timeZone.getPossibleInstantsFor", @@ -309,3 +351,44 @@ const zonedRelativeTo = TemporalHelpers.propertyBagObserver(actual, { // basic order of operations with ZonedDateTime relativeTo: instance.round(createOptionsObserver({ relativeTo: zonedRelativeTo })); assert.compareArray(actual, expectedOpsForZonedRelativeTo, "order of operations for ZonedDateTime relativeTo"); +actual.splice(0); // clear + +// code path through RoundDuration that rounds to the nearest year: +const expectedOpsForYearRoundingZoned = expectedOpsForZonedRelativeTo.concat([ + // NanosecondsToDays + "get options.relativeTo.timeZone.getOffsetNanosecondsFor", // 7. GetPlainDateTimeFor + "call options.relativeTo.timeZone.getOffsetNanosecondsFor", + "get options.relativeTo.timeZone.getOffsetNanosecondsFor", // 11. GetPlainDateTimeFor + "call options.relativeTo.timeZone.getOffsetNanosecondsFor", + "get options.relativeTo.calendar.dateUntil", // 12. DifferenceISODateTime + "call options.relativeTo.calendar.dateUntil", + // NanosecondsToDays → AddZonedDateTime + "get options.relativeTo.timeZone.getOffsetNanosecondsFor", // 5. GetPlainDateTimeFor + "call options.relativeTo.timeZone.getOffsetNanosecondsFor", + "get options.relativeTo.calendar.dateAdd", // 8. + "call options.relativeTo.calendar.dateAdd", + "get options.relativeTo.timeZone.getPossibleInstantsFor", // 10. GetInstantFor + "call options.relativeTo.timeZone.getPossibleInstantsFor", + // NanosecondsToDays → AddZonedDateTime + "get options.relativeTo.timeZone.getOffsetNanosecondsFor", // 5. GetPlainDateTimeFor + "call options.relativeTo.timeZone.getOffsetNanosecondsFor", + "get options.relativeTo.calendar.dateAdd", // 8. + "call options.relativeTo.calendar.dateAdd", + "get options.relativeTo.timeZone.getPossibleInstantsFor", // 10. GetInstantFor + "call options.relativeTo.timeZone.getPossibleInstantsFor", + "get options.relativeTo.calendar.dateAdd", // 9.b + "call options.relativeTo.calendar.dateAdd", // 9.c + "call options.relativeTo.calendar.dateAdd", // 9.e + "call options.relativeTo.calendar.dateAdd", // 9.j + "get options.relativeTo.calendar.dateUntil", // 9.m + "call options.relativeTo.calendar.dateUntil", // 9.m + "call options.relativeTo.calendar.dateAdd", // 9.r + "call options.relativeTo.calendar.dateAdd", // 9.w MoveRelativeDate +]); +instance.round(createOptionsObserver({ smallestUnit: "years", relativeTo: zonedRelativeTo })); +assert.compareArray( + actual, + expectedOpsForYearRoundingZoned, + "order of operations with smallestUnit = years and ZonedDateTime relativeTo" +); +actual.splice(0); // clear diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-calendar-number.js index 6aee637fc195..682e48a490c3 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-calendar-number.js @@ -12,13 +12,9 @@ const instance = new Temporal.Duration(1, 0, 0, 0, 24); const calendar = 19970327; -let relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; -const result1 = instance.round({ largestUnit: "years", relativeTo }); -TemporalHelpers.assertDuration(result1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for relativeTo.calendar"); - -relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; -const result2 = instance.round({ largestUnit: "years", relativeTo }); -TemporalHelpers.assertDuration(result2, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for relativeTo.calendar (nested property)"); +const relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; +const result = instance.round({ largestUnit: "years", relativeTo }); +TemporalHelpers.assertDuration(result, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for relativeTo.calendar"); const numbers = [ 1, @@ -27,16 +23,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; + const relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws( RangeError, () => instance.round({ largestUnit: "years", relativeTo }), `Number ${calendar} does not convert to a valid ISO string for relativeTo.calendar` ); - relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.round({ largestUnit: "years", relativeTo }), - `Number ${calendar} does not convert to a valid ISO string for relativeTo.calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-calendar-string.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-calendar-string.js new file mode 100644 index 000000000000..070e4ad7649f --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-calendar-string.js @@ -0,0 +1,26 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.round +description: > + Builtin dateFromFields method is not observably called when the property bag + has a string-valued calendar property +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const dateFromFieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dateFromFields"); +Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("dateFromFields should not be looked up"); + }, +}); + +const instance = new Temporal.Duration(1, 0, 0, 0, 24); +const relativeTo = { year: 2000, month: 5, day: 2, calendar: "iso8601" }; +instance.round({ largestUnit: "years", relativeTo }); + +Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", dateFromFieldsOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-calendar-wrong-type.js index 0baa3c35ad54..0a6adffc5899 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-calendar-wrong-type.js @@ -18,20 +18,17 @@ const rangeErrorTests = [ ["", "empty string"], [1, "number that doesn't convert to a valid ISO string"], [1n, "bigint"], - [new Temporal.TimeZone("UTC"), "time zone instance"], ]; for (const [calendar, description] of rangeErrorTests) { - let relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; + const relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.round({ largestUnit: "years", relativeTo }), `${description} does not convert to a valid ISO string`); - - relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.round({ largestUnit: "years", relativeTo }), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], [Temporal.PlainDate, "Temporal.PlainDate, object"], [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], [Temporal.ZonedDateTime, "Temporal.ZonedDateTime, object"], @@ -39,12 +36,6 @@ const typeErrorTests = [ ]; for (const [calendar, description] of typeErrorTests) { - let relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; + const relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.round({ largestUnit: "years", relativeTo }), `${description} is not a valid property bag and does not convert to a string`); - - relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.round({ largestUnit: "years", relativeTo }), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.round({ largestUnit: "years", relativeTo }), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-timezone-instance-does-not-get-timeZone-property.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-timezone-instance-does-not-get-timeZone-property.js deleted file mode 100644 index 0f0cb9ff2148..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-timezone-instance-does-not-get-timeZone-property.js +++ /dev/null @@ -1,22 +0,0 @@ -// 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.round -description: > - A Temporal.TimeZone instance passed to round() does not have its - 'timeZone' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.Duration(1); - -const timeZone = new Temporal.TimeZone("UTC"); -Object.defineProperty(timeZone, "timeZone", { - get() { - throw new Test262Error("timeZone.timeZone should not be accessed"); - }, -}); - -instance.round({ largestUnit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone } }); -instance.round({ largestUnit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-timezone-string-datetime.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-timezone-string-datetime.js index cc4d8b377fd7..774bb727cf6b 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-timezone-string-datetime.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-timezone-string-datetime.js @@ -11,7 +11,6 @@ const instance = new Temporal.Duration(1); let timeZone = "2021-08-19T17:30"; assert.throws(RangeError, () => instance.round({ largestUnit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), "bare date-time string is not a time zone"); -assert.throws(RangeError, () => instance.round({ largestUnit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), "bare date-time string is not a time zone"); // The following are all valid strings so should not throw: @@ -32,5 +31,4 @@ assert.throws(RangeError, () => instance.round({ largestUnit: "months", relative "2021-08-19T1730-0700[UTC]", ].forEach((timeZone) => { instance.round({ largestUnit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone } }); - instance.round({ largestUnit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }); }); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-timezone-string-leap-second.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-timezone-string-leap-second.js index 73e01540e2c6..de17fb684adb 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-timezone-string-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-timezone-string-leap-second.js @@ -10,12 +10,10 @@ features: [Temporal] const instance = new Temporal.Duration(1); let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; -// A string with a leap second is a valid ISO string, so the following two -// operations should not throw +// A string with a leap second is a valid ISO string, so the following +// operation should not throw instance.round({ largestUnit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone } }); -instance.round({ largestUnit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }); timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; assert.throws(RangeError, () => instance.round({ largestUnit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), "leap second in time zone name not valid"); -assert.throws(RangeError, () => instance.round({ largestUnit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), "leap second in time zone name not valid (nested property)"); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-timezone-string-year-zero.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-timezone-string-year-zero.js index 290099ebed96..3edcb20432a8 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-timezone-string-year-zero.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-timezone-string-year-zero.js @@ -18,9 +18,4 @@ invalidStrings.forEach((timeZone) => { () => instance.round({ largestUnit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), "reject minus zero as extended year" ); - assert.throws( - RangeError, - () => instance.round({ largestUnit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), - "reject minus zero as extended year (nested property)" - ); }); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-timezone-string.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-timezone-string.js index a279c3cdea79..2061506da384 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-timezone-string.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-timezone-string.js @@ -4,9 +4,27 @@ /*--- esid: sec-temporal.duration.prototype.round description: Time zone IDs are valid input for a time zone +includes: [temporalHelpers.js] features: [Temporal] ---*/ +const getPossibleInstantsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getPossibleInstantsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getPossibleInstantsFor should not be looked up"); + }, +}); +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + const instance = new Temporal.Duration(1); // The following are all valid strings so should not throw: @@ -14,3 +32,6 @@ const instance = new Temporal.Duration(1); ["UTC", "+01:00"].forEach((timeZone) => { instance.round({ largestUnit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone } }); }); + +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", getPossibleInstantsForOriginal); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-timezone-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-timezone-wrong-type.js index c77296c0713a..8c0557196108 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-timezone-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-timezone-wrong-type.js @@ -18,22 +18,18 @@ const rangeErrorTests = [ [1, "number that doesn't convert to a valid ISO string"], [19761118, "number that would convert to a valid ISO string in other contexts"], [1n, "bigint"], - [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of rangeErrorTests) { assert.throws(RangeError, () => instance.round({ largestUnit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), `${description} does not convert to a valid ISO string`); - assert.throws(RangeError, () => instance.round({ largestUnit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], + [{}, "object not implementing time zone protocol"], + [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of typeErrorTests) { assert.throws(TypeError, () => instance.round({ largestUnit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), `${description} is not a valid object and does not convert to a string`); - assert.throws(TypeError, () => instance.round({ largestUnit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), `${description} is not a valid object and does not convert to a string (nested property)`); } - -const timeZone = undefined; -assert.throws(RangeError, () => instance.round({ largestUnit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), `undefined is always a RangeError as nested property`); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/relativeto-zoneddatetime-nanoseconds-to-days-range-errors.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/relativeto-zoneddatetime-nanoseconds-to-days-range-errors.js index bebb9c411d63..cf6f0219c600 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/relativeto-zoneddatetime-nanoseconds-to-days-range-errors.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/relativeto-zoneddatetime-nanoseconds-to-days-range-errors.js @@ -54,7 +54,8 @@ assert.throws(RangeError, () => oneNsDuration.round({ relativeTo: zdt, smallestUnit: "days", - }) + }), + "RangeError when days < 0 and sign = 1" ); // NanosecondsToDays.20: days > 0 and sign = -1 @@ -74,7 +75,8 @@ assert.throws(RangeError, () => negOneNsDuration.round({ relativeTo: zdt, smallestUnit: "days", - }) + }), + "RangeError when days > 0 and sign = -1" ); // NanosecondsToDays.22: nanoseconds > 0 and sign = -1 @@ -93,9 +95,10 @@ zdt = new Temporal.ZonedDateTime( ) ); assert.throws(RangeError, () => - // Using -1ns duration sets _nanoseocnds_ to -1 and _sign_ to -1 + // Using -1ns duration sets _nanoseconds_ to -1 and _sign_ to -1 negOneNsDuration.round({ relativeTo: zdt, smallestUnit: "days", - }) + }), + "RangeError when nanoseconds > 0 and sign = -1" ); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/throws-in-unbalance-duration-relative-when-sign-mismatched.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/throws-in-unbalance-duration-relative-when-sign-mismatched.js index 2cac32ec245c..492d89a7ee4d 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/throws-in-unbalance-duration-relative-when-sign-mismatched.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/throws-in-unbalance-duration-relative-when-sign-mismatched.js @@ -22,7 +22,7 @@ var cal = new class extends Temporal.Calendar { }("iso8601"); var relativeTo = new Temporal.PlainDateTime(1970, 1, 1, 0, 0, 0, 0, 0, 0, cal); -assert.sameValue(relativeTo.calendar, cal); +assert.sameValue(relativeTo.getCalendar(), cal); var options = { smallestUnit: "days", diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/timezone-getpossibleinstantsfor-iterable.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/timezone-getpossibleinstantsfor-iterable.js index a67eb7e60a5e..1838425cb15c 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/timezone-getpossibleinstantsfor-iterable.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/timezone-getpossibleinstantsfor-iterable.js @@ -36,7 +36,6 @@ const expected = [ "2000-01-01T00:00:00", // called once on the input relativeTo object "2001-02-09T00:00:00", // called once on relativeTo plus years, months, weeks, days from the receiver "2001-02-10T00:00:00", // called once on the previous value plus the calendar days difference between that and the time part of the duration - "2001-02-01T00:00:00", // called once on relativeTo plus the years, months, and weeks part of the balance result ]; TemporalHelpers.checkTimeZonePossibleInstantsIterable((timeZone) => { diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/zero-day-length-1.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/zero-day-length-1.js new file mode 100644 index 000000000000..ed7f281bca44 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/zero-day-length-1.js @@ -0,0 +1,40 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.round +description: A malicious time zone resulting a day length of zero is handled correctly +info: | + Based on a test by André Bargull. + + RoundDuration step 6: + d. Let _result_ be ? NanosecondsToDays(_nanoseconds_, _intermediate_). + e. Set _days_ to _days_ + _result_.[[Days]] + _result_.[[Nanoseconds]] / _result_.[[DayLength]]. + + NanosecondsToDays steps 19-23: + 19. If _days_ < 0 and _sign_ = 1, throw a *RangeError* exception. + 20. If _days_ > 0 and _sign_ = -1, throw a *RangeError* exception. + 21. If _nanoseconds_ < 0, then + a. Assert: sign is -1. + 22. If _nanoseconds_ > 0 and _sign_ = -1, throw a *RangeError* exception. + 23. Assert: The inequality abs(_nanoseconds_) < abs(_dayLengthNs_) holds. +features: [Temporal] +---*/ + +const instance = new Temporal.Duration(0, 0, 0, 0, -24, 0, 0, 0, 0, -1); + +const tz = new class extends Temporal.TimeZone { + #getPossibleInstantsForCalls = 0; + + getPossibleInstantsFor(dt) { + this.#getPossibleInstantsForCalls++; + + if (this.#getPossibleInstantsForCalls <= 2) { + return [new Temporal.Instant(-86400_000_000_000n - 2n)] + } + return super.getPossibleInstantsFor(dt); + } +}("UTC"); + +const relativeTo = new Temporal.ZonedDateTime(0n, tz, "iso8601"); +assert.throws(RangeError, () => instance.round({ relativeTo, smallestUnit: "days" })); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/zero-day-length-2.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/zero-day-length-2.js new file mode 100644 index 000000000000..60d5fbee152a --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/round/zero-day-length-2.js @@ -0,0 +1,53 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.round +description: A malicious time zone resulting a day length of zero is handled correctly +info: | + Based on a test by André Bargull. + + RoundDuration step 6: + d. Let _result_ be ? NanosecondsToDays(_nanoseconds_, _intermediate_). + e. Set _days_ to _days_ + _result_.[[Days]] + _result_.[[Nanoseconds]] / _result_.[[DayLength]]. + + NanosecondsToDays steps 19-23: + 19. If _days_ < 0 and _sign_ = 1, throw a *RangeError* exception. + 20. If _days_ > 0 and _sign_ = -1, throw a *RangeError* exception. + 21. If _nanoseconds_ < 0, then + a. Assert: sign is -1. + 22. If _nanoseconds_ > 0 and _sign_ = -1, throw a *RangeError* exception. + 23. Assert: The inequality abs(_nanoseconds_) < abs(_dayLengthNs_) holds. +features: [Temporal] +---*/ + +const instance = new Temporal.Duration(0, 0, 0, 0, 24, 0, 0, 0, 0, 1); + +const tz = new class extends Temporal.TimeZone { + #getPossibleInstantsForCalls = 0; + + getPossibleInstantsFor(dt) { + this.#getPossibleInstantsForCalls++; + + if (this.#getPossibleInstantsForCalls <= 2) { + return [new Temporal.Instant(86400_000_000_000n + 2n)] + } + return super.getPossibleInstantsFor(dt); + } +}("UTC"); + +const cal = new class extends Temporal.Calendar { + #dateUntilCalls = 0; + + dateUntil(one, two, options) { + this.#dateUntilCalls++; + + if (this.#dateUntilCalls === 1) { + return new Temporal.Duration(0, 0, 0, -2); + } + return super.dateUntil(one, two, options); + } +}("iso8601"); + +const relativeTo = new Temporal.ZonedDateTime(0n, tz, cal); +assert.throws(RangeError, () => instance.round({ relativeTo, smallestUnit: "days" })); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/subtract/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/subtract/order-of-operations.js index 0819c8786f56..5b9dcf3dd2ba 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/subtract/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/subtract/order-of-operations.js @@ -71,7 +71,27 @@ actual.splice(0); // clear const expectedOpsForPlainRelativeTo = expected.concat([ // ToRelativeTemporalObject "get options.relativeTo.calendar", - "has options.relativeTo.calendar.calendar", + "has options.relativeTo.calendar.dateAdd", + "has options.relativeTo.calendar.dateFromFields", + "has options.relativeTo.calendar.dateUntil", + "has options.relativeTo.calendar.day", + "has options.relativeTo.calendar.dayOfWeek", + "has options.relativeTo.calendar.dayOfYear", + "has options.relativeTo.calendar.daysInMonth", + "has options.relativeTo.calendar.daysInWeek", + "has options.relativeTo.calendar.daysInYear", + "has options.relativeTo.calendar.fields", + "has options.relativeTo.calendar.id", + "has options.relativeTo.calendar.inLeapYear", + "has options.relativeTo.calendar.mergeFields", + "has options.relativeTo.calendar.month", + "has options.relativeTo.calendar.monthCode", + "has options.relativeTo.calendar.monthDayFromFields", + "has options.relativeTo.calendar.monthsInYear", + "has options.relativeTo.calendar.weekOfYear", + "has options.relativeTo.calendar.year", + "has options.relativeTo.calendar.yearMonthFromFields", + "has options.relativeTo.calendar.yearOfWeek", "get options.relativeTo.calendar.fields", "call options.relativeTo.calendar.fields", // PrepareTemporalFields @@ -136,7 +156,27 @@ actual.splice(0); // clear const expectedOpsForZonedRelativeTo = expected.concat([ // ToRelativeTemporalObject "get options.relativeTo.calendar", - "has options.relativeTo.calendar.calendar", + "has options.relativeTo.calendar.dateAdd", + "has options.relativeTo.calendar.dateFromFields", + "has options.relativeTo.calendar.dateUntil", + "has options.relativeTo.calendar.day", + "has options.relativeTo.calendar.dayOfWeek", + "has options.relativeTo.calendar.dayOfYear", + "has options.relativeTo.calendar.daysInMonth", + "has options.relativeTo.calendar.daysInWeek", + "has options.relativeTo.calendar.daysInYear", + "has options.relativeTo.calendar.fields", + "has options.relativeTo.calendar.id", + "has options.relativeTo.calendar.inLeapYear", + "has options.relativeTo.calendar.mergeFields", + "has options.relativeTo.calendar.month", + "has options.relativeTo.calendar.monthCode", + "has options.relativeTo.calendar.monthDayFromFields", + "has options.relativeTo.calendar.monthsInYear", + "has options.relativeTo.calendar.weekOfYear", + "has options.relativeTo.calendar.year", + "has options.relativeTo.calendar.yearMonthFromFields", + "has options.relativeTo.calendar.yearOfWeek", "get options.relativeTo.calendar.fields", "call options.relativeTo.calendar.fields", // PrepareTemporalFields @@ -178,7 +218,9 @@ const expectedOpsForZonedRelativeTo = expected.concat([ "get options.relativeTo.calendar.dateFromFields", "call options.relativeTo.calendar.dateFromFields", // ToRelativeTemporalObject again - "has options.relativeTo.timeZone.timeZone", + "has options.relativeTo.timeZone.getOffsetNanosecondsFor", + "has options.relativeTo.timeZone.getPossibleInstantsFor", + "has options.relativeTo.timeZone.id", // InterpretISODateTimeOffset "get options.relativeTo.timeZone.getPossibleInstantsFor", "call options.relativeTo.timeZone.getPossibleInstantsFor", diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-calendar-number.js index d00e30568fce..ff3b452eb29e 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-calendar-number.js @@ -12,13 +12,9 @@ const instance = new Temporal.Duration(1, 0, 0, 1); const calendar = 19970327; -let relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; -const result1 = instance.subtract(new Temporal.Duration(0, 0, 0, 0, 24), { relativeTo }); -TemporalHelpers.assertDuration(result1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for relativeTo.calendar"); - -relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; -const result2 = instance.subtract(new Temporal.Duration(0, 0, 0, 0, 24), { relativeTo }); -TemporalHelpers.assertDuration(result2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for relativeTo.calendar (nested property)"); +const relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; +const result = instance.subtract(new Temporal.Duration(0, 0, 0, 0, 24), { relativeTo }); +TemporalHelpers.assertDuration(result, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for relativeTo.calendar"); const numbers = [ 1, @@ -27,16 +23,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; + const relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws( RangeError, () => instance.subtract(new Temporal.Duration(0, 0, 0, 0, 24), { relativeTo }), `Number ${calendar} does not convert to a valid ISO string for relativeTo.calendar` ); - relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.subtract(new Temporal.Duration(0, 0, 0, 0, 24), { relativeTo }), - `Number ${calendar} does not convert to a valid ISO string for relativeTo.calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-calendar-string.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-calendar-string.js new file mode 100644 index 000000000000..989b046d9214 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-calendar-string.js @@ -0,0 +1,26 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.subtract +description: > + Builtin dateFromFields method is not observably called when the property bag + has a string-valued calendar property +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const dateFromFieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dateFromFields"); +Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("dateFromFields should not be looked up"); + }, +}); + +const instance = new Temporal.Duration(1, 0, 0, 1); +const relativeTo = { year: 2000, month: 5, day: 2, calendar: "iso8601" }; +instance.subtract(new Temporal.Duration(0, 0, 0, 0, 24), { relativeTo }); + +Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", dateFromFieldsOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-calendar-wrong-type.js index eb831ff77f48..5a9b7ca12789 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-calendar-wrong-type.js @@ -18,20 +18,17 @@ const rangeErrorTests = [ ["", "empty string"], [1, "number that doesn't convert to a valid ISO string"], [1n, "bigint"], - [new Temporal.TimeZone("UTC"), "time zone instance"], ]; for (const [calendar, description] of rangeErrorTests) { - let relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; + const relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.subtract(new Temporal.Duration(0, 0, 0, 0, 24), { relativeTo }), `${description} does not convert to a valid ISO string`); - - relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.subtract(new Temporal.Duration(0, 0, 0, 0, 24), { relativeTo }), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], [Temporal.PlainDate, "Temporal.PlainDate, object"], [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], [Temporal.ZonedDateTime, "Temporal.ZonedDateTime, object"], @@ -39,12 +36,6 @@ const typeErrorTests = [ ]; for (const [calendar, description] of typeErrorTests) { - let relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; + const relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.subtract(new Temporal.Duration(0, 0, 0, 0, 24), { relativeTo }), `${description} is not a valid property bag and does not convert to a string`); - - relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.subtract(new Temporal.Duration(0, 0, 0, 0, 24), { relativeTo }), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.subtract(new Temporal.Duration(0, 0, 0, 0, 24), { relativeTo }), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-timezone-instance-does-not-get-timeZone-property.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-timezone-instance-does-not-get-timeZone-property.js deleted file mode 100644 index b4a92890a5e5..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-timezone-instance-does-not-get-timeZone-property.js +++ /dev/null @@ -1,22 +0,0 @@ -// 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.subtract -description: > - A Temporal.TimeZone instance passed to subtract() does not have its - 'timeZone' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.Duration(1); - -const timeZone = new Temporal.TimeZone("UTC"); -Object.defineProperty(timeZone, "timeZone", { - get() { - throw new Test262Error("timeZone.timeZone should not be accessed"); - }, -}); - -instance.subtract(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }); -instance.subtract(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-timezone-string-datetime.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-timezone-string-datetime.js index 1944c6d4d5e4..1f85b2dcf6e9 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-timezone-string-datetime.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-timezone-string-datetime.js @@ -11,7 +11,6 @@ const instance = new Temporal.Duration(1); let timeZone = "2021-08-19T17:30"; assert.throws(RangeError, () => instance.subtract(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), "bare date-time string is not a time zone"); -assert.throws(RangeError, () => instance.subtract(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), "bare date-time string is not a time zone"); // The following are all valid strings so should not throw: @@ -32,5 +31,4 @@ assert.throws(RangeError, () => instance.subtract(new Temporal.Duration(1), { re "2021-08-19T1730-0700[UTC]", ].forEach((timeZone) => { instance.subtract(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }); - instance.subtract(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }); }); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-timezone-string-leap-second.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-timezone-string-leap-second.js index 5cd39edc248c..088075a80cce 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-timezone-string-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-timezone-string-leap-second.js @@ -10,12 +10,10 @@ features: [Temporal] const instance = new Temporal.Duration(1); let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; -// A string with a leap second is a valid ISO string, so the following two -// operations should not throw +// A string with a leap second is a valid ISO string, so the following +// operation should not throw instance.subtract(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }); -instance.subtract(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }); timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; assert.throws(RangeError, () => instance.subtract(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), "leap second in time zone name not valid"); -assert.throws(RangeError, () => instance.subtract(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), "leap second in time zone name not valid (nested property)"); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-timezone-string-year-zero.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-timezone-string-year-zero.js index 251016b43220..7e7830a2e004 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-timezone-string-year-zero.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-timezone-string-year-zero.js @@ -18,9 +18,4 @@ invalidStrings.forEach((timeZone) => { () => instance.subtract(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), "reject minus zero as extended year" ); - assert.throws( - RangeError, - () => instance.subtract(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), - "reject minus zero as extended year (nested property)" - ); }); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-timezone-string.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-timezone-string.js index 48dacac7694f..c05acabb357c 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-timezone-string.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-timezone-string.js @@ -4,9 +4,27 @@ /*--- esid: sec-temporal.duration.prototype.subtract description: Time zone IDs are valid input for a time zone +includes: [temporalHelpers.js] features: [Temporal] ---*/ +const getPossibleInstantsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getPossibleInstantsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getPossibleInstantsFor should not be looked up"); + }, +}); +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + const instance = new Temporal.Duration(1); // The following are all valid strings so should not throw: @@ -14,3 +32,6 @@ const instance = new Temporal.Duration(1); ["UTC", "+01:00"].forEach((timeZone) => { instance.subtract(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }); }); + +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", getPossibleInstantsForOriginal); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-timezone-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-timezone-wrong-type.js index 41d797752451..61ad351a6070 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-timezone-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-timezone-wrong-type.js @@ -18,22 +18,18 @@ const rangeErrorTests = [ [1, "number that doesn't convert to a valid ISO string"], [19761118, "number that would convert to a valid ISO string in other contexts"], [1n, "bigint"], - [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of rangeErrorTests) { assert.throws(RangeError, () => instance.subtract(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), `${description} does not convert to a valid ISO string`); - assert.throws(RangeError, () => instance.subtract(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], + [{}, "object not implementing time zone protocol"], + [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of typeErrorTests) { assert.throws(TypeError, () => instance.subtract(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), `${description} is not a valid object and does not convert to a string`); - assert.throws(TypeError, () => instance.subtract(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), `${description} is not a valid object and does not convert to a string (nested property)`); } - -const timeZone = undefined; -assert.throws(RangeError, () => instance.subtract(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), `undefined is always a RangeError as nested property`); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/order-of-operations.js index 44aa5e89c9c8..45b550f0bdca 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/order-of-operations.js @@ -36,7 +36,27 @@ const expectedOpsForPlainRelativeTo = [ // ToRelativeTemporalObject "get options.relativeTo", "get options.relativeTo.calendar", - "has options.relativeTo.calendar.calendar", + "has options.relativeTo.calendar.dateAdd", + "has options.relativeTo.calendar.dateFromFields", + "has options.relativeTo.calendar.dateUntil", + "has options.relativeTo.calendar.day", + "has options.relativeTo.calendar.dayOfWeek", + "has options.relativeTo.calendar.dayOfYear", + "has options.relativeTo.calendar.daysInMonth", + "has options.relativeTo.calendar.daysInWeek", + "has options.relativeTo.calendar.daysInYear", + "has options.relativeTo.calendar.fields", + "has options.relativeTo.calendar.id", + "has options.relativeTo.calendar.inLeapYear", + "has options.relativeTo.calendar.mergeFields", + "has options.relativeTo.calendar.month", + "has options.relativeTo.calendar.monthCode", + "has options.relativeTo.calendar.monthDayFromFields", + "has options.relativeTo.calendar.monthsInYear", + "has options.relativeTo.calendar.weekOfYear", + "has options.relativeTo.calendar.year", + "has options.relativeTo.calendar.yearMonthFromFields", + "has options.relativeTo.calendar.yearOfWeek", "get options.relativeTo.calendar.fields", "call options.relativeTo.calendar.fields", "get options.relativeTo.day", @@ -144,7 +164,27 @@ const expectedOpsForZonedRelativeTo = [ // ToRelativeTemporalObject "get options.relativeTo", "get options.relativeTo.calendar", - "has options.relativeTo.calendar.calendar", + "has options.relativeTo.calendar.dateAdd", + "has options.relativeTo.calendar.dateFromFields", + "has options.relativeTo.calendar.dateUntil", + "has options.relativeTo.calendar.day", + "has options.relativeTo.calendar.dayOfWeek", + "has options.relativeTo.calendar.dayOfYear", + "has options.relativeTo.calendar.daysInMonth", + "has options.relativeTo.calendar.daysInWeek", + "has options.relativeTo.calendar.daysInYear", + "has options.relativeTo.calendar.fields", + "has options.relativeTo.calendar.id", + "has options.relativeTo.calendar.inLeapYear", + "has options.relativeTo.calendar.mergeFields", + "has options.relativeTo.calendar.month", + "has options.relativeTo.calendar.monthCode", + "has options.relativeTo.calendar.monthDayFromFields", + "has options.relativeTo.calendar.monthsInYear", + "has options.relativeTo.calendar.weekOfYear", + "has options.relativeTo.calendar.year", + "has options.relativeTo.calendar.yearMonthFromFields", + "has options.relativeTo.calendar.yearOfWeek", "get options.relativeTo.calendar.fields", "call options.relativeTo.calendar.fields", "get options.relativeTo.day", @@ -183,7 +223,9 @@ const expectedOpsForZonedRelativeTo = [ "call options.relativeTo.year.valueOf", "get options.relativeTo.calendar.dateFromFields", "call options.relativeTo.calendar.dateFromFields", - "has options.relativeTo.timeZone.timeZone", + "has options.relativeTo.timeZone.getOffsetNanosecondsFor", + "has options.relativeTo.timeZone.getPossibleInstantsFor", + "has options.relativeTo.timeZone.id", // InterpretISODateTimeOffset "get options.relativeTo.timeZone.getPossibleInstantsFor", "call options.relativeTo.timeZone.getPossibleInstantsFor", @@ -193,9 +235,6 @@ const expectedOpsForZonedRelativeTo = [ "get options.unit", "get options.unit.toString", "call options.unit.toString", - // RoundDuration → ToTemporalDate - "get options.relativeTo.timeZone.getOffsetNanosecondsFor", - "call options.relativeTo.timeZone.getOffsetNanosecondsFor", ]; const zonedRelativeTo = TemporalHelpers.propertyBagObserver(actual, { @@ -216,4 +255,63 @@ const zonedRelativeTo = TemporalHelpers.propertyBagObserver(actual, { // basic order of observable operations, without rounding: instance.total(createOptionsObserver({ unit: "nanoseconds", relativeTo: zonedRelativeTo })); -assert.compareArray(actual, expectedOpsForZonedRelativeTo, "order of operations for ZonedDateTime relativeTo"); +assert.compareArray( + actual, + expectedOpsForZonedRelativeTo.concat([ + // RoundDuration → ToTemporalDate + "get options.relativeTo.timeZone.getOffsetNanosecondsFor", + "call options.relativeTo.timeZone.getOffsetNanosecondsFor", + ]), + "order of operations for ZonedDateTime relativeTo"); +actual.splice(0); // clear + +const expectedOpsForYearRoundingZoned = expectedOpsForZonedRelativeTo.concat([ + // BalancePossiblyInfiniteDuration → NanosecondsToDays + "get options.relativeTo.timeZone.getOffsetNanosecondsFor", // 7. GetPlainDateTimeFor + "call options.relativeTo.timeZone.getOffsetNanosecondsFor", + "get options.relativeTo.timeZone.getOffsetNanosecondsFor", // 11. GetPlainDateTimeFor + "call options.relativeTo.timeZone.getOffsetNanosecondsFor", + "get options.relativeTo.calendar.dateUntil", // 12. DifferenceISODateTime + "call options.relativeTo.calendar.dateUntil", + // BalancePossiblyInfiniteDuration → NanosecondsToDays → AddZonedDateTime + "get options.relativeTo.timeZone.getOffsetNanosecondsFor", // 5. GetPlainDateTimeFor + "call options.relativeTo.timeZone.getOffsetNanosecondsFor", + "get options.relativeTo.calendar.dateAdd", // 8. + "call options.relativeTo.calendar.dateAdd", + "get options.relativeTo.timeZone.getPossibleInstantsFor", // 10. GetInstantFor + "call options.relativeTo.timeZone.getPossibleInstantsFor", + // BalancePossiblyInfiniteDuration → NanosecondsToDays → AddZonedDateTime + "get options.relativeTo.timeZone.getOffsetNanosecondsFor", // 5. GetPlainDateTimeFor + "call options.relativeTo.timeZone.getOffsetNanosecondsFor", + "get options.relativeTo.calendar.dateAdd", // 8. + "call options.relativeTo.calendar.dateAdd", + "get options.relativeTo.timeZone.getPossibleInstantsFor", // 10. GetInstantFor + "call options.relativeTo.timeZone.getPossibleInstantsFor", +], [ + // ToTemporalDate + "get options.relativeTo.timeZone.getOffsetNanosecondsFor", + "call options.relativeTo.timeZone.getOffsetNanosecondsFor", + // code path through RoundDuration that rounds to the nearest year: + // MoveRelativeZonedDateTime → AddZonedDateTime + "get options.relativeTo.timeZone.getOffsetNanosecondsFor", // 5. GetPlainDateTimeFor + "call options.relativeTo.timeZone.getOffsetNanosecondsFor", + "get options.relativeTo.calendar.dateAdd", // 8. + "call options.relativeTo.calendar.dateAdd", + "get options.relativeTo.timeZone.getPossibleInstantsFor", // 10. GetInstantFor + "call options.relativeTo.timeZone.getPossibleInstantsFor", + "get options.relativeTo.calendar.dateAdd", // 9.b + "call options.relativeTo.calendar.dateAdd", // 9.c + "call options.relativeTo.calendar.dateAdd", // 9.e + "call options.relativeTo.calendar.dateAdd", // 9.j + "get options.relativeTo.calendar.dateUntil", // 9.m + "call options.relativeTo.calendar.dateUntil", // 9.m + "call options.relativeTo.calendar.dateAdd", // 9.r + "call options.relativeTo.calendar.dateAdd", // 9.w MoveRelativeDate +]); +instance.total(createOptionsObserver({ unit: "years", relativeTo: zonedRelativeTo })); +assert.compareArray( + actual, + expectedOpsForYearRoundingZoned, + "order of operations with unit = years and ZonedDateTime relativeTo" +); +actual.splice(0); // clear diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-calendar-number.js index 773e2f03bbc8..6633ab616cd3 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-calendar-number.js @@ -11,13 +11,9 @@ const instance = new Temporal.Duration(1, 0, 0, 0, 24); const calendar = 19970327; -let relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; -const result1 = instance.total({ unit: "days", relativeTo }); -assert.sameValue(result1, 367, "19970327 is a valid ISO string for relativeTo.calendar"); - -relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; -const result2 = instance.total({ unit: "days", relativeTo }); -assert.sameValue(result2, 367, "19970327 is a valid ISO string for relativeTo.calendar (nested property)"); +const relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; +const result = instance.total({ unit: "days", relativeTo }); +assert.sameValue(result, 367, "19970327 is a valid ISO string for relativeTo.calendar"); const numbers = [ 1, @@ -26,16 +22,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; + const relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws( RangeError, () => instance.total({ unit: "days", relativeTo }), `Number ${calendar} does not convert to a valid ISO string for relativeTo.calendar` ); - relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.total({ unit: "days", relativeTo }), - `Number ${calendar} does not convert to a valid ISO string for relativeTo.calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-calendar-string.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-calendar-string.js new file mode 100644 index 000000000000..c2e5ce2ca827 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-calendar-string.js @@ -0,0 +1,26 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.total +description: > + Builtin dateFromFields method is not observably called when the property bag + has a string-valued calendar property +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const dateFromFieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dateFromFields"); +Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("dateFromFields should not be looked up"); + }, +}); + +const instance = new Temporal.Duration(1, 0, 0, 0, 24); +const relativeTo = { year: 2000, month: 5, day: 2, calendar: "iso8601" }; +instance.total({ unit: "days", relativeTo }); + +Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", dateFromFieldsOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-calendar-wrong-type.js index d225356a5ebc..a495c04dd01e 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-calendar-wrong-type.js @@ -18,20 +18,17 @@ const rangeErrorTests = [ ["", "empty string"], [1, "number that doesn't convert to a valid ISO string"], [1n, "bigint"], - [new Temporal.TimeZone("UTC"), "time zone instance"], ]; for (const [calendar, description] of rangeErrorTests) { - let relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; + const relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.total({ unit: "days", relativeTo }), `${description} does not convert to a valid ISO string`); - - relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.total({ unit: "days", relativeTo }), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], [Temporal.PlainDate, "Temporal.PlainDate, object"], [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], [Temporal.ZonedDateTime, "Temporal.ZonedDateTime, object"], @@ -39,12 +36,6 @@ const typeErrorTests = [ ]; for (const [calendar, description] of typeErrorTests) { - let relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; + const relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.total({ unit: "days", relativeTo }), `${description} is not a valid property bag and does not convert to a string`); - - relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.total({ unit: "days", relativeTo }), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.total({ unit: "days", relativeTo }), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-timezone-instance-does-not-get-timeZone-property.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-timezone-instance-does-not-get-timeZone-property.js deleted file mode 100644 index 2ca7ed5f552f..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-timezone-instance-does-not-get-timeZone-property.js +++ /dev/null @@ -1,22 +0,0 @@ -// 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.total -description: > - A Temporal.TimeZone instance passed to total() does not have its - 'timeZone' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.Duration(1); - -const timeZone = new Temporal.TimeZone("UTC"); -Object.defineProperty(timeZone, "timeZone", { - get() { - throw new Test262Error("timeZone.timeZone should not be accessed"); - }, -}); - -instance.total({ unit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone } }); -instance.total({ unit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-timezone-string-datetime.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-timezone-string-datetime.js index 7f34abd37797..3d4b8f6c6a23 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-timezone-string-datetime.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-timezone-string-datetime.js @@ -11,7 +11,6 @@ const instance = new Temporal.Duration(1); let timeZone = "2021-08-19T17:30"; assert.throws(RangeError, () => instance.total({ unit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), "bare date-time string is not a time zone"); -assert.throws(RangeError, () => instance.total({ unit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), "bare date-time string is not a time zone"); // The following are all valid strings so should not throw: @@ -32,5 +31,4 @@ assert.throws(RangeError, () => instance.total({ unit: "months", relativeTo: { y "2021-08-19T1730-0700[UTC]", ].forEach((timeZone) => { instance.total({ unit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone } }); - instance.total({ unit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }); }); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-timezone-string-leap-second.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-timezone-string-leap-second.js index 0167a3c6ddaa..9fa62464bc68 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-timezone-string-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-timezone-string-leap-second.js @@ -10,12 +10,10 @@ features: [Temporal] const instance = new Temporal.Duration(1); let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; -// A string with a leap second is a valid ISO string, so the following two -// operations should not throw +// A string with a leap second is a valid ISO string, so the following +// operation should not throw instance.total({ unit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone } }); -instance.total({ unit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }); timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; assert.throws(RangeError, () => instance.total({ unit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), "leap second in time zone name not valid"); -assert.throws(RangeError, () => instance.total({ unit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), "leap second in time zone name not valid (nested property)"); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-timezone-string-year-zero.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-timezone-string-year-zero.js index 223a510ca997..2aca32cd5413 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-timezone-string-year-zero.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-timezone-string-year-zero.js @@ -18,9 +18,4 @@ invalidStrings.forEach((timeZone) => { () => instance.total({ unit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), "reject minus zero as extended year" ); - assert.throws( - RangeError, - () => instance.total({ unit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), - "reject minus zero as extended year (nested property)" - ); }); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-timezone-string.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-timezone-string.js index 9269225e5686..4bd5209ab9eb 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-timezone-string.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-timezone-string.js @@ -4,9 +4,27 @@ /*--- esid: sec-temporal.duration.prototype.total description: Time zone IDs are valid input for a time zone +includes: [temporalHelpers.js] features: [Temporal] ---*/ +const getPossibleInstantsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getPossibleInstantsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getPossibleInstantsFor should not be looked up"); + }, +}); +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + const instance = new Temporal.Duration(1); // The following are all valid strings so should not throw: @@ -14,3 +32,6 @@ const instance = new Temporal.Duration(1); ["UTC", "+01:00"].forEach((timeZone) => { instance.total({ unit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone } }); }); + +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", getPossibleInstantsForOriginal); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-timezone-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-timezone-wrong-type.js index e6c0d94209b9..b19bec2af7a7 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-timezone-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-timezone-wrong-type.js @@ -18,22 +18,18 @@ const rangeErrorTests = [ [1, "number that doesn't convert to a valid ISO string"], [19761118, "number that would convert to a valid ISO string in other contexts"], [1n, "bigint"], - [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of rangeErrorTests) { assert.throws(RangeError, () => instance.total({ unit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), `${description} does not convert to a valid ISO string`); - assert.throws(RangeError, () => instance.total({ unit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], + [{}, "object not implementing time zone protocol"], + [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of typeErrorTests) { assert.throws(TypeError, () => instance.total({ unit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), `${description} is not a valid object and does not convert to a string`); - assert.throws(TypeError, () => instance.total({ unit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), `${description} is not a valid object and does not convert to a string (nested property)`); } - -const timeZone = undefined; -assert.throws(RangeError, () => instance.total({ unit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), `undefined is always a RangeError as nested property`); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/relativeto-zoneddatetime-nanoseconds-to-days-range-errors.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/relativeto-zoneddatetime-nanoseconds-to-days-range-errors.js index b3a26f76ecf9..9957cbda0a95 100644 --- a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/relativeto-zoneddatetime-nanoseconds-to-days-range-errors.js +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/relativeto-zoneddatetime-nanoseconds-to-days-range-errors.js @@ -53,7 +53,8 @@ assert.throws(RangeError, () => oneNsDuration.total({ relativeTo: zdt, unit: "day", - }) + }), + "RangeError when days < 0 and sign = 1" ); // NanosecondsToDays.20: days > 0 and sign = -1 @@ -72,7 +73,8 @@ assert.throws(RangeError, () => negOneNsDuration.total({ relativeTo: zdt, unit: "day", - }) + }), + "RangeError when days > 0 and sign = -1" ); // NanosecondsToDays.22: nanoseconds > 0 and sign = -1 @@ -94,5 +96,6 @@ assert.throws(RangeError, () => negOneNsDuration.total({ relativeTo: zdt, unit: "day", - }) + }), + "RangeError when nanoseconds > 0 and sign = -1" ); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/zero-day-length-1.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/zero-day-length-1.js new file mode 100644 index 000000000000..2790977b23d4 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/zero-day-length-1.js @@ -0,0 +1,40 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.total +description: A malicious time zone resulting a day length of zero is handled correctly +info: | + Based on a test by André Bargull. + + RoundDuration step 6: + d. Let _result_ be ? NanosecondsToDays(_nanoseconds_, _intermediate_). + e. Set _days_ to _days_ + _result_.[[Days]] + _result_.[[Nanoseconds]] / _result_.[[DayLength]]. + + NanosecondsToDays steps 19-23: + 19. If _days_ < 0 and _sign_ = 1, throw a *RangeError* exception. + 20. If _days_ > 0 and _sign_ = -1, throw a *RangeError* exception. + 21. If _nanoseconds_ < 0, then + a. Assert: sign is -1. + 22. If _nanoseconds_ > 0 and _sign_ = -1, throw a *RangeError* exception. + 23. Assert: The inequality abs(_nanoseconds_) < abs(_dayLengthNs_) holds. +features: [Temporal] +---*/ + +const instance = new Temporal.Duration(0, 0, 0, 0, -24, 0, 0, 0, 0, -1); + +const tz = new class extends Temporal.TimeZone { + #getPossibleInstantsForCalls = 0; + + getPossibleInstantsFor(dt) { + this.#getPossibleInstantsForCalls++; + + if (this.#getPossibleInstantsForCalls <= 2) { + return [new Temporal.Instant(-86400_000_000_000n - 2n)] + } + return super.getPossibleInstantsFor(dt); + } +}("UTC"); + +const relativeTo = new Temporal.ZonedDateTime(0n, tz, "iso8601"); +assert.throws(RangeError, () => instance.total({ relativeTo, unit: "days" })); diff --git a/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/zero-day-length-2.js b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/zero-day-length-2.js new file mode 100644 index 000000000000..7d4d75205f58 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Duration/prototype/total/zero-day-length-2.js @@ -0,0 +1,53 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.round +description: A malicious time zone resulting a day length of zero is handled correctly +info: | + Based on a test by André Bargull. + + RoundDuration step 6: + d. Let _result_ be ? NanosecondsToDays(_nanoseconds_, _intermediate_). + e. Set _days_ to _days_ + _result_.[[Days]] + _result_.[[Nanoseconds]] / _result_.[[DayLength]]. + + NanosecondsToDays steps 19-23: + 19. If _days_ < 0 and _sign_ = 1, throw a *RangeError* exception. + 20. If _days_ > 0 and _sign_ = -1, throw a *RangeError* exception. + 21. If _nanoseconds_ < 0, then + a. Assert: sign is -1. + 22. If _nanoseconds_ > 0 and _sign_ = -1, throw a *RangeError* exception. + 23. Assert: The inequality abs(_nanoseconds_) < abs(_dayLengthNs_) holds. +features: [Temporal] +---*/ + +const instance = new Temporal.Duration(0, 0, 0, 0, 24, 0, 0, 0, 0, 1); + +const tz = new class extends Temporal.TimeZone { + #getPossibleInstantsForCalls = 0; + + getPossibleInstantsFor(dt) { + this.#getPossibleInstantsForCalls++; + + if (this.#getPossibleInstantsForCalls <= 2) { + return [new Temporal.Instant(86400_000_000_000n + 2n)] + } + return super.getPossibleInstantsFor(dt); + } +}("UTC"); + +const cal = new class extends Temporal.Calendar { + #dateUntilCalls = 0; + + dateUntil(one, two, options) { + this.#dateUntilCalls++; + + if (this.#dateUntilCalls === 1) { + return new Temporal.Duration(0, 0, 0, -2); + } + return super.dateUntil(one, two, options); + } +}("iso8601"); + +const relativeTo = new Temporal.ZonedDateTime(0n, tz, cal); +assert.throws(RangeError, () => instance.total({ relativeTo, unit: "days" })); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/compare/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/Instant/compare/argument-string-calendar-annotation.js index 4c11f5f83218..7336725aac1e 100644 --- a/JSTests/test262/test/built-ins/Temporal/Instant/compare/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/Instant/compare/argument-string-calendar-annotation.js @@ -15,7 +15,6 @@ const tests = [ ["1970-01-01T00:00Z[u-ca=discord]", "annotation is ignored"], ["1970-01-01T00:00Z[!u-ca=discord]", "annotation with ! is ignored"], ["1970-01-01T00:00Z[u-ca=iso8601][u-ca=discord]", "two annotations are ignored"], - ["1970-01-01T00:00Z[u-ca=iso8601][!u-ca=discord]", "two annotations are ignored even with !"], ]; tests.forEach(([arg, description]) => { diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/compare/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/Instant/compare/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..a8aac8fff669 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Instant/compare/argument-string-multiple-calendar.js @@ -0,0 +1,32 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.compare +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01T00:00Z[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00Z[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00Z[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00Z[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; + +const epoch = new Temporal.Instant(0n); + +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => Temporal.Instant.compare(arg, epoch), + `reject more than one calendar annotation if any critical: ${arg} (first argument)` + ); + assert.throws( + RangeError, + () => Temporal.Instant.compare(epoch, arg), + `reject more than one calendar annotation if any critical: ${arg} (second argument)` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/from/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/Instant/from/argument-string-calendar-annotation.js index 3b5310c090aa..aaec43e11baa 100644 --- a/JSTests/test262/test/built-ins/Temporal/Instant/from/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/Instant/from/argument-string-calendar-annotation.js @@ -15,7 +15,6 @@ const tests = [ ["1970-01-01T00:00Z[u-ca=discord]", "annotation is ignored"], ["1970-01-01T00:00Z[!u-ca=discord]", "annotation with ! is ignored"], ["1970-01-01T00:00Z[u-ca=iso8601][u-ca=discord]", "two annotations are ignored"], - ["1970-01-01T00:00Z[u-ca=iso8601][!u-ca=discord]", "two annotations are ignored even with !"], ]; tests.forEach(([arg, description]) => { diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/from/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/Instant/from/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..0785a6e8944f --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Instant/from/argument-string-multiple-calendar.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.from +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01T00:00Z[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00Z[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00Z[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00Z[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; + +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => Temporal.Instant.from(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/epochMicroseconds/basic.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/epochMicroseconds/basic.js index ca4a582ab60b..48b2dff6ee50 100644 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/epochMicroseconds/basic.js +++ b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/epochMicroseconds/basic.js @@ -12,5 +12,5 @@ assert.sameValue(afterEpoch.epochMicroseconds, 217175010_123_456n, "epochMicrose assert.sameValue(typeof afterEpoch.epochMicroseconds, "bigint", "epochMicroseconds value is a bigint"); const beforeEpoch = new Temporal.Instant(-217175010_876_543_211n); -assert.sameValue(beforeEpoch.epochMicroseconds, -217175010_876_543n, "epochMicroseconds pre epoch"); +assert.sameValue(beforeEpoch.epochMicroseconds, -217175010_876_544n, "epochMicroseconds pre epoch"); assert.sameValue(typeof beforeEpoch.epochMicroseconds, "bigint", "epochMicroseconds value is a bigint"); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/epochMilliseconds/basic.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/epochMilliseconds/basic.js index 418a5a95e4aa..e71d5ea34c3e 100644 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/epochMilliseconds/basic.js +++ b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/epochMilliseconds/basic.js @@ -12,5 +12,5 @@ assert.sameValue(afterEpoch.epochMilliseconds, 217175010_123, "epochMilliseconds assert.sameValue(typeof afterEpoch.epochMilliseconds, "number", "epochMilliseconds value is a number"); const beforeEpoch = new Temporal.Instant(-217175010_876_543_211n); -assert.sameValue(beforeEpoch.epochMilliseconds, -217175010_876, "epochMilliseconds pre epoch"); +assert.sameValue(beforeEpoch.epochMilliseconds, -217175010_877, "epochMilliseconds pre epoch"); assert.sameValue(typeof beforeEpoch.epochMilliseconds, "number", "epochMilliseconds value is a number"); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/epochSeconds/basic.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/epochSeconds/basic.js index 7c3e8ab7987a..404b01c55811 100644 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/epochSeconds/basic.js +++ b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/epochSeconds/basic.js @@ -12,5 +12,5 @@ assert.sameValue(afterEpoch.epochSeconds, 217175010, "epochSeconds post epoch"); assert.sameValue(typeof afterEpoch.epochSeconds, "number", "epochSeconds value is a number"); const beforeEpoch = new Temporal.Instant(-217175010_876_543_211n); -assert.sameValue(beforeEpoch.epochSeconds, -217175010, "epochSeconds pre epoch"); +assert.sameValue(beforeEpoch.epochSeconds, -217175011, "epochSeconds pre epoch"); assert.sameValue(typeof beforeEpoch.epochSeconds, "number", "epochSeconds value is a number"); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/equals/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/equals/argument-string-calendar-annotation.js index fb4f3a39cfbd..4387ed259d1e 100644 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/equals/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/equals/argument-string-calendar-annotation.js @@ -15,7 +15,6 @@ const tests = [ ["1970-01-01T00:00Z[u-ca=discord]", "annotation is ignored"], ["1970-01-01T00:00Z[!u-ca=discord]", "annotation with ! is ignored"], ["1970-01-01T00:00Z[u-ca=iso8601][u-ca=discord]", "two annotations are ignored"], - ["1970-01-01T00:00Z[u-ca=iso8601][!u-ca=discord]", "two annotations are ignored even with !"], ]; const instance = new Temporal.Instant(0n); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/equals/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/equals/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..d1acb1976c5b --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/equals/argument-string-multiple-calendar.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.equals +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01T00:00Z[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00Z[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00Z[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00Z[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.Instant(0n); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.equals(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/since/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/since/argument-string-calendar-annotation.js index 8056b73b985c..fcab109a3c75 100644 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/since/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/since/argument-string-calendar-annotation.js @@ -16,7 +16,6 @@ const tests = [ ["1970-01-01T00:00Z[u-ca=discord]", "annotation is ignored"], ["1970-01-01T00:00Z[!u-ca=discord]", "annotation with ! is ignored"], ["1970-01-01T00:00Z[u-ca=iso8601][u-ca=discord]", "two annotations are ignored"], - ["1970-01-01T00:00Z[u-ca=iso8601][!u-ca=discord]", "two annotations are ignored even with !"], ]; const instance = new Temporal.Instant(0n); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/since/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/since/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..812e7f16ee37 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/since/argument-string-multiple-calendar.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 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: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01T00:00Z[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00Z[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00Z[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00Z[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.Instant(0n); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.since(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toJSON/timezone-getoffsetnanosecondsfor-not-callable.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toJSON/timezone-getoffsetnanosecondsfor-not-callable.js deleted file mode 100644 index e906dea0e812..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toJSON/timezone-getoffsetnanosecondsfor-not-callable.js +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.instant.prototype.tojson -description: TypeError thrown if timeZone.getOffsetNanosecondsFor is not callable -features: [BigInt, Symbol, Temporal, arrow-function] ----*/ - -const instance = new Temporal.Instant(1_000_000_000_987_654_321n); - -[undefined, null, true, Math.PI, 'string', Symbol('sym'), 42n, {}].forEach((notCallable) => { - Temporal.TimeZone.prototype.getOffsetNanosecondsFor = notCallable; - assert.throws( - TypeError, - () => instance.toJSON(), - `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError` - ); -}); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toString/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toString/order-of-operations.js index bdec0d3efb28..0c4e27bc0336 100644 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toString/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toString/order-of-operations.js @@ -19,7 +19,9 @@ const expected = [ "get options.smallestUnit.toString", "call options.smallestUnit.toString", "get options.timeZone", - "has options.timeZone.timeZone", + "has options.timeZone.getOffsetNanosecondsFor", + "has options.timeZone.getPossibleInstantsFor", + "has options.timeZone.id", "get options.timeZone.getOffsetNanosecondsFor", "call options.timeZone.getOffsetNanosecondsFor", "get options.timeZone.getOffsetNanosecondsFor", diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toString/timezone-instance-does-not-get-timeZone-property.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toString/timezone-instance-does-not-get-timeZone-property.js deleted file mode 100644 index 54e6309bc3c6..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toString/timezone-instance-does-not-get-timeZone-property.js +++ /dev/null @@ -1,22 +0,0 @@ -// 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: > - A Temporal.TimeZone instance passed to toString() does not have its - 'timeZone' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.Instant(0n); - -const timeZone = new Temporal.TimeZone("UTC"); -Object.defineProperty(timeZone, "timeZone", { - get() { - throw new Test262Error("timeZone.timeZone should not be accessed"); - }, -}); - -instance.toString({ timeZone }); -instance.toString({ timeZone: { timeZone } }); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toString/timezone-string-datetime.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toString/timezone-string-datetime.js index e803ecbb0b6e..b1d948e4d4e8 100644 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toString/timezone-string-datetime.js +++ b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toString/timezone-string-datetime.js @@ -11,34 +11,23 @@ const instance = new Temporal.Instant(0n); let timeZone = "2021-08-19T17:30"; assert.throws(RangeError, () => instance.toString({ timeZone }), "bare date-time string is not a time zone"); -assert.throws(RangeError, () => instance.toString({ timeZone: { timeZone } }), "bare date-time string is not a time zone"); timeZone = "2021-08-19T17:30Z"; const result1 = instance.toString({ timeZone }); assert.sameValue(result1.substr(-6), "+00:00", "date-time + Z is UTC time zone"); -const result2 = instance.toString({ timeZone: { timeZone } }); -assert.sameValue(result2.substr(-6), "+00:00", "date-time + Z is UTC time zone (string in property bag)"); timeZone = "2021-08-19T17:30-07:00"; -const result3 = instance.toString({ timeZone }); -assert.sameValue(result3.substr(-6), "-07:00", "date-time + offset is the offset time zone"); -const result4 = instance.toString({ timeZone: { timeZone } }); -assert.sameValue(result4.substr(-6), "-07:00", "date-time + offset is the offset time zone (string in property bag)"); +const result2 = instance.toString({ timeZone }); +assert.sameValue(result2.substr(-6), "-07:00", "date-time + offset is the offset time zone"); timeZone = "2021-08-19T17:30[UTC]"; -const result5 = instance.toString({ timeZone }); -assert.sameValue(result5.substr(-6), "+00:00", "date-time + IANA annotation is the offset time zone"); -const result6 = instance.toString({ timeZone: { timeZone } }); -assert.sameValue(result6.substr(-6), "+00:00", "date-time + IANA annotation is the offset time zone (string in property bag)"); +const result3 = instance.toString({ timeZone }); +assert.sameValue(result3.substr(-6), "+00:00", "date-time + IANA annotation is the offset time zone"); timeZone = "2021-08-19T17:30Z[UTC]"; -const result7 = instance.toString({ timeZone }); -assert.sameValue(result7.substr(-6), "+00:00", "date-time + Z + IANA annotation is the offset time zone"); -const result8 = instance.toString({ timeZone: { timeZone } }); -assert.sameValue(result8.substr(-6), "+00:00", "date-time + Z + IANA annotation is the offset time zone (string in property bag)"); +const result4 = instance.toString({ timeZone }); +assert.sameValue(result4.substr(-6), "+00:00", "date-time + Z + IANA annotation is the offset time zone"); timeZone = "2021-08-19T17:30-07:00[UTC]"; -const result9 = instance.toString({ timeZone }); -assert.sameValue(result9.substr(-6), "+00:00", "date-time + offset + IANA annotation is the offset time zone"); -const result10 = instance.toString({ timeZone: { timeZone } }); -assert.sameValue(result10.substr(-6), "+00:00", "date-time + offset + IANA annotation is the offset time zone (string in property bag)"); +const result5 = instance.toString({ timeZone }); +assert.sameValue(result5.substr(-6), "+00:00", "date-time + offset + IANA annotation is the offset time zone"); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toString/timezone-string-leap-second.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toString/timezone-string-leap-second.js index 72e339139405..fd64b06af753 100644 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toString/timezone-string-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toString/timezone-string-leap-second.js @@ -10,11 +10,8 @@ features: [Temporal] const instance = new Temporal.Instant(0n); let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; -const result1 = instance.toString({ timeZone }); -assert.sameValue(result1.substr(-6), "+00:00", "leap second is a valid ISO string for TimeZone"); -const result2 = instance.toString({ timeZone: { timeZone } }); -assert.sameValue(result2.substr(-6), "+00:00", "leap second is a valid ISO string for TimeZone (nested property)"); +const result = instance.toString({ timeZone }); +assert.sameValue(result.substr(-6), "+00:00", "leap second is a valid ISO string for TimeZone"); timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; assert.throws(RangeError, () => instance.toString({ timeZone }), "leap second in time zone name not valid"); -assert.throws(RangeError, () => instance.toString({ timeZone: { timeZone } }), "leap second in time zone name not valid (nested property)"); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toString/timezone-string-multiple-offsets.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toString/timezone-string-multiple-offsets.js index 9d118c093ecb..2b16120473f7 100644 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toString/timezone-string-multiple-offsets.js +++ b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toString/timezone-string-multiple-offsets.js @@ -10,7 +10,5 @@ features: [Temporal] const instance = new Temporal.Instant(0n); const timeZone = "2021-08-19T17:30:45.123456789+01:46[+01:45:30.987654321]"; -const result1 = instance.toString({ timeZone }); -assert.sameValue(result1.substr(-6), "+01:46", "Time zone string determined from offset"); -const result2 = instance.toString({ timeZone: { timeZone } }); -assert.sameValue(result2.substr(-6), "+01:46", "Time zone string determined from offset"); +const result = instance.toString({ timeZone }); +assert.sameValue(result.substr(-6), "+01:46", "Time zone string determined from offset"); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toString/timezone-string-year-zero.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toString/timezone-string-year-zero.js index c04a611c0704..9e8cfd9b7374 100644 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toString/timezone-string-year-zero.js +++ b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toString/timezone-string-year-zero.js @@ -18,9 +18,4 @@ invalidStrings.forEach((timeZone) => { () => instance.toString({ timeZone }), "reject minus zero as extended year" ); - assert.throws( - RangeError, - () => instance.toString({ timeZone: { timeZone } }), - "reject minus zero as extended year (nested property)" - ); }); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toString/timezone-string.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toString/timezone-string.js index 9c7ba8d863b2..9c6346a65cdb 100644 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toString/timezone-string.js +++ b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toString/timezone-string.js @@ -4,9 +4,27 @@ /*--- esid: sec-temporal.instant.prototype.tostring description: Time zone IDs are valid input for a time zone +includes: [temporalHelpers.js] features: [Temporal] ---*/ +const getPossibleInstantsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getPossibleInstantsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getPossibleInstantsFor should not be looked up"); + }, +}); +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + const instance = new Temporal.Instant(0n); const result1 = instance.toString({ timeZone: "UTC" }); @@ -14,3 +32,6 @@ assert.sameValue(result1.substr(-6), "+00:00", "Time zone created from string 'U const result2 = instance.toString({ timeZone: "-01:30" }); assert.sameValue(result2.substr(-6), "-01:30", "Time zone created from string '-01:30'"); + +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", getPossibleInstantsForOriginal); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toString/timezone-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toString/timezone-wrong-type.js index 699b279b8257..7ca0cc0a2d6d 100644 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toString/timezone-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toString/timezone-wrong-type.js @@ -18,22 +18,18 @@ const rangeErrorTests = [ [1, "number that doesn't convert to a valid ISO string"], [19761118, "number that would convert to a valid ISO string in other contexts"], [1n, "bigint"], - [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of rangeErrorTests) { assert.throws(RangeError, () => instance.toString({ timeZone }), `${description} does not convert to a valid ISO string`); - assert.throws(RangeError, () => instance.toString({ timeZone: { timeZone } }), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], + [{}, "object not implementing time zone protocol"], + [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of typeErrorTests) { assert.throws(TypeError, () => instance.toString({ timeZone }), `${description} is not a valid object and does not convert to a string`); - assert.throws(TypeError, () => instance.toString({ timeZone: { timeZone } }), `${description} is not a valid object and does not convert to a string (nested property)`); } - -const timeZone = undefined; -assert.throws(RangeError, () => instance.toString({ timeZone: { timeZone } }), `undefined is always a RangeError as nested property`); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toString/timezone.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toString/timezone.js index acf2219485d6..3a5735416567 100644 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toString/timezone.js +++ b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toString/timezone.js @@ -10,7 +10,9 @@ features: [Temporal] const actual = []; const expected = [ - "has timeZone.timeZone", + "has timeZone.getOffsetNanosecondsFor", + "has timeZone.getPossibleInstantsFor", + "has timeZone.id", "get timeZone.getOffsetNanosecondsFor", "call timeZone.getOffsetNanosecondsFor", "get timeZone.getOffsetNanosecondsFor", diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-case-insensitive.js index ed23625dab38..8b67bb69099c 100644 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-case-insensitive.js @@ -11,4 +11,4 @@ const instance = new Temporal.Instant(1_000_000_000_000_000_000n); const arg = "iSo8601"; const result = instance.toZonedDateTime({ calendar: arg, timeZone: "UTC" }); -assert.sameValue(result.calendar.id, "iso8601", "Calendar is case-insensitive"); +assert.sameValue(result.calendarId, "iso8601", "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 856a24f3bc7e..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,22 +0,0 @@ -// 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.tozoneddatetime -description: > - A Temporal.Calendar instance passed to toZonedDateTime() does not have its - 'calendar' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.Instant(1_000_000_000_000_000_000n); - -const arg = new Temporal.Calendar("iso8601"); -Object.defineProperty(arg, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -instance.toZonedDateTime({ calendar: arg, timeZone: "UTC" }); -instance.toZonedDateTime({ calendar: { calendar: arg }, timeZone: "UTC" }); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-number.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-number.js index b66e68c75c8c..21a496debea1 100644 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-number.js @@ -12,7 +12,7 @@ const instance = new Temporal.Instant(1_000_000_000_000_000_000n); const arg = 19761118; const result = instance.toZonedDateTime({ calendar: arg, timeZone: "UTC" }); -assert.sameValue(result.calendar.id, "iso8601", "19761118 is a valid ISO string for Calendar"); +assert.sameValue(result.calendarId, "iso8601", "19761118 is a valid ISO string for Calendar"); const numbers = [ 1, diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-string-leap-second.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-string-leap-second.js index 7264f33377f2..185517ed1a20 100644 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-string-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-string-leap-second.js @@ -9,18 +9,10 @@ features: [Temporal] const instance = new Temporal.Instant(1_000_000_000_000_000_000n); -let arg = "2016-12-31T23:59:60"; -const result1 = instance.toZonedDateTime({ calendar: arg, timeZone: "UTC" }); +const arg = "2016-12-31T23:59:60"; +const result = instance.toZonedDateTime({ calendar: arg, timeZone: "UTC" }); assert.sameValue( - result1.calendar.id, + result.calendarId, "iso8601", "leap second is a valid ISO string for Calendar" ); - -arg = { calendar: "2016-12-31T23:59:60" }; -const result2 = instance.toZonedDateTime({ calendar: arg, timeZone: "UTC" }); -assert.sameValue( - result2.calendar.id, - "iso8601", - "leap second is a valid ISO string for Calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-string.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-string.js index 6984994a4616..97ce4abd3be9 100644 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-string.js +++ b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-string.js @@ -12,4 +12,4 @@ const instance = new Temporal.Instant(1_000_000_000_000_000_000n); const arg = "iso8601"; const result = instance.toZonedDateTime({ calendar: arg, timeZone: "UTC" }); -assert.sameValue(result.calendar.id, "iso8601", `Calendar created from string "${arg}"`); +assert.sameValue(result.getISOFields().calendar, "iso8601", `Calendar created from string "${arg}"`); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-temporal-object.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-temporal-object.js index f75fc26bdda2..f43ba3ba35ed 100644 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-temporal-object.js +++ b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-temporal-object.js @@ -6,7 +6,7 @@ esid: sec-temporal.instant.prototype.tozoneddatetime description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots info: | sec-temporal-totemporalcalendar step 1.b: - b. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then + b. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then i. Return _temporalCalendarLike_.[[Calendar]]. includes: [compareArray.js] features: [Temporal] @@ -14,12 +14,11 @@ features: [Temporal] const plainDate = new Temporal.PlainDate(2000, 5, 2); const plainDateTime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); -const plainTime = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); const plainMonthDay = new Temporal.PlainMonthDay(5, 2); const plainYearMonth = new Temporal.PlainYearMonth(2000, 5); const zonedDateTime = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); -[plainDate, plainDateTime, plainTime, plainMonthDay, plainYearMonth, zonedDateTime].forEach((arg) => { +[plainDate, plainDateTime, plainMonthDay, plainYearMonth, zonedDateTime].forEach((arg) => { const actual = []; const expected = []; @@ -34,7 +33,7 @@ const zonedDateTime = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UT const instance = new Temporal.Instant(1_000_000_000_000_000_000n); const result = instance.toZonedDateTime({ calendar: arg, timeZone: "UTC" }); - assert.sameValue(result.calendar, calendar, "Temporal object coerced to calendar"); + assert.sameValue(result.getISOFields().calendar, calendar, "Temporal object coerced to calendar"); assert.compareArray(actual, expected, "calendar getter not called"); }); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-wrong-type.js index 24c2a13b607c..515f292b0ea3 100644 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-wrong-type.js @@ -17,19 +17,19 @@ const rangeErrorTests = [ ["", "empty string"], [1, "number that doesn't convert to a valid ISO string"], [1n, "bigint"], - [new Temporal.TimeZone("UTC"), "time zone instance"], ]; for (const [arg, description] of rangeErrorTests) { assert.throws(RangeError, () => instance.toZonedDateTime({ calendar: arg, timeZone: "UTC" }), `${description} does not convert to a valid ISO string`); - assert.throws(RangeError, () => instance.toZonedDateTime({ calendar: { calendar: arg }, timeZone: "UTC" }), `${description} does not convert to a valid ISO string (in property bag)`); } const typeErrorTests = [ [Symbol(), "symbol"], + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], ]; for (const [arg, description] of typeErrorTests) { assert.throws(TypeError, () => instance.toZonedDateTime({ calendar: arg, timeZone: "UTC" }), `${description} is not a valid object and does not convert to a string`); - assert.throws(TypeError, () => instance.toZonedDateTime({ calendar: { calendar: arg }, timeZone: "UTC" }), `${description} is not a valid object and does not convert to a string (in property bag)`); } diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/plain-custom-timezone.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/plain-custom-timezone.js index be9aee89929d..6e5b78892281 100644 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/plain-custom-timezone.js +++ b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/plain-custom-timezone.js @@ -10,7 +10,9 @@ features: [Temporal] const actual = []; const expected = [ - "has timeZone.timeZone", + "has timeZone.getOffsetNanosecondsFor", + "has timeZone.getPossibleInstantsFor", + "has timeZone.id", ]; const instant = Temporal.Instant.from("1975-02-02T14:25:36.123456789Z"); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-case-insensitive.js index 9dee0af7d3d9..c7a0dc6d561a 100644 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-case-insensitive.js @@ -7,8 +7,8 @@ description: Time zone names are case insensitive features: [Temporal] ---*/ -const instance = new Temporal.Instant(0n); +const instance = new Temporal.Instant(0n); const timeZone = 'uTc'; const result = instance.toZonedDateTime({ timeZone, calendar: "iso8601" }); -assert.sameValue(result.timeZone.id, 'UTC', `Time zone created from string "${timeZone}"`); +assert.sameValue(result.timeZoneId, 'UTC', `Time zone created from string "${timeZone}"`); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-instance-does-not-get-timeZone-property.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-instance-does-not-get-timeZone-property.js deleted file mode 100644 index 9d171db011a8..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-instance-does-not-get-timeZone-property.js +++ /dev/null @@ -1,22 +0,0 @@ -// 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.tozoneddatetime -description: > - A Temporal.TimeZone instance passed to toZonedDateTime() does not have its - 'timeZone' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.Instant(0n); - -const timeZone = new Temporal.TimeZone("UTC"); -Object.defineProperty(timeZone, "timeZone", { - get() { - throw new Test262Error("timeZone.timeZone should not be accessed"); - }, -}); - -instance.toZonedDateTime({ timeZone, calendar: "iso8601" }); -instance.toZonedDateTime({ timeZone: { timeZone }, calendar: "iso8601" }); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-string-datetime.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-string-datetime.js index d9ca41702e8a..db6dcd0569aa 100644 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-string-datetime.js +++ b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-string-datetime.js @@ -11,34 +11,23 @@ const instance = new Temporal.Instant(0n); let timeZone = "2021-08-19T17:30"; assert.throws(RangeError, () => instance.toZonedDateTime({ timeZone, calendar: "iso8601" }), "bare date-time string is not a time zone"); -assert.throws(RangeError, () => instance.toZonedDateTime({ timeZone: { timeZone }, calendar: "iso8601" }), "bare date-time string is not a time zone"); timeZone = "2021-08-19T17:30Z"; const result1 = instance.toZonedDateTime({ timeZone, calendar: "iso8601" }); -assert.sameValue(result1.timeZone.id, "UTC", "date-time + Z is UTC time zone"); -const result2 = instance.toZonedDateTime({ timeZone: { timeZone }, calendar: "iso8601" }); -assert.sameValue(result2.timeZone.id, "UTC", "date-time + Z is UTC time zone (string in property bag)"); +assert.sameValue(result1.timeZoneId, "UTC", "date-time + Z is UTC time zone"); timeZone = "2021-08-19T17:30-07:00"; -const result3 = instance.toZonedDateTime({ timeZone, calendar: "iso8601" }); -assert.sameValue(result3.timeZone.id, "-07:00", "date-time + offset is the offset time zone"); -const result4 = instance.toZonedDateTime({ timeZone: { timeZone }, calendar: "iso8601" }); -assert.sameValue(result4.timeZone.id, "-07:00", "date-time + offset is the offset time zone (string in property bag)"); +const result2 = instance.toZonedDateTime({ timeZone, calendar: "iso8601" }); +assert.sameValue(result2.timeZoneId, "-07:00", "date-time + offset is the offset time zone"); timeZone = "2021-08-19T17:30[UTC]"; -const result5 = instance.toZonedDateTime({ timeZone, calendar: "iso8601" }); -assert.sameValue(result5.timeZone.id, "UTC", "date-time + IANA annotation is the IANA time zone"); -const result6 = instance.toZonedDateTime({ timeZone: { timeZone }, calendar: "iso8601" }); -assert.sameValue(result6.timeZone.id, "UTC", "date-time + IANA annotation is the IANA time zone (string in property bag)"); +const result3 = instance.toZonedDateTime({ timeZone, calendar: "iso8601" }); +assert.sameValue(result3.timeZoneId, "UTC", "date-time + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30Z[UTC]"; -const result7 = instance.toZonedDateTime({ timeZone, calendar: "iso8601" }); -assert.sameValue(result7.timeZone.id, "UTC", "date-time + Z + IANA annotation is the IANA time zone"); -const result8 = instance.toZonedDateTime({ timeZone: { timeZone }, calendar: "iso8601" }); -assert.sameValue(result8.timeZone.id, "UTC", "date-time + Z + IANA annotation is the IANA time zone (string in property bag)"); +const result4 = instance.toZonedDateTime({ timeZone, calendar: "iso8601" }); +assert.sameValue(result4.timeZoneId, "UTC", "date-time + Z + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30-07:00[UTC]"; -const result9 = instance.toZonedDateTime({ timeZone, calendar: "iso8601" }); -assert.sameValue(result9.timeZone.id, "UTC", "date-time + offset + IANA annotation is the IANA time zone"); -const result10 = instance.toZonedDateTime({ timeZone: { timeZone }, calendar: "iso8601" }); -assert.sameValue(result10.timeZone.id, "UTC", "date-time + offset + IANA annotation is the IANA time zone (string in property bag)"); +const result5 = instance.toZonedDateTime({ timeZone, calendar: "iso8601" }); +assert.sameValue(result5.timeZoneId, "UTC", "date-time + offset + IANA annotation is the IANA time zone"); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-string-leap-second.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-string-leap-second.js index b3a25f04a9be..fd7e6b68ad25 100644 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-string-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-string-leap-second.js @@ -10,11 +10,8 @@ features: [Temporal] const instance = new Temporal.Instant(0n); let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; -const result1 = instance.toZonedDateTime({ timeZone, calendar: "iso8601" }); -assert.sameValue(result1.timeZone.id, "UTC", "leap second is a valid ISO string for TimeZone"); -const result2 = instance.toZonedDateTime({ timeZone: { timeZone }, calendar: "iso8601" }); -assert.sameValue(result2.timeZone.id, "UTC", "leap second is a valid ISO string for TimeZone (nested property)"); +const result = instance.toZonedDateTime({ timeZone, calendar: "iso8601" }); +assert.sameValue(result.timeZoneId, "UTC", "leap second is a valid ISO string for TimeZone"); timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; assert.throws(RangeError, () => instance.toZonedDateTime({ timeZone, calendar: "iso8601" }), "leap second in time zone name not valid"); -assert.throws(RangeError, () => instance.toZonedDateTime({ timeZone: { timeZone }, calendar: "iso8601" }), "leap second in time zone name not valid (nested property)"); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-string-multiple-offsets.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-string-multiple-offsets.js index 793bbe898892..ec9250d56c42 100644 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-string-multiple-offsets.js +++ b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-string-multiple-offsets.js @@ -10,7 +10,5 @@ features: [Temporal] const instance = new Temporal.Instant(0n); const timeZone = "2021-08-19T17:30:45.123456789+01:46[+01:45:30.987654321]"; -const result1 = instance.toZonedDateTime({ timeZone, calendar: "iso8601" }); -assert.sameValue(result1.timeZone.id, "+01:45:30.987654321", "Time zone string determined from bracket name"); -const result2 = instance.toZonedDateTime({ timeZone: { timeZone }, calendar: "iso8601" }); -assert.sameValue(result2.timeZone.id, "+01:45:30.987654321", "Time zone string determined from bracket name"); +const result = instance.toZonedDateTime({ timeZone, calendar: "iso8601" }); +assert.sameValue(result.timeZoneId, "+01:45:30.987654321", "Time zone string determined from bracket name"); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-string-year-zero.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-string-year-zero.js index 841a1bcb3d20..c4ed2917f20f 100644 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-string-year-zero.js +++ b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-string-year-zero.js @@ -18,9 +18,4 @@ invalidStrings.forEach((timeZone) => { () => instance.toZonedDateTime({ timeZone, calendar: "iso8601" }), "reject minus zero as extended year" ); - assert.throws( - RangeError, - () => instance.toZonedDateTime({ timeZone: { timeZone }, calendar: "iso8601" }), - "reject minus zero as extended year (nested property)" - ); }); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-string.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-string.js index 57f8c34c014e..9893e1fa8284 100644 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-string.js +++ b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-string.js @@ -4,12 +4,33 @@ /*--- esid: sec-temporal.instant.prototype.tozoneddatetime description: Time zone IDs are valid input for a time zone +includes: [temporalHelpers.js] features: [Temporal] ---*/ +const getPossibleInstantsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getPossibleInstantsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getPossibleInstantsFor should not be looked up"); + }, +}); +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + const instance = new Temporal.Instant(0n); ["UTC", "+01:30"].forEach((timeZone) => { const result = instance.toZonedDateTime({ timeZone, calendar: "iso8601" }); - assert.sameValue(result.timeZone.id, timeZone, `Time zone created from string "${timeZone}"`); + assert.sameValue(result.getISOFields().timeZone, timeZone, `time zone slot should store string "${timeZone}"`); }); + +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", getPossibleInstantsForOriginal); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-wrong-type.js index 8f5f4d049473..0b3dd555e864 100644 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-wrong-type.js @@ -18,22 +18,18 @@ const rangeErrorTests = [ [1, "number that doesn't convert to a valid ISO string"], [19761118, "number that would convert to a valid ISO string in other contexts"], [1n, "bigint"], - [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of rangeErrorTests) { assert.throws(RangeError, () => instance.toZonedDateTime({ timeZone, calendar: "iso8601" }), `${description} does not convert to a valid ISO string`); - assert.throws(RangeError, () => instance.toZonedDateTime({ timeZone: { timeZone }, calendar: "iso8601" }), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], + [{}, "object not implementing time zone protocol"], + [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of typeErrorTests) { assert.throws(TypeError, () => instance.toZonedDateTime({ timeZone, calendar: "iso8601" }), `${description} is not a valid object and does not convert to a string`); - assert.throws(TypeError, () => instance.toZonedDateTime({ timeZone: { timeZone }, calendar: "iso8601" }), `${description} is not a valid object and does not convert to a string (nested property)`); } - -const timeZone = undefined; -assert.throws(RangeError, () => instance.toZonedDateTime({ timeZone: { timeZone }, calendar: "iso8601" }), `undefined is always a RangeError as nested property`); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/calendar-is-builtin.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/calendar-is-builtin.js new file mode 100644 index 000000000000..662eaedb35cb --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/calendar-is-builtin.js @@ -0,0 +1,13 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.tozoneddatetimeiso +description: > + toZonedDateTimeISO() results in a ZonedDateTime with builtin ISO calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Instant(0n); +const result = instance.toZonedDateTimeISO("UTC"); +assert.sameValue(result.getISOFields().calendar, "iso8601", "calendar slot stores a string"); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-case-insensitive.js index ab37a3564cff..7bda964b3f10 100644 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-case-insensitive.js @@ -7,8 +7,8 @@ description: Time zone names are case insensitive features: [Temporal] ---*/ -const instance = new Temporal.Instant(0n); +const instance = new Temporal.Instant(0n); const timeZone = 'uTc'; const result = instance.toZonedDateTimeISO(timeZone); -assert.sameValue(result.timeZone.id, 'UTC', `Time zone created from string "${timeZone}"`); +assert.sameValue(result.timeZoneId, 'UTC', `Time zone created from string "${timeZone}"`); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-instance-does-not-get-timeZone-property.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-instance-does-not-get-timeZone-property.js deleted file mode 100644 index 0753643e2a27..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-instance-does-not-get-timeZone-property.js +++ /dev/null @@ -1,22 +0,0 @@ -// 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.tozoneddatetimeiso -description: > - A Temporal.TimeZone instance passed to toZonedDateTimeISO() does not have its - 'timeZone' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.Instant(0n); - -const timeZone = new Temporal.TimeZone("UTC"); -Object.defineProperty(timeZone, "timeZone", { - get() { - throw new Test262Error("timeZone.timeZone should not be accessed"); - }, -}); - -instance.toZonedDateTimeISO(timeZone); -instance.toZonedDateTimeISO({ timeZone }); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-string-datetime.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-string-datetime.js index 87abc3340169..c5cb987c462f 100644 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-string-datetime.js +++ b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-string-datetime.js @@ -11,34 +11,23 @@ const instance = new Temporal.Instant(0n); let timeZone = "2021-08-19T17:30"; assert.throws(RangeError, () => instance.toZonedDateTimeISO(timeZone), "bare date-time string is not a time zone"); -assert.throws(RangeError, () => instance.toZonedDateTimeISO({ timeZone }), "bare date-time string is not a time zone"); timeZone = "2021-08-19T17:30Z"; const result1 = instance.toZonedDateTimeISO(timeZone); -assert.sameValue(result1.timeZone.id, "UTC", "date-time + Z is UTC time zone"); -const result2 = instance.toZonedDateTimeISO({ timeZone }); -assert.sameValue(result2.timeZone.id, "UTC", "date-time + Z is UTC time zone (string in property bag)"); +assert.sameValue(result1.timeZoneId, "UTC", "date-time + Z is UTC time zone"); timeZone = "2021-08-19T17:30-07:00"; -const result3 = instance.toZonedDateTimeISO(timeZone); -assert.sameValue(result3.timeZone.id, "-07:00", "date-time + offset is the offset time zone"); -const result4 = instance.toZonedDateTimeISO({ timeZone }); -assert.sameValue(result4.timeZone.id, "-07:00", "date-time + offset is the offset time zone (string in property bag)"); +const result2 = instance.toZonedDateTimeISO(timeZone); +assert.sameValue(result2.timeZoneId, "-07:00", "date-time + offset is the offset time zone"); timeZone = "2021-08-19T17:30[UTC]"; -const result5 = instance.toZonedDateTimeISO(timeZone); -assert.sameValue(result5.timeZone.id, "UTC", "date-time + IANA annotation is the IANA time zone"); -const result6 = instance.toZonedDateTimeISO({ timeZone }); -assert.sameValue(result6.timeZone.id, "UTC", "date-time + IANA annotation is the IANA time zone (string in property bag)"); +const result3 = instance.toZonedDateTimeISO(timeZone); +assert.sameValue(result3.timeZoneId, "UTC", "date-time + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30Z[UTC]"; -const result7 = instance.toZonedDateTimeISO(timeZone); -assert.sameValue(result7.timeZone.id, "UTC", "date-time + Z + IANA annotation is the IANA time zone"); -const result8 = instance.toZonedDateTimeISO({ timeZone }); -assert.sameValue(result8.timeZone.id, "UTC", "date-time + Z + IANA annotation is the IANA time zone (string in property bag)"); +const result4 = instance.toZonedDateTimeISO(timeZone); +assert.sameValue(result4.timeZoneId, "UTC", "date-time + Z + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30-07:00[UTC]"; -const result9 = instance.toZonedDateTimeISO(timeZone); -assert.sameValue(result9.timeZone.id, "UTC", "date-time + offset + IANA annotation is the IANA time zone"); -const result10 = instance.toZonedDateTimeISO({ timeZone }); -assert.sameValue(result10.timeZone.id, "UTC", "date-time + offset + IANA annotation is the IANA time zone (string in property bag)"); +const result5 = instance.toZonedDateTimeISO(timeZone); +assert.sameValue(result5.timeZoneId, "UTC", "date-time + offset + IANA annotation is the IANA time zone"); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-string-leap-second.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-string-leap-second.js index 46be8be647eb..460b4da173b9 100644 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-string-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-string-leap-second.js @@ -10,11 +10,8 @@ features: [Temporal] const instance = new Temporal.Instant(0n); let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; -const result1 = instance.toZonedDateTimeISO(timeZone); -assert.sameValue(result1.timeZone.id, "UTC", "leap second is a valid ISO string for TimeZone"); -const result2 = instance.toZonedDateTimeISO({ timeZone }); -assert.sameValue(result2.timeZone.id, "UTC", "leap second is a valid ISO string for TimeZone (nested property)"); +const result = instance.toZonedDateTimeISO(timeZone); +assert.sameValue(result.timeZoneId, "UTC", "leap second is a valid ISO string for TimeZone"); timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; assert.throws(RangeError, () => instance.toZonedDateTimeISO(timeZone), "leap second in time zone name not valid"); -assert.throws(RangeError, () => instance.toZonedDateTimeISO({ timeZone }), "leap second in time zone name not valid (nested property)"); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-string-multiple-offsets.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-string-multiple-offsets.js index 16ce94429cde..3fbfc4a12b67 100644 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-string-multiple-offsets.js +++ b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-string-multiple-offsets.js @@ -10,7 +10,5 @@ features: [Temporal] const instance = new Temporal.Instant(0n); const timeZone = "2021-08-19T17:30:45.123456789+01:46[+01:45:30.987654321]"; -const result1 = instance.toZonedDateTimeISO(timeZone); -assert.sameValue(result1.timeZone.id, "+01:45:30.987654321", "Time zone string determined from bracket name"); -const result2 = instance.toZonedDateTimeISO({ timeZone }); -assert.sameValue(result2.timeZone.id, "+01:45:30.987654321", "Time zone string determined from bracket name"); +const result = instance.toZonedDateTimeISO(timeZone); +assert.sameValue(result.timeZoneId, "+01:45:30.987654321", "Time zone string determined from bracket name"); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-string-year-zero.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-string-year-zero.js index a8a397ada44c..79113665ddf7 100644 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-string-year-zero.js +++ b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-string-year-zero.js @@ -18,9 +18,4 @@ invalidStrings.forEach((timeZone) => { () => instance.toZonedDateTimeISO(timeZone), "reject minus zero as extended year" ); - assert.throws( - RangeError, - () => instance.toZonedDateTimeISO({ timeZone }), - "reject minus zero as extended year (nested property)" - ); }); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-string.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-string.js index 2dbecc39d402..1c4d9b66c8cc 100644 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-string.js +++ b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-string.js @@ -4,12 +4,33 @@ /*--- esid: sec-temporal.instant.prototype.tozoneddatetimeiso description: Time zone IDs are valid input for a time zone +includes: [temporalHelpers.js] features: [Temporal] ---*/ +const getPossibleInstantsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getPossibleInstantsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getPossibleInstantsFor should not be looked up"); + }, +}); +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + const instance = new Temporal.Instant(0n); ["UTC", "+01:30"].forEach((timeZone) => { const result = instance.toZonedDateTimeISO(timeZone); - assert.sameValue(result.timeZone.id, timeZone, `Time zone created from string "${timeZone}"`); + assert.sameValue(result.getISOFields().timeZone, timeZone, `time zone slot should store string "${timeZone}"`); }); + +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", getPossibleInstantsForOriginal); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-wrong-type.js index fbe21dfed23f..7f09d939a8e5 100644 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-wrong-type.js @@ -18,22 +18,18 @@ const rangeErrorTests = [ [1, "number that doesn't convert to a valid ISO string"], [19761118, "number that would convert to a valid ISO string in other contexts"], [1n, "bigint"], - [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of rangeErrorTests) { assert.throws(RangeError, () => instance.toZonedDateTimeISO(timeZone), `${description} does not convert to a valid ISO string`); - assert.throws(RangeError, () => instance.toZonedDateTimeISO({ timeZone }), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], + [{}, "object not implementing time zone protocol"], + [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of typeErrorTests) { assert.throws(TypeError, () => instance.toZonedDateTimeISO(timeZone), `${description} is not a valid object and does not convert to a string`); - assert.throws(TypeError, () => instance.toZonedDateTimeISO({ timeZone }), `${description} is not a valid object and does not convert to a string (nested property)`); } - -const timeZone = undefined; -assert.throws(RangeError, () => instance.toZonedDateTimeISO({ timeZone }), `undefined is always a RangeError as nested property`); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/until/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/until/argument-string-calendar-annotation.js index 7887c615132a..f6b6e409789f 100644 --- a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/until/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/until/argument-string-calendar-annotation.js @@ -16,7 +16,6 @@ const tests = [ ["1970-01-01T00:00Z[u-ca=discord]", "annotation is ignored"], ["1970-01-01T00:00Z[!u-ca=discord]", "annotation with ! is ignored"], ["1970-01-01T00:00Z[u-ca=iso8601][u-ca=discord]", "two annotations are ignored"], - ["1970-01-01T00:00Z[u-ca=iso8601][!u-ca=discord]", "two annotations are ignored even with !"], ]; const instance = new Temporal.Instant(0n); diff --git a/JSTests/test262/test/built-ins/Temporal/Instant/prototype/until/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/until/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..1990e24e9203 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Instant/prototype/until/argument-string-multiple-calendar.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 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: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01T00:00Z[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00Z[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00Z[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00Z[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.Instant(0n); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.until(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDate/calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDate/calendar-case-insensitive.js index 2654459f2239..aaefeff6cc29 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDate/calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDate/calendar-case-insensitive.js @@ -10,4 +10,4 @@ features: [Temporal] const arg = "iSo8601"; const result = Temporal.Now.plainDate(arg); -assert.sameValue(result.calendar.id, "iso8601", "Calendar is case-insensitive"); +assert.sameValue(result.calendarId, "iso8601", "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDate/calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDate/calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index c8e606ecca57..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDate/calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,20 +0,0 @@ -// 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.now.plaindate -description: > - A Temporal.Calendar instance passed to plainDate() does not have its - 'calendar' property observably checked -features: [Temporal] ----*/ - -const arg = new Temporal.Calendar("iso8601"); -Object.defineProperty(arg, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -Temporal.Now.plainDate(arg); -Temporal.Now.plainDate({ calendar: arg }); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDate/calendar-number.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDate/calendar-number.js index 8586672bdd80..a82a0f8c072a 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDate/calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDate/calendar-number.js @@ -10,7 +10,7 @@ features: [Temporal] const arg = 19761118; const result = Temporal.Now.plainDate(arg); -assert.sameValue(result.calendar.id, "iso8601", "19761118 is a valid ISO string for Calendar"); +assert.sameValue(result.calendarId, "iso8601", "19761118 is a valid ISO string for Calendar"); const numbers = [ 1, diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDate/calendar-string-leap-second.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDate/calendar-string-leap-second.js index 25c6a9bd3b3d..ba9192a4d676 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDate/calendar-string-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDate/calendar-string-leap-second.js @@ -7,18 +7,10 @@ description: Leap second is a valid ISO string for Calendar features: [Temporal] ---*/ -let arg = "2016-12-31T23:59:60"; -const result1 = Temporal.Now.plainDate(arg); +const arg = "2016-12-31T23:59:60"; +const result = Temporal.Now.plainDate(arg); assert.sameValue( - result1.calendar.id, + result.calendarId, "iso8601", "leap second is a valid ISO string for Calendar" ); - -arg = { calendar: "2016-12-31T23:59:60" }; -const result2 = Temporal.Now.plainDate(arg); -assert.sameValue( - result2.calendar.id, - "iso8601", - "leap second is a valid ISO string for Calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDate/calendar-string.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDate/calendar-string.js index 5e411bfd351c..e6d247a547be 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDate/calendar-string.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDate/calendar-string.js @@ -10,4 +10,4 @@ features: [Temporal] const arg = "iso8601"; const result = Temporal.Now.plainDate(arg); -assert.sameValue(result.calendar.id, "iso8601", `Calendar created from string "${arg}"`); +assert.sameValue(result.getISOFields().calendar, "iso8601", `Calendar created from string "${arg}"`); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDate/calendar-temporal-object.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDate/calendar-temporal-object.js index 3d749f2989ee..c116e5e332a1 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDate/calendar-temporal-object.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDate/calendar-temporal-object.js @@ -6,7 +6,7 @@ esid: sec-temporal.now.plaindate description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots info: | sec-temporal-totemporalcalendar step 1.b: - b. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then + b. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then i. Return _temporalCalendarLike_.[[Calendar]]. includes: [compareArray.js] features: [Temporal] @@ -14,12 +14,11 @@ features: [Temporal] const plainDate = new Temporal.PlainDate(2000, 5, 2); const plainDateTime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); -const plainTime = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); const plainMonthDay = new Temporal.PlainMonthDay(5, 2); const plainYearMonth = new Temporal.PlainYearMonth(2000, 5); const zonedDateTime = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); -[plainDate, plainDateTime, plainTime, plainMonthDay, plainYearMonth, zonedDateTime].forEach((arg) => { +[plainDate, plainDateTime, plainMonthDay, plainYearMonth, zonedDateTime].forEach((arg) => { const actual = []; const expected = []; @@ -33,7 +32,7 @@ const zonedDateTime = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UT }); const result = Temporal.Now.plainDate(arg); - assert.sameValue(result.calendar, calendar, "Temporal object coerced to calendar"); + assert.sameValue(result.getISOFields().calendar, calendar, "Temporal object coerced to calendar"); assert.compareArray(actual, expected, "calendar getter not called"); }); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDate/calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDate/calendar-wrong-type.js index 7aa62022e0b7..e45fa6a81b5d 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDate/calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDate/calendar-wrong-type.js @@ -15,19 +15,19 @@ const rangeErrorTests = [ ["", "empty string"], [1, "number that doesn't convert to a valid ISO string"], [1n, "bigint"], - [new Temporal.TimeZone("UTC"), "time zone instance"], ]; for (const [arg, description] of rangeErrorTests) { assert.throws(RangeError, () => Temporal.Now.plainDate(arg), `${description} does not convert to a valid ISO string`); - assert.throws(RangeError, () => Temporal.Now.plainDate({ calendar: arg }), `${description} does not convert to a valid ISO string (in property bag)`); } const typeErrorTests = [ [Symbol(), "symbol"], + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], ]; for (const [arg, description] of typeErrorTests) { assert.throws(TypeError, () => Temporal.Now.plainDate(arg), `${description} is not a valid object and does not convert to a string`); - assert.throws(TypeError, () => Temporal.Now.plainDate({ calendar: arg }), `${description} is not a valid object and does not convert to a string (in property bag)`); } diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDate/timezone-instance-does-not-get-timeZone-property.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDate/timezone-instance-does-not-get-timeZone-property.js deleted file mode 100644 index 36bf9b2cb17d..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDate/timezone-instance-does-not-get-timeZone-property.js +++ /dev/null @@ -1,20 +0,0 @@ -// 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.now.plaindate -description: > - A Temporal.TimeZone instance passed to plainDate() does not have its - 'timeZone' property observably checked -features: [Temporal] ----*/ - -const timeZone = new Temporal.TimeZone("UTC"); -Object.defineProperty(timeZone, "timeZone", { - get() { - throw new Test262Error("timeZone.timeZone should not be accessed"); - }, -}); - -Temporal.Now.plainDate("iso8601", timeZone); -Temporal.Now.plainDate("iso8601", { timeZone }); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDate/timezone-string-datetime.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDate/timezone-string-datetime.js index 2118b8a51ae0..0e8d22bd9aac 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDate/timezone-string-datetime.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDate/timezone-string-datetime.js @@ -9,7 +9,6 @@ features: [Temporal] let timeZone = "2021-08-19T17:30"; assert.throws(RangeError, () => Temporal.Now.plainDate("iso8601", timeZone), "bare date-time string is not a time zone"); -assert.throws(RangeError, () => Temporal.Now.plainDate("iso8601", { timeZone }), "bare date-time string is not a time zone"); // The following are all valid strings so should not throw: @@ -30,5 +29,4 @@ assert.throws(RangeError, () => Temporal.Now.plainDate("iso8601", { timeZone }), "2021-08-19T1730-0700[UTC]", ].forEach((timeZone) => { Temporal.Now.plainDate("iso8601", timeZone); - Temporal.Now.plainDate("iso8601", { timeZone }); }); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDate/timezone-string-leap-second.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDate/timezone-string-leap-second.js index 93db0e2f4cc6..febcb8a08f43 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDate/timezone-string-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDate/timezone-string-leap-second.js @@ -9,12 +9,10 @@ features: [Temporal] let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; -// A string with a leap second is a valid ISO string, so the following two -// operations should not throw +// A string with a leap second is a valid ISO string, so the following +// operation should not throw Temporal.Now.plainDate("iso8601", timeZone); -Temporal.Now.plainDate("iso8601", { timeZone }); timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; assert.throws(RangeError, () => Temporal.Now.plainDate("iso8601", timeZone), "leap second in time zone name not valid"); -assert.throws(RangeError, () => Temporal.Now.plainDate("iso8601", { timeZone }), "leap second in time zone name not valid (nested property)"); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDate/timezone-string-year-zero.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDate/timezone-string-year-zero.js index 71bb7a11a7fc..501894916e88 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDate/timezone-string-year-zero.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDate/timezone-string-year-zero.js @@ -17,9 +17,4 @@ invalidStrings.forEach((timeZone) => { () => Temporal.Now.plainDate("iso8601", timeZone), "reject minus zero as extended year" ); - assert.throws( - RangeError, - () => Temporal.Now.plainDate("iso8601", { timeZone }), - "reject minus zero as extended year (nested property)" - ); }); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDate/timezone-string.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDate/timezone-string.js index 60aff45c345c..877d14dbd07e 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDate/timezone-string.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDate/timezone-string.js @@ -4,11 +4,32 @@ /*--- esid: sec-temporal.now.plaindate description: Time zone IDs are valid input for a time zone +includes: [temporalHelpers.js] features: [Temporal] ---*/ +const getPossibleInstantsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getPossibleInstantsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getPossibleInstantsFor should not be looked up"); + }, +}); +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + // The following are all valid strings so should not throw: ["UTC", "+01:00"].forEach((timeZone) => { Temporal.Now.plainDate("iso8601", timeZone); }); + +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", getPossibleInstantsForOriginal); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDate/timezone-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDate/timezone-wrong-type.js index 3319d2378a9c..18ec9b628e3c 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDate/timezone-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDate/timezone-wrong-type.js @@ -16,22 +16,18 @@ const rangeErrorTests = [ [1, "number that doesn't convert to a valid ISO string"], [19761118, "number that would convert to a valid ISO string in other contexts"], [1n, "bigint"], - [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of rangeErrorTests) { assert.throws(RangeError, () => Temporal.Now.plainDate("iso8601", timeZone), `${description} does not convert to a valid ISO string`); - assert.throws(RangeError, () => Temporal.Now.plainDate("iso8601", { timeZone }), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], + [{}, "object not implementing time zone protocol"], + [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of typeErrorTests) { assert.throws(TypeError, () => Temporal.Now.plainDate("iso8601", timeZone), `${description} is not a valid object and does not convert to a string`); - assert.throws(TypeError, () => Temporal.Now.plainDate("iso8601", { timeZone }), `${description} is not a valid object and does not convert to a string (nested property)`); } - -const timeZone = undefined; -assert.throws(RangeError, () => Temporal.Now.plainDate("iso8601", { timeZone }), `undefined is always a RangeError as nested property`); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDate/toPlainDate-override.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDate/toPlainDate-override.js index 3e76b5534b17..aa9a3ae32a9e 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDate/toPlainDate-override.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDate/toPlainDate-override.js @@ -10,7 +10,9 @@ features: [Temporal] const actual = []; const expected = [ - "has timeZone.timeZone", + "has timeZone.getOffsetNanosecondsFor", + "has timeZone.getPossibleInstantsFor", + "has timeZone.id", "get timeZone.getOffsetNanosecondsFor", "call timeZone.getOffsetNanosecondsFor", ]; diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateISO/return-value.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateISO/return-value.js index 705a410fbb41..511e51f7692d 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateISO/return-value.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDateISO/return-value.js @@ -9,4 +9,4 @@ features: [Temporal] const d = Temporal.Now.plainDateISO(); assert(d instanceof Temporal.PlainDate); -assert.sameValue(d.calendar.id, "iso8601"); +assert.sameValue(d.getISOFields().calendar, "iso8601", "calendar slot should store a string"); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateISO/timezone-instance-does-not-get-timeZone-property.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateISO/timezone-instance-does-not-get-timeZone-property.js deleted file mode 100644 index fdb608b647ea..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateISO/timezone-instance-does-not-get-timeZone-property.js +++ /dev/null @@ -1,20 +0,0 @@ -// 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.now.plaindateiso -description: > - A Temporal.TimeZone instance passed to plainDateISO() does not have its - 'timeZone' property observably checked -features: [Temporal] ----*/ - -const timeZone = new Temporal.TimeZone("UTC"); -Object.defineProperty(timeZone, "timeZone", { - get() { - throw new Test262Error("timeZone.timeZone should not be accessed"); - }, -}); - -Temporal.Now.plainDateISO(timeZone); -Temporal.Now.plainDateISO({ timeZone }); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateISO/timezone-string-datetime.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateISO/timezone-string-datetime.js index c964b704254f..d7cd7915dd66 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateISO/timezone-string-datetime.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDateISO/timezone-string-datetime.js @@ -9,7 +9,6 @@ features: [Temporal] let timeZone = "2021-08-19T17:30"; assert.throws(RangeError, () => Temporal.Now.plainDateISO(timeZone), "bare date-time string is not a time zone"); -assert.throws(RangeError, () => Temporal.Now.plainDateISO({ timeZone }), "bare date-time string is not a time zone"); // The following are all valid strings so should not throw: @@ -30,5 +29,4 @@ assert.throws(RangeError, () => Temporal.Now.plainDateISO({ timeZone }), "bare d "2021-08-19T1730-0700[UTC]", ].forEach((timeZone) => { Temporal.Now.plainDateISO(timeZone); - Temporal.Now.plainDateISO({ timeZone }); }); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateISO/timezone-string-leap-second.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateISO/timezone-string-leap-second.js index 54f01540c1cc..4d5288df5ee4 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateISO/timezone-string-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDateISO/timezone-string-leap-second.js @@ -9,12 +9,10 @@ features: [Temporal] let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; -// A string with a leap second is a valid ISO string, so the following two -// operations should not throw +// A string with a leap second is a valid ISO string, so the following +// operation should not throw Temporal.Now.plainDateISO(timeZone); -Temporal.Now.plainDateISO({ timeZone }); timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; assert.throws(RangeError, () => Temporal.Now.plainDateISO(timeZone), "leap second in time zone name not valid"); -assert.throws(RangeError, () => Temporal.Now.plainDateISO({ timeZone }), "leap second in time zone name not valid (nested property)"); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateISO/timezone-string-year-zero.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateISO/timezone-string-year-zero.js index 5a0c755aa70c..a2b11251b597 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateISO/timezone-string-year-zero.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDateISO/timezone-string-year-zero.js @@ -17,9 +17,4 @@ invalidStrings.forEach((timeZone) => { () => Temporal.Now.plainDateISO(timeZone), "reject minus zero as extended year" ); - assert.throws( - RangeError, - () => Temporal.Now.plainDateISO({ timeZone }), - "reject minus zero as extended year (nested property)" - ); }); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateISO/timezone-string.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateISO/timezone-string.js index d9a452e2dfa2..0062a04bac8b 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateISO/timezone-string.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDateISO/timezone-string.js @@ -4,11 +4,32 @@ /*--- esid: sec-temporal.now.plaindateiso description: Time zone IDs are valid input for a time zone +includes: [temporalHelpers.js] features: [Temporal] ---*/ +const getPossibleInstantsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getPossibleInstantsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getPossibleInstantsFor should not be looked up"); + }, +}); +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + // The following are all valid strings so should not throw: ["UTC", "+01:00"].forEach((timeZone) => { Temporal.Now.plainDateISO(timeZone); }); + +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", getPossibleInstantsForOriginal); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateISO/timezone-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateISO/timezone-wrong-type.js index bc6dace702af..1478b5303ab0 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateISO/timezone-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDateISO/timezone-wrong-type.js @@ -16,22 +16,18 @@ const rangeErrorTests = [ [1, "number that doesn't convert to a valid ISO string"], [19761118, "number that would convert to a valid ISO string in other contexts"], [1n, "bigint"], - [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of rangeErrorTests) { assert.throws(RangeError, () => Temporal.Now.plainDateISO(timeZone), `${description} does not convert to a valid ISO string`); - assert.throws(RangeError, () => Temporal.Now.plainDateISO({ timeZone }), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], + [{}, "object not implementing time zone protocol"], + [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of typeErrorTests) { assert.throws(TypeError, () => Temporal.Now.plainDateISO(timeZone), `${description} is not a valid object and does not convert to a string`); - assert.throws(TypeError, () => Temporal.Now.plainDateISO({ timeZone }), `${description} is not a valid object and does not convert to a string (nested property)`); } - -const timeZone = undefined; -assert.throws(RangeError, () => Temporal.Now.plainDateISO({ timeZone }), `undefined is always a RangeError as nested property`); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-case-insensitive.js index 18c553fd6c03..93e5a8f19792 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-case-insensitive.js @@ -10,4 +10,4 @@ features: [Temporal] const arg = "iSo8601"; const result = Temporal.Now.plainDateTime(arg); -assert.sameValue(result.calendar.id, "iso8601", "Calendar is case-insensitive"); +assert.sameValue(result.calendarId, "iso8601", "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-function.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-function.js index 7147a27575dd..e7c560d056bb 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-function.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-function.js @@ -9,12 +9,35 @@ features: [BigInt, Proxy, Temporal] const actual = []; const expected = [ - 'has timeZone.timeZone', + 'has timeZone.getOffsetNanosecondsFor', + 'has timeZone.getPossibleInstantsFor', + 'has timeZone.id', 'get timeZone.getOffsetNanosecondsFor', 'call timeZone.getOffsetNanosecondsFor' ]; const calendar = function() {}; +calendar.dateAdd = () => {}; +calendar.dateFromFields = () => {}; +calendar.dateUntil = () => {}; +calendar.day = () => {}; +calendar.dayOfWeek = () => {}; +calendar.dayOfYear = () => {}; +calendar.daysInMonth = () => {}; +calendar.daysInWeek = () => {}; +calendar.daysInYear = () => {}; +calendar.fields = () => {}; +calendar.id = "test-calendar"; +calendar.inLeapYear = () => {}; +calendar.mergeFields = () => {}; +calendar.month = () => {}; +calendar.monthCode = () => {}; +calendar.monthDayFromFields = () => {}; +calendar.monthsInYear = () => {}; +calendar.weekOfYear = () => {}; +calendar.year = () => {}; +calendar.yearMonthFromFields = () => {}; +calendar.yearOfWeek = () => {}; const timeZone = TemporalHelpers.timeZoneObserver(actual, "timeZone", { getOffsetNanosecondsFor(instant) { diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 3bddf244a13f..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,20 +0,0 @@ -// 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.now.plaindatetime -description: > - A Temporal.Calendar instance passed to plainDateTime() does not have its - 'calendar' property observably checked -features: [Temporal] ----*/ - -const arg = new Temporal.Calendar("iso8601"); -Object.defineProperty(arg, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -Temporal.Now.plainDateTime(arg); -Temporal.Now.plainDateTime({ calendar: arg }); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-number.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-number.js index 5d226c703ea1..57d2e7967281 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-number.js @@ -10,7 +10,7 @@ features: [Temporal] const arg = 19761118; const result = Temporal.Now.plainDateTime(arg); -assert.sameValue(result.calendar.id, "iso8601", "19761118 is a valid ISO string for Calendar"); +assert.sameValue(result.calendarId, "iso8601", "19761118 is a valid ISO string for Calendar"); const numbers = [ 1, diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-object-fail-call-tostring.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-object-fail-call-tostring.js deleted file mode 100644 index fbc15b4919a3..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-object-fail-call-tostring.js +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-temporal.now.plaindatetime -description: Forwards error thrown by invoking "toString" property -features: [Temporal] ----*/ - -var calendar = { - calendar: { - calendar: true, - toString: function() { - throw new Test262Error(); - }, - } -}; - -assert.throws(Test262Error, function() { - Temporal.Now.plainDateTime(calendar); -}, 'Temporal.Now.plainDateTime(calendar) throws a Test262Error exception'); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-object-fail-get-calendar.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-object-fail-get-calendar.js deleted file mode 100644 index 9f3a9b61b60a..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-object-fail-get-calendar.js +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-temporal.now.plaindatetime -description: Forwards error thrown by retrieving value of "calendar" property -features: [Temporal] ----*/ - -var calendar = { - get calendar() { - throw new Test262Error(); - }, -}; - -assert.throws(Test262Error, function() { - Temporal.Now.plainDateTime(calendar); -}, 'Temporal.Now.plainDateTime(calendar) throws a Test262Error exception'); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-object-fail-has-calendar.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-object-fail-has-calendar.js deleted file mode 100644 index f7d71b30b2b8..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-object-fail-has-calendar.js +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.now.plaindatetime -description: Forwards error thrown by checking presence of "calendar" property -features: [Proxy, Temporal] ----*/ - -var calendar = new Proxy({}, { - has: function(target, property) { - if (property === 'calendar') { - throw new Test262Error(); - } - }, -}); - -assert.throws(Test262Error, function() { - Temporal.Now.plainDateTime(calendar); -}, 'Temporal.Now.plainDateTime(calendar) throws a Test262Error exception'); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-object-fail-has-nested-calendar.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-object-fail-has-nested-calendar.js deleted file mode 100644 index e43ca5457ed3..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-object-fail-has-nested-calendar.js +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-temporal.now.plaindatetime -description: Forwards error thrown by checking presence of nested "calendar" property -features: [Proxy, Temporal] ----*/ - -var calendar = { - calendar: new Proxy({}, { - has: function(target, property) { - if (property === 'calendar') { - throw new Test262Error(); - } - }, - }) -}; - -assert.throws(Test262Error, function() { - Temporal.Now.plainDateTime(calendar); -}, 'Temporal.Now.plainDateTime(calendar) throws a Test262Error exception'); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-object.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-object.js index 6e1527edfbe2..15cbeec9bedf 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-object.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-object.js @@ -9,26 +9,33 @@ features: [Proxy, Temporal] ---*/ const actual = []; -const expectedWithout = [ - 'has calendar.calendar', - 'get calendar.calendar', - 'has nestedCalendar.calendar' +const expected = [ + "has calendar.dateAdd", + "has calendar.dateFromFields", + "has calendar.dateUntil", + "has calendar.day", + "has calendar.dayOfWeek", + "has calendar.dayOfYear", + "has calendar.daysInMonth", + "has calendar.daysInWeek", + "has calendar.daysInYear", + "has calendar.fields", + "has calendar.id", + "has calendar.inLeapYear", + "has calendar.mergeFields", + "has calendar.month", + "has calendar.monthCode", + "has calendar.monthDayFromFields", + "has calendar.monthsInYear", + "has calendar.weekOfYear", + "has calendar.year", + "has calendar.yearMonthFromFields", + "has calendar.yearOfWeek", ]; -const expectedWith = [ - 'has calendar.calendar', - 'get calendar.calendar', - 'has nestedCalendar.calendar', - 'get nestedCalendar[Symbol.toPrimitive]', - 'get nestedCalendar.toString', - 'call nestedCalendar.toString' -]; -const nestedCalendar = TemporalHelpers.calendarObserver(actual, "nestedCalendar", { - toString: "iso8601", -}); + const calendar = TemporalHelpers.calendarObserver(actual, "calendar", { toString: "iso8601", }); -calendar.calendar = nestedCalendar; Object.defineProperty(Temporal.Calendar, 'from', { get() { @@ -39,11 +46,4 @@ Object.defineProperty(Temporal.Calendar, 'from', { Temporal.Now.plainDateTime(calendar); -assert.compareArray(actual, expectedWithout, 'Observable interactions without `calendar` property'); - -actual.length = 0; -nestedCalendar.calendar = null; - -Temporal.Now.plainDateTime(calendar); - -assert.compareArray(actual, expectedWith, 'Observable interactions with `calendar` property'); +assert.compareArray(actual, expected, 'order of observable operations'); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-string-leap-second.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-string-leap-second.js index 98af04f8088f..352f33ae8403 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-string-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-string-leap-second.js @@ -7,18 +7,10 @@ description: Leap second is a valid ISO string for Calendar features: [Temporal] ---*/ -let arg = "2016-12-31T23:59:60"; -const result1 = Temporal.Now.plainDateTime(arg); +const arg = "2016-12-31T23:59:60"; +const result = Temporal.Now.plainDateTime(arg); assert.sameValue( - result1.calendar.id, + result.calendarId, "iso8601", "leap second is a valid ISO string for Calendar" ); - -arg = { calendar: "2016-12-31T23:59:60" }; -const result2 = Temporal.Now.plainDateTime(arg); -assert.sameValue( - result2.calendar.id, - "iso8601", - "leap second is a valid ISO string for Calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-string.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-string.js index 4a43867f5273..964c8148cdab 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-string.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-string.js @@ -10,4 +10,4 @@ features: [Temporal] const arg = "iso8601"; const result = Temporal.Now.plainDateTime(arg); -assert.sameValue(result.calendar.id, "iso8601", `Calendar created from string "${arg}"`); +assert.sameValue(result.getISOFields().calendar, "iso8601", `Calendar created from string "${arg}"`); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-temporal-object.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-temporal-object.js index 6a14b68dfcb6..54ee450dcc96 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-temporal-object.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-temporal-object.js @@ -6,7 +6,7 @@ esid: sec-temporal.now.plaindatetime description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots info: | sec-temporal-totemporalcalendar step 1.b: - b. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then + b. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then i. Return _temporalCalendarLike_.[[Calendar]]. includes: [compareArray.js] features: [Temporal] @@ -14,12 +14,11 @@ features: [Temporal] const plainDate = new Temporal.PlainDate(2000, 5, 2); const plainDateTime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); -const plainTime = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); const plainMonthDay = new Temporal.PlainMonthDay(5, 2); const plainYearMonth = new Temporal.PlainYearMonth(2000, 5); const zonedDateTime = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); -[plainDate, plainDateTime, plainTime, plainMonthDay, plainYearMonth, zonedDateTime].forEach((arg) => { +[plainDate, plainDateTime, plainMonthDay, plainYearMonth, zonedDateTime].forEach((arg) => { const actual = []; const expected = []; @@ -33,7 +32,7 @@ const zonedDateTime = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UT }); const result = Temporal.Now.plainDateTime(arg); - assert.sameValue(result.calendar, calendar, "Temporal object coerced to calendar"); + assert.sameValue(result.getISOFields().calendar, calendar, "Temporal object coerced to calendar"); assert.compareArray(actual, expected, "calendar getter not called"); }); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-wrong-type.js index 47a2e0ed18c5..aa561c82c5b9 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/calendar-wrong-type.js @@ -15,19 +15,19 @@ const rangeErrorTests = [ ["", "empty string"], [1, "number that doesn't convert to a valid ISO string"], [1n, "bigint"], - [new Temporal.TimeZone("UTC"), "time zone instance"], ]; for (const [arg, description] of rangeErrorTests) { assert.throws(RangeError, () => Temporal.Now.plainDateTime(arg), `${description} does not convert to a valid ISO string`); - assert.throws(RangeError, () => Temporal.Now.plainDateTime({ calendar: arg }), `${description} does not convert to a valid ISO string (in property bag)`); } const typeErrorTests = [ [Symbol(), "symbol"], + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], ]; for (const [arg, description] of typeErrorTests) { assert.throws(TypeError, () => Temporal.Now.plainDateTime(arg), `${description} is not a valid object and does not convert to a string`); - assert.throws(TypeError, () => Temporal.Now.plainDateTime({ calendar: arg }), `${description} is not a valid object and does not convert to a string (in property bag)`); } diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/return-value.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/return-value.js index 8ae9424be190..3ec75b7f237b 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/return-value.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/return-value.js @@ -8,6 +8,8 @@ features: [BigInt, Temporal] const calendar = Temporal.Calendar.from('iso8601'); const timeZone = { + id: 'Etc/Test', + getPossibleInstantsFor() { return []; }, getOffsetNanosecondsFor(instant) { return -Number(instant.epochNanoseconds % 86400000000000n); } diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-getoffsetnanosecondsfor-invocation.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-getoffsetnanosecondsfor-invocation.js index 5a24b0271d94..8e0266a54ae9 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-getoffsetnanosecondsfor-invocation.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-getoffsetnanosecondsfor-invocation.js @@ -8,6 +8,8 @@ features: [Temporal] var calls = []; var timeZone = { + id: 'Etc/Test', + getPossibleInstantsFor() { return []; }, getOffsetNanosecondsFor: function() { calls.push({ args: arguments, diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-getoffsetnanosecondsfor-not-a-number.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-getoffsetnanosecondsfor-not-a-number.js index 628bdea9330e..e8755f386f58 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-getoffsetnanosecondsfor-not-a-number.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-getoffsetnanosecondsfor-not-a-number.js @@ -21,7 +21,9 @@ for (const dateTime of invalidValues) { let callCount = 0; const timeZone = { - getOffsetNanosecondsFor(instant, calendar) { + id: 'Etc/Test', + getPossibleInstantsFor() { return []; }, + getOffsetNanosecondsFor() { callCount += 1; return dateTime; } diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-getoffsetnanosecondsfor-poisoned.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-getoffsetnanosecondsfor-poisoned.js index e46cecbf1445..a8649a046a6d 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-getoffsetnanosecondsfor-poisoned.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-getoffsetnanosecondsfor-poisoned.js @@ -7,6 +7,8 @@ features: [Temporal] ---*/ var timeZone = { + id: 'Etc/Test', + getPossibleInstantsFor() { return []; }, get getOffsetNanosecondsFor() { throw new Test262Error(); } diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-getoffsetnanosecondsfor-throws.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-getoffsetnanosecondsfor-throws.js index 3af6f00c4ab9..12ed043c9cff 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-getoffsetnanosecondsfor-throws.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-getoffsetnanosecondsfor-throws.js @@ -7,6 +7,8 @@ features: [Temporal] ---*/ var timeZone = { + id: 'Etc/Test', + getPossibleInstantsFor() { return []; }, getOffsetNanosecondsFor() { throw new Test262Error(); } diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-instance-does-not-get-timeZone-property.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-instance-does-not-get-timeZone-property.js deleted file mode 100644 index dcc4274edfa7..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-instance-does-not-get-timeZone-property.js +++ /dev/null @@ -1,20 +0,0 @@ -// 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.now.plaindatetime -description: > - A Temporal.TimeZone instance passed to plainDateTime() does not have its - 'timeZone' property observably checked -features: [Temporal] ----*/ - -const timeZone = new Temporal.TimeZone("UTC"); -Object.defineProperty(timeZone, "timeZone", { - get() { - throw new Test262Error("timeZone.timeZone should not be accessed"); - }, -}); - -Temporal.Now.plainDateTime("iso8601", timeZone); -Temporal.Now.plainDateTime("iso8601", { timeZone }); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-object-fail-call-tostring.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-object-fail-call-tostring.js deleted file mode 100644 index 8042f0e831ed..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-object-fail-call-tostring.js +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-temporal.now.plaindatetime -description: Forwards error thrown by invoking "toString" property -features: [Temporal] ----*/ - -var timeZone = { - timeZone: { - timeZone: true, - toString: function() { - throw new Test262Error(); - }, - } -}; - -assert.throws(Test262Error, function() { - Temporal.Now.plainDateTime("iso8601", timeZone); -}, 'Temporal.Now.plainDateTime("iso8601", timeZone) throws a Test262Error exception'); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-object-fail-get-timezone.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-object-fail-get-timezone.js deleted file mode 100644 index 88c56aee2a5b..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-object-fail-get-timezone.js +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-temporal.now.plaindatetime -description: Forwards error thrown by retrieving value of "timeZone" property -features: [Temporal] ----*/ - -var timeZone = { - get timeZone() { - throw new Test262Error(); - }, -}; - -assert.throws(Test262Error, function() { - Temporal.Now.plainDateTime("iso8601", timeZone); -}, 'Temporal.Now.plainDateTime("iso8601", timeZone) throws a Test262Error exception'); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-object-fail-has-nested-timezone.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-object-fail-has-nested-timezone.js deleted file mode 100644 index e7a0c0bc98f5..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-object-fail-has-nested-timezone.js +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-temporal.now.plaindatetime -description: Forwards error thrown by checking presence of nested "timeZone" property -features: [Proxy, Temporal] ----*/ - -var timeZone = { - timeZone: new Proxy({}, { - has: function(target, property) { - if (property === 'timeZone') { - throw new Test262Error(); - } - }, - }) -}; - -assert.throws(Test262Error, function() { - Temporal.Now.plainDateTime("iso8601", timeZone); -}, 'Temporal.Now.plainDateTime("iso8601", timeZone) throws a Test262Error exception'); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-object-fail-has-timezone.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-object-fail-has-timezone.js deleted file mode 100644 index 8ecbfc40b1da..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-object-fail-has-timezone.js +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-temporal.now.plaindatetime -description: Forwards error thrown by checking presence of "timeZone" property -features: [Proxy, Temporal] ----*/ - -var timeZone = new Proxy({}, { - has: function(target, property) { - if (property === 'timeZone') { - throw new Test262Error(); - } - }, -}); - -assert.throws(Test262Error, function() { - Temporal.Now.plainDateTime("iso8601", timeZone); -}, 'Temporal.Now.plainDateTime("iso8601", timeZone) throws a Test262Error exception'); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-object.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-object.js index 384f361087a2..ea8a25e32b8d 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-object.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-object.js @@ -9,25 +9,13 @@ features: [BigInt, Proxy, Temporal] const actual = []; const expected = [ - 'has timeZone.timeZone', - 'get timeZone.timeZone', - 'has nestedTimeZone.timeZone', - 'get nestedTimeZone.getOffsetNanosecondsFor', - 'call nestedTimeZone.getOffsetNanosecondsFor' + 'has timeZone.getOffsetNanosecondsFor', + 'has timeZone.getPossibleInstantsFor', + 'has timeZone.id', + 'get timeZone.getOffsetNanosecondsFor', + 'call timeZone.getOffsetNanosecondsFor' ]; -const nestedTimeZone = TemporalHelpers.timeZoneObserver(actual, "nestedTimeZone", { - getOffsetNanosecondsFor(instant) { - assert.sameValue( - instant instanceof Temporal.Instant, - true, - 'The result of evaluating (instant instanceof Temporal.Instant) is expected to be true' - ); - - return -Number(instant.epochNanoseconds % 86400000000000n); - } -}); - const timeZone = TemporalHelpers.timeZoneObserver(actual, "timeZone", { getOffsetNanosecondsFor(instant) { assert.sameValue( @@ -39,7 +27,6 @@ const timeZone = TemporalHelpers.timeZoneObserver(actual, "timeZone", { return -Number(instant.epochNanoseconds % 86400000000000n); } }); -timeZone.timeZone = nestedTimeZone; Object.defineProperty(Temporal.TimeZone, 'from', { get() { diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-string-datetime.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-string-datetime.js index 2bf41674f16c..3980f4a66fac 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-string-datetime.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-string-datetime.js @@ -9,7 +9,6 @@ features: [Temporal] let timeZone = "2021-08-19T17:30"; assert.throws(RangeError, () => Temporal.Now.plainDateTime("iso8601", timeZone), "bare date-time string is not a time zone"); -assert.throws(RangeError, () => Temporal.Now.plainDateTime("iso8601", { timeZone }), "bare date-time string is not a time zone"); // The following are all valid strings so should not throw: @@ -30,5 +29,4 @@ assert.throws(RangeError, () => Temporal.Now.plainDateTime("iso8601", { timeZone "2021-08-19T1730-0700[UTC]", ].forEach((timeZone) => { Temporal.Now.plainDateTime("iso8601", timeZone); - Temporal.Now.plainDateTime("iso8601", { timeZone }); }); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-string-leap-second.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-string-leap-second.js index e080f9aa857e..e3c5d0056d8e 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-string-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-string-leap-second.js @@ -9,12 +9,10 @@ features: [Temporal] let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; -// A string with a leap second is a valid ISO string, so the following two -// operations should not throw +// A string with a leap second is a valid ISO string, so the following +// operation should not throw Temporal.Now.plainDateTime("iso8601", timeZone); -Temporal.Now.plainDateTime("iso8601", { timeZone }); timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; assert.throws(RangeError, () => Temporal.Now.plainDateTime("iso8601", timeZone), "leap second in time zone name not valid"); -assert.throws(RangeError, () => Temporal.Now.plainDateTime("iso8601", { timeZone }), "leap second in time zone name not valid (nested property)"); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-string-year-zero.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-string-year-zero.js index 32c6a023c7f1..aef3cec297f1 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-string-year-zero.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-string-year-zero.js @@ -17,9 +17,4 @@ invalidStrings.forEach((timeZone) => { () => Temporal.Now.plainDateTime("iso8601", timeZone), "reject minus zero as extended year" ); - assert.throws( - RangeError, - () => Temporal.Now.plainDateTime("iso8601", { timeZone }), - "reject minus zero as extended year (nested property)" - ); }); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-string.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-string.js index 1b4c0d10ec3b..23420d4cd19e 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-string.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-string.js @@ -4,11 +4,32 @@ /*--- esid: sec-temporal.now.plaindatetime description: Time zone IDs are valid input for a time zone +includes: [temporalHelpers.js] features: [Temporal] ---*/ +const getPossibleInstantsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getPossibleInstantsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getPossibleInstantsFor should not be looked up"); + }, +}); +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + // The following are all valid strings so should not throw: ["UTC", "+01:00"].forEach((timeZone) => { Temporal.Now.plainDateTime("iso8601", timeZone); }); + +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", getPossibleInstantsForOriginal); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-wrong-type.js index 429a0f865b4c..d68dc04aa013 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone-wrong-type.js @@ -16,22 +16,18 @@ const rangeErrorTests = [ [1, "number that doesn't convert to a valid ISO string"], [19761118, "number that would convert to a valid ISO string in other contexts"], [1n, "bigint"], - [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of rangeErrorTests) { assert.throws(RangeError, () => Temporal.Now.plainDateTime("iso8601", timeZone), `${description} does not convert to a valid ISO string`); - assert.throws(RangeError, () => Temporal.Now.plainDateTime("iso8601", { timeZone }), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], + [{}, "object not implementing time zone protocol"], + [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of typeErrorTests) { assert.throws(TypeError, () => Temporal.Now.plainDateTime("iso8601", timeZone), `${description} is not a valid object and does not convert to a string`); - assert.throws(TypeError, () => Temporal.Now.plainDateTime("iso8601", { timeZone }), `${description} is not a valid object and does not convert to a string (nested property)`); } - -const timeZone = undefined; -assert.throws(RangeError, () => Temporal.Now.plainDateTime("iso8601", { timeZone }), `undefined is always a RangeError as nested property`); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone.js index c0fab520496e..bb176e6892a6 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTime/timezone.js @@ -10,7 +10,9 @@ features: [Temporal] const actual = []; const expected = [ - "has timeZone.timeZone", + "has timeZone.getOffsetNanosecondsFor", + "has timeZone.getPossibleInstantsFor", + "has timeZone.id", "get timeZone.getOffsetNanosecondsFor", "call timeZone.getOffsetNanosecondsFor", ]; diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/return-value-calendar.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/return-value-calendar.js index 0a666629e824..073856d8ee03 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/return-value-calendar.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/return-value-calendar.js @@ -8,5 +8,4 @@ features: [Temporal] ---*/ const result = Temporal.Now.plainDateTimeISO(); -assert(result.calendar instanceof Temporal.Calendar); -assert.sameValue(result.calendar.id, "iso8601"); +assert.sameValue(result.getISOFields().calendar, "iso8601", "calendar slot should store a string"); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/return-value.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/return-value.js index c0de72cb6d54..f1f31f2bb93e 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/return-value.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/return-value.js @@ -6,6 +6,8 @@ description: Return value describes the start of a day features: [BigInt, Temporal] ---*/ const timeZone = { + id: 'Etc/Test', + getPossibleInstantsFor() { return []; }, getOffsetNanosecondsFor(instant) { return -Number(instant.epochNanoseconds % 86400000000000n); } diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-getoffsetnanosecondsfor-invocation.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-getoffsetnanosecondsfor-invocation.js index 4cf8cd201104..03f3bd666e10 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-getoffsetnanosecondsfor-invocation.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-getoffsetnanosecondsfor-invocation.js @@ -8,6 +8,8 @@ features: [Temporal] var calls = []; var timeZone = { + id: 'Etc/Test', + getPossibleInstantsFor() { return []; }, getOffsetNanosecondsFor: function() { calls.push({ args: arguments, diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-getoffsetnanosecondsfor-not-a-number.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-getoffsetnanosecondsfor-not-a-number.js index 57f530481204..4fd510ca606b 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-getoffsetnanosecondsfor-not-a-number.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-getoffsetnanosecondsfor-not-a-number.js @@ -21,6 +21,8 @@ for (const dateTime of invalidValues) { let callCount = 0; const timeZone = { + id: 'Etc/Test', + getPossibleInstantsFor() { return []; }, getOffsetNanosecondsFor(instant, calendar) { callCount += 1; return dateTime; diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-getoffsetnanosecondsfor-poisoned.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-getoffsetnanosecondsfor-poisoned.js index 822e6a6b6dcf..e1d4a73506c1 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-getoffsetnanosecondsfor-poisoned.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-getoffsetnanosecondsfor-poisoned.js @@ -7,6 +7,8 @@ features: [Temporal] ---*/ var timeZone = { + id: 'Etc/Test', + getPossibleInstantsFor() { return []; }, get getOffsetNanosecondsFor() { throw new Test262Error(); } diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-getoffsetnanosecondsfor-throws.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-getoffsetnanosecondsfor-throws.js index 2c87fdf471e2..21b92652a65f 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-getoffsetnanosecondsfor-throws.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-getoffsetnanosecondsfor-throws.js @@ -7,6 +7,8 @@ features: [Temporal] ---*/ var timeZone = { + id: 'Etc/Test', + getPossibleInstantsFor() { return []; }, getOffsetNanosecondsFor() { throw new Test262Error(); } diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-instance-does-not-get-timeZone-property.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-instance-does-not-get-timeZone-property.js deleted file mode 100644 index 3eb819949742..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-instance-does-not-get-timeZone-property.js +++ /dev/null @@ -1,20 +0,0 @@ -// 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.now.plaindatetimeiso -description: > - A Temporal.TimeZone instance passed to plainDateTimeISO() does not have its - 'timeZone' property observably checked -features: [Temporal] ----*/ - -const timeZone = new Temporal.TimeZone("UTC"); -Object.defineProperty(timeZone, "timeZone", { - get() { - throw new Test262Error("timeZone.timeZone should not be accessed"); - }, -}); - -Temporal.Now.plainDateTimeISO(timeZone); -Temporal.Now.plainDateTimeISO({ timeZone }); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-object-fail-call-tostring.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-object-fail-call-tostring.js deleted file mode 100644 index 80277327d2eb..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-object-fail-call-tostring.js +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-temporal.now.plaindatetimeiso -description: Forwards error thrown by invoking "toString" property -features: [Temporal] ----*/ - -var timeZone = { - timeZone: { - timeZone: true, - toString: function() { - throw new Test262Error(); - }, - } -}; - -assert.throws(Test262Error, function() { - Temporal.Now.plainDateTimeISO(timeZone); -}, 'Temporal.Now.plainDateTimeISO(timeZone) throws a Test262Error exception'); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-object-fail-get-timezone.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-object-fail-get-timezone.js deleted file mode 100644 index 37cc21b8cc8b..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-object-fail-get-timezone.js +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-temporal.now.plaindatetimeiso -description: Forwards error thrown by retrieving value of "timeZone" property -features: [Temporal] ----*/ - -var timeZone = { - get timeZone() { - throw new Test262Error(); - }, -}; - -assert.throws(Test262Error, function() { - Temporal.Now.plainDateTimeISO(timeZone); -}, 'Temporal.Now.plainDateTimeISO(timeZone) throws a Test262Error exception'); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-object-fail-has-nested-timezone.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-object-fail-has-nested-timezone.js deleted file mode 100644 index dc75b4230254..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-object-fail-has-nested-timezone.js +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-temporal.now.plaindatetimeiso -description: Forwards error thrown by checking presence of nested "timeZone" property -features: [Proxy, Temporal] ----*/ - -var timeZone = { - timeZone: new Proxy({}, { - has: function(target, property) { - if (property === 'timeZone') { - throw new Test262Error(); - } - }, - }) -}; - -assert.throws(Test262Error, function() { - Temporal.Now.plainDateTimeISO(timeZone); -}, 'Temporal.Now.plainDateTimeISO(timeZone) throws a Test262Error exception'); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-object-fail-has-timezone.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-object-fail-has-timezone.js deleted file mode 100644 index 86850e3c79d8..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-object-fail-has-timezone.js +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-temporal.now.plaindatetimeiso -description: Forwards error thrown by checking presence of "timeZone" property -features: [Proxy, Temporal] ----*/ - -var timeZone = new Proxy({}, { - has: function(target, property) { - if (property === 'timeZone') { - throw new Test262Error(); - } - }, -}); - -assert.throws(Test262Error, function() { - Temporal.Now.plainDateTimeISO(timeZone); -}, 'Temporal.Now.plainDateTimeISO(timeZone) throws a Test262Error exception'); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-object.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-object.js index 5ef5745ba598..329207447e55 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-object.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-object.js @@ -9,25 +9,13 @@ features: [BigInt, Proxy, Temporal] const actual = []; const expected = [ - 'has timeZone.timeZone', - 'get timeZone.timeZone', - 'has nestedTimeZone.timeZone', - 'get nestedTimeZone.getOffsetNanosecondsFor', - 'call nestedTimeZone.getOffsetNanosecondsFor' + 'has timeZone.getOffsetNanosecondsFor', + 'has timeZone.getPossibleInstantsFor', + 'has timeZone.id', + 'get timeZone.getOffsetNanosecondsFor', + 'call timeZone.getOffsetNanosecondsFor' ]; -const nestedTimeZone = TemporalHelpers.timeZoneObserver(actual, "nestedTimeZone", { - getOffsetNanosecondsFor(instant) { - assert.sameValue( - instant instanceof Temporal.Instant, - true, - 'The result of evaluating (instant instanceof Temporal.Instant) is expected to be true' - ); - - return -Number(instant.epochNanoseconds % 86400000000000n); - } -}); - const timeZone = TemporalHelpers.timeZoneObserver(actual, "timeZone", { getOffsetNanosecondsFor(instant) { assert.sameValue( @@ -39,7 +27,6 @@ const timeZone = TemporalHelpers.timeZoneObserver(actual, "timeZone", { return -Number(instant.epochNanoseconds % 86400000000000n); } }); -timeZone.timeZone = nestedTimeZone; Object.defineProperty(Temporal.TimeZone, 'from', { get() { diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-string-datetime.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-string-datetime.js index 20509a2abb60..50be32b2ce9e 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-string-datetime.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-string-datetime.js @@ -9,7 +9,6 @@ features: [Temporal] let timeZone = "2021-08-19T17:30"; assert.throws(RangeError, () => Temporal.Now.plainDateTimeISO(timeZone), "bare date-time string is not a time zone"); -assert.throws(RangeError, () => Temporal.Now.plainDateTimeISO({ timeZone }), "bare date-time string is not a time zone"); // The following are all valid strings so should not throw: @@ -30,5 +29,4 @@ assert.throws(RangeError, () => Temporal.Now.plainDateTimeISO({ timeZone }), "ba "2021-08-19T1730-0700[UTC]", ].forEach((timeZone) => { Temporal.Now.plainDateTimeISO(timeZone); - Temporal.Now.plainDateTimeISO({ timeZone }); }); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-string-leap-second.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-string-leap-second.js index 4fc82538c222..37dc7cf296d1 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-string-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-string-leap-second.js @@ -9,12 +9,10 @@ features: [Temporal] let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; -// A string with a leap second is a valid ISO string, so the following two -// operations should not throw +// A string with a leap second is a valid ISO string, so the following +// operation should not throw Temporal.Now.plainDateTimeISO(timeZone); -Temporal.Now.plainDateTimeISO({ timeZone }); timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; assert.throws(RangeError, () => Temporal.Now.plainDateTimeISO(timeZone), "leap second in time zone name not valid"); -assert.throws(RangeError, () => Temporal.Now.plainDateTimeISO({ timeZone }), "leap second in time zone name not valid (nested property)"); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-string-year-zero.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-string-year-zero.js index 48501a4b07db..4cefee0c8b10 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-string-year-zero.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-string-year-zero.js @@ -17,9 +17,4 @@ invalidStrings.forEach((timeZone) => { () => Temporal.Now.plainDateTimeISO(timeZone), "reject minus zero as extended year" ); - assert.throws( - RangeError, - () => Temporal.Now.plainDateTimeISO({ timeZone }), - "reject minus zero as extended year (nested property)" - ); }); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-string.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-string.js index a4aebae5a522..2cdab47af058 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-string.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-string.js @@ -4,11 +4,32 @@ /*--- esid: sec-temporal.now.plaindatetimeiso description: Time zone IDs are valid input for a time zone +includes: [temporalHelpers.js] features: [Temporal] ---*/ +const getPossibleInstantsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getPossibleInstantsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getPossibleInstantsFor should not be looked up"); + }, +}); +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + // The following are all valid strings so should not throw: ["UTC", "+01:00"].forEach((timeZone) => { Temporal.Now.plainDateTimeISO(timeZone); }); + +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", getPossibleInstantsForOriginal); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-wrong-type.js index 508de638b2b2..5fde195e2a00 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainDateTimeISO/timezone-wrong-type.js @@ -16,22 +16,18 @@ const rangeErrorTests = [ [1, "number that doesn't convert to a valid ISO string"], [19761118, "number that would convert to a valid ISO string in other contexts"], [1n, "bigint"], - [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of rangeErrorTests) { assert.throws(RangeError, () => Temporal.Now.plainDateTimeISO(timeZone), `${description} does not convert to a valid ISO string`); - assert.throws(RangeError, () => Temporal.Now.plainDateTimeISO({ timeZone }), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], + [{}, "object not implementing time zone protocol"], + [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of typeErrorTests) { assert.throws(TypeError, () => Temporal.Now.plainDateTimeISO(timeZone), `${description} is not a valid object and does not convert to a string`); - assert.throws(TypeError, () => Temporal.Now.plainDateTimeISO({ timeZone }), `${description} is not a valid object and does not convert to a string (nested property)`); } - -const timeZone = undefined; -assert.throws(RangeError, () => Temporal.Now.plainDateTimeISO({ timeZone }), `undefined is always a RangeError as nested property`); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainTimeISO/return-value.js b/JSTests/test262/test/built-ins/Temporal/Now/plainTimeISO/return-value.js index 34dc61f7a709..9f3ec0d4cbc1 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainTimeISO/return-value.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainTimeISO/return-value.js @@ -9,4 +9,3 @@ features: [Temporal] const t = Temporal.Now.plainTimeISO(); assert(t instanceof Temporal.PlainTime); -assert.sameValue(t.calendar.id, "iso8601"); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainTimeISO/timezone-instance-does-not-get-timeZone-property.js b/JSTests/test262/test/built-ins/Temporal/Now/plainTimeISO/timezone-instance-does-not-get-timeZone-property.js deleted file mode 100644 index e49afec915b7..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainTimeISO/timezone-instance-does-not-get-timeZone-property.js +++ /dev/null @@ -1,20 +0,0 @@ -// 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.now.plaintimeiso -description: > - A Temporal.TimeZone instance passed to plainTimeISO() does not have its - 'timeZone' property observably checked -features: [Temporal] ----*/ - -const timeZone = new Temporal.TimeZone("UTC"); -Object.defineProperty(timeZone, "timeZone", { - get() { - throw new Test262Error("timeZone.timeZone should not be accessed"); - }, -}); - -Temporal.Now.plainTimeISO(timeZone); -Temporal.Now.plainTimeISO({ timeZone }); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainTimeISO/timezone-string-datetime.js b/JSTests/test262/test/built-ins/Temporal/Now/plainTimeISO/timezone-string-datetime.js index ce0307e1b3ec..425ddbd92c6e 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainTimeISO/timezone-string-datetime.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainTimeISO/timezone-string-datetime.js @@ -9,7 +9,6 @@ features: [Temporal] let timeZone = "2021-08-19T17:30"; assert.throws(RangeError, () => Temporal.Now.plainTimeISO(timeZone), "bare date-time string is not a time zone"); -assert.throws(RangeError, () => Temporal.Now.plainTimeISO({ timeZone }), "bare date-time string is not a time zone"); // The following are all valid strings so should not throw: @@ -30,5 +29,4 @@ assert.throws(RangeError, () => Temporal.Now.plainTimeISO({ timeZone }), "bare d "2021-08-19T1730-0700[UTC]", ].forEach((timeZone) => { Temporal.Now.plainTimeISO(timeZone); - Temporal.Now.plainTimeISO({ timeZone }); }); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainTimeISO/timezone-string-leap-second.js b/JSTests/test262/test/built-ins/Temporal/Now/plainTimeISO/timezone-string-leap-second.js index f37d00c9b2ff..b01ae8c46dfa 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainTimeISO/timezone-string-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainTimeISO/timezone-string-leap-second.js @@ -9,12 +9,10 @@ features: [Temporal] let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; -// A string with a leap second is a valid ISO string, so the following two -// operations should not throw +// A string with a leap second is a valid ISO string, so the following +// operation should not throw Temporal.Now.plainTimeISO(timeZone); -Temporal.Now.plainTimeISO({ timeZone }); timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; assert.throws(RangeError, () => Temporal.Now.plainTimeISO(timeZone), "leap second in time zone name not valid"); -assert.throws(RangeError, () => Temporal.Now.plainTimeISO({ timeZone }), "leap second in time zone name not valid (nested property)"); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainTimeISO/timezone-string-year-zero.js b/JSTests/test262/test/built-ins/Temporal/Now/plainTimeISO/timezone-string-year-zero.js index a9770de6fdd4..11b45dde31fb 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainTimeISO/timezone-string-year-zero.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainTimeISO/timezone-string-year-zero.js @@ -17,9 +17,4 @@ invalidStrings.forEach((timeZone) => { () => Temporal.Now.plainTimeISO(timeZone), "reject minus zero as extended year" ); - assert.throws( - RangeError, - () => Temporal.Now.plainTimeISO({ timeZone }), - "reject minus zero as extended year (nested property)" - ); }); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainTimeISO/timezone-string.js b/JSTests/test262/test/built-ins/Temporal/Now/plainTimeISO/timezone-string.js index 939f6afa0abf..a8fa8c371372 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainTimeISO/timezone-string.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainTimeISO/timezone-string.js @@ -4,11 +4,32 @@ /*--- esid: sec-temporal.now.plaintimeiso description: Time zone IDs are valid input for a time zone +includes: [temporalHelpers.js] features: [Temporal] ---*/ +const getPossibleInstantsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getPossibleInstantsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getPossibleInstantsFor should not be looked up"); + }, +}); +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + // The following are all valid strings so should not throw: ["UTC", "+01:00"].forEach((timeZone) => { Temporal.Now.plainTimeISO(timeZone); }); + +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", getPossibleInstantsForOriginal); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainTimeISO/timezone-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/Now/plainTimeISO/timezone-wrong-type.js index 557f8aee0e85..09be7bb69640 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainTimeISO/timezone-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainTimeISO/timezone-wrong-type.js @@ -16,22 +16,18 @@ const rangeErrorTests = [ [1, "number that doesn't convert to a valid ISO string"], [19761118, "number that would convert to a valid ISO string in other contexts"], [1n, "bigint"], - [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of rangeErrorTests) { assert.throws(RangeError, () => Temporal.Now.plainTimeISO(timeZone), `${description} does not convert to a valid ISO string`); - assert.throws(RangeError, () => Temporal.Now.plainTimeISO({ timeZone }), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], + [{}, "object not implementing time zone protocol"], + [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of typeErrorTests) { assert.throws(TypeError, () => Temporal.Now.plainTimeISO(timeZone), `${description} is not a valid object and does not convert to a string`); - assert.throws(TypeError, () => Temporal.Now.plainTimeISO({ timeZone }), `${description} is not a valid object and does not convert to a string (nested property)`); } - -const timeZone = undefined; -assert.throws(RangeError, () => Temporal.Now.plainTimeISO({ timeZone }), `undefined is always a RangeError as nested property`); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainTimeISO/timezone.js b/JSTests/test262/test/built-ins/Temporal/Now/plainTimeISO/timezone.js index 246bf54d8f09..afdbe41bd82e 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainTimeISO/timezone.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainTimeISO/timezone.js @@ -10,7 +10,9 @@ features: [Temporal] const actual = []; const expected = [ - "has timeZone.timeZone", + "has timeZone.getOffsetNanosecondsFor", + "has timeZone.getPossibleInstantsFor", + "has timeZone.id", "get timeZone.getOffsetNanosecondsFor", "call timeZone.getOffsetNanosecondsFor", ]; diff --git a/JSTests/test262/test/built-ins/Temporal/Now/plainTimeISO/toPlainTime-override.js b/JSTests/test262/test/built-ins/Temporal/Now/plainTimeISO/toPlainTime-override.js index b276ab7264b3..7411562060f8 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/plainTimeISO/toPlainTime-override.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/plainTimeISO/toPlainTime-override.js @@ -10,7 +10,9 @@ features: [Temporal] const actual = []; const expected = [ - "has timeZone.timeZone", + "has timeZone.getOffsetNanosecondsFor", + "has timeZone.getPossibleInstantsFor", + "has timeZone.id", "get timeZone.getOffsetNanosecondsFor", "call timeZone.getOffsetNanosecondsFor", ]; diff --git a/JSTests/test262/test/built-ins/Temporal/Now/timeZone/extensible.js b/JSTests/test262/test/built-ins/Temporal/Now/timeZone/extensible.js deleted file mode 100644 index 929a07084762..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/timeZone/extensible.js +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.now.timezone -description: Temporal.Now.timeZone is extensible. -info: | - ## 17 ECMAScript Standard Built-in Objects - - Unless specified otherwise, the [[Extensible]] internal slot - of a built-in object initially has the value true. -features: [Temporal] ----*/ - -assert( - Object.isExtensible(Temporal.Now.timeZone), - 'Object.isExtensible(Temporal.Now.timeZone) must return true' -); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/timeZone/length.js b/JSTests/test262/test/built-ins/Temporal/Now/timeZone/length.js deleted file mode 100644 index fdf33918f16b..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/timeZone/length.js +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (C) 2020 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.now.timezone -description: Temporal.Now.timeZone.length is 0 -info: | - Every built-in function object, including constructors, has a "length" property whose value is - an integer. Unless otherwise specified, this value is equal to the largest number of named - arguments shown in the subclause headings for the function description. Optional parameters - (which are indicated with brackets: [ ]) or rest parameters (which are shown using the form - «...name») are not included in the default argument count. - - Unless otherwise specified, the "length" property of a built-in function object has the - attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. -includes: [propertyHelper.js] -features: [Temporal] ----*/ - -verifyProperty(Temporal.Now.timeZone, "length", { - value: 0, - writable: false, - enumerable: false, - configurable: true, -}); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/timeZone/name.js b/JSTests/test262/test/built-ins/Temporal/Now/timeZone/name.js deleted file mode 100644 index 2e70d8b02dbc..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/timeZone/name.js +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.now.timezone -description: Temporal.Now.timeZone.name is "timeZone". -info: | - ## 17 ECMAScript Standard Built-in Objects: - Every built-in Function object, including constructors, that is not - identified as an anonymous function has a name property whose value is a - String. - - Unless otherwise specified, the name property of a built-in Function object, - if it exists, has the attributes { [[Writable]]: false, [[Enumerable]]: - false, [[Configurable]]: true }. -includes: [propertyHelper.js] -features: [Temporal] ----*/ - -assert.sameValue( - Temporal.Now.timeZone.name, - 'timeZone', - 'The value of Temporal.Now.timeZone.name is expected to be "timeZone"' -); - -verifyProperty(Temporal.Now.timeZone, 'name', { - enumerable: false, - writable: false, - configurable: true -}); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/timeZone/new-object.js b/JSTests/test262/test/built-ins/Temporal/Now/timeZone/new-object.js deleted file mode 100644 index 01ff926a6087..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/timeZone/new-object.js +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (C) 2020 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.now.timezone -description: Each invocation of the function produces a distinct object value -features: [Temporal] ----*/ - -const tz = Temporal.Now.timeZone; -const tz1 = tz(); -const tz2 = tz(); -assert.notSameValue(tz1, tz2, 'The value of tz1 is expected to not equal the value of `tz2`'); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/timeZone/not-a-constructor.js b/JSTests/test262/test/built-ins/Temporal/Now/timeZone/not-a-constructor.js deleted file mode 100644 index 7239f3b43ee3..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/timeZone/not-a-constructor.js +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.now.timezone -description: Temporal.Now.timeZone does not implement [[Construct]] -info: | - ECMAScript Function Objects - - Built-in function objects that are not identified as constructors do not - implement the [[Construct]] internal method unless otherwise specified in - the description of a particular function. -includes: [isConstructor.js] -features: [Reflect.construct, Temporal, arrow-function] ----*/ - -assert.sameValue(isConstructor(Temporal.Now.timeZone), false, 'isConstructor(Temporal.Now.timeZone) must return false'); - -assert.throws(TypeError, () => { - new Temporal.Now.timeZone(); -}, 'new Temporal.Now.timeZone() throws a TypeError exception'); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/timeZone/prop-desc.js b/JSTests/test262/test/built-ins/Temporal/Now/timeZone/prop-desc.js deleted file mode 100644 index 15829fb2eb18..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/timeZone/prop-desc.js +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.now.timezone -description: The "timeZone" property of Temporal.Now -info: | - Section 17: Every other data property described in clauses 18 through 26 - and in Annex B.2 has the attributes { [[Writable]]: true, - [[Enumerable]]: false, [[Configurable]]: true } unless otherwise specified. -includes: [propertyHelper.js] -features: [Temporal] ----*/ - -assert.sameValue(typeof Temporal.Now.timeZone, "function", "typeof is function"); - -verifyProperty(Temporal.Now, 'timeZone', { - enumerable: false, - writable: true, - configurable: true -}); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/timeZone/return-value.js b/JSTests/test262/test/built-ins/Temporal/Now/timeZone/return-value.js deleted file mode 100644 index 098717a1cede..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/timeZone/return-value.js +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.now.timezone -description: Temporal.Now.timeZone returns an instance of the TimeZone constructor -info: | - 1. Return ? SystemTimeZone(). -features: [Temporal] ----*/ - -assert.sameValue( - Object.getPrototypeOf(Temporal.Now.timeZone()), - Temporal.TimeZone.prototype, - 'Object.getPrototypeOf(Temporal.Now.timeZone()) returns Temporal.TimeZone.prototype' -); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/timeZoneId/extensible.js b/JSTests/test262/test/built-ins/Temporal/Now/timeZoneId/extensible.js new file mode 100644 index 000000000000..05a87d588be2 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Now/timeZoneId/extensible.js @@ -0,0 +1,18 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.now.timezoneid +description: Temporal.Now.timeZoneId is extensible. +info: | + ## 17 ECMAScript Standard Built-in Objects + + Unless specified otherwise, the [[Extensible]] internal slot + of a built-in object initially has the value true. +features: [Temporal] +---*/ + +assert( + Object.isExtensible(Temporal.Now.timeZoneId), + 'Object.isExtensible(Temporal.Now.timeZoneId) must return true' +); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/timeZoneId/length.js b/JSTests/test262/test/built-ins/Temporal/Now/timeZoneId/length.js new file mode 100644 index 000000000000..0a268a2e530e --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Now/timeZoneId/length.js @@ -0,0 +1,25 @@ +// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.now.timezoneid +description: Temporal.Now.timeZoneId.length is 0 +info: | + Every built-in function object, including constructors, has a "length" property whose value is + an integer. Unless otherwise specified, this value is equal to the largest number of named + arguments shown in the subclause headings for the function description. Optional parameters + (which are indicated with brackets: [ ]) or rest parameters (which are shown using the form + «...name») are not included in the default argument count. + + Unless otherwise specified, the "length" property of a built-in function object has the + attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +verifyProperty(Temporal.Now.timeZoneId, "length", { + value: 0, + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/timeZoneId/name.js b/JSTests/test262/test/built-ins/Temporal/Now/timeZoneId/name.js new file mode 100644 index 000000000000..67c9858604a0 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Now/timeZoneId/name.js @@ -0,0 +1,30 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.now.timezoneid +description: Temporal.Now.timeZoneId.name is "timeZoneId". +info: | + ## 17 ECMAScript Standard Built-in Objects: + Every built-in Function object, including constructors, that is not + identified as an anonymous function has a name property whose value is a + String. + + Unless otherwise specified, the name property of a built-in Function object, + if it exists, has the attributes { [[Writable]]: false, [[Enumerable]]: + false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + Temporal.Now.timeZoneId.name, + 'timeZoneId', + 'The value of Temporal.Now.timeZoneId.name is expected to be "timeZoneId"' +); + +verifyProperty(Temporal.Now.timeZoneId, 'name', { + enumerable: false, + writable: false, + configurable: true +}); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/timeZoneId/not-a-constructor.js b/JSTests/test262/test/built-ins/Temporal/Now/timeZoneId/not-a-constructor.js new file mode 100644 index 000000000000..4056fd39ec11 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Now/timeZoneId/not-a-constructor.js @@ -0,0 +1,21 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.now.timezoneid +description: Temporal.Now.timeZoneId does not implement [[Construct]] +info: | + ECMAScript Function Objects + + Built-in function objects that are not identified as constructors do not + implement the [[Construct]] internal method unless otherwise specified in + the description of a particular function. +includes: [isConstructor.js] +features: [Reflect.construct, Temporal, arrow-function] +---*/ + +assert.sameValue(isConstructor(Temporal.Now.timeZoneId), false, 'isConstructor(Temporal.Now.timeZoneId) must return false'); + +assert.throws(TypeError, () => { + new Temporal.Now.timeZoneId(); +}, 'new Temporal.Now.timeZoneId() throws a TypeError exception'); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/timeZoneId/prop-desc.js b/JSTests/test262/test/built-ins/Temporal/Now/timeZoneId/prop-desc.js new file mode 100644 index 000000000000..15cafacf0c52 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Now/timeZoneId/prop-desc.js @@ -0,0 +1,21 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.now.timezoneid +description: The "timeZoneId" property of Temporal.Now +info: | + Section 17: Every other data property described in clauses 18 through 26 + and in Annex B.2 has the attributes { [[Writable]]: true, + [[Enumerable]]: false, [[Configurable]]: true } unless otherwise specified. +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue(typeof Temporal.Now.timeZoneId, "function", "typeof is function"); + +verifyProperty(Temporal.Now, 'timeZoneId', { + enumerable: false, + writable: true, + configurable: true +}); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/timeZoneId/return-value.js b/JSTests/test262/test/built-ins/Temporal/Now/timeZoneId/return-value.js new file mode 100644 index 000000000000..efb52a123de5 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/Now/timeZoneId/return-value.js @@ -0,0 +1,16 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.now.timezoneid +description: Temporal.Now.timeZoneId returns a string +info: | + 1. Return DefaultTimeZone(). +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.Now.timeZoneId(), + "string", + "Temporal.Now.timeZoneId() returns a string" +); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-case-insensitive.js index 1222f7175f0a..9b6bbb31565b 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-case-insensitive.js @@ -10,4 +10,4 @@ features: [Temporal] const arg = "iSo8601"; const result = Temporal.Now.zonedDateTime(arg); -assert.sameValue(result.calendar.id, "iso8601", "Calendar is case-insensitive"); +assert.sameValue(result.calendarId, "iso8601", "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-function.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-function.js index 8c3fa3ab561b..01911ec74842 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-function.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-function.js @@ -7,12 +7,34 @@ includes: [compareArray.js, temporalHelpers.js] features: [BigInt, Proxy, Temporal] ---*/ const actual = []; - const expected = [ - 'has timeZone.timeZone' + "has timeZone.getOffsetNanosecondsFor", + "has timeZone.getPossibleInstantsFor", + "has timeZone.id", ]; const calendar = function() {}; +calendar.dateAdd = () => {}; +calendar.dateFromFields = () => {}; +calendar.dateUntil = () => {}; +calendar.day = () => {}; +calendar.dayOfWeek = () => {}; +calendar.dayOfYear = () => {}; +calendar.daysInMonth = () => {}; +calendar.daysInWeek = () => {}; +calendar.daysInYear = () => {}; +calendar.fields = () => {}; +calendar.id = "test-calendar"; +calendar.inLeapYear = () => {}; +calendar.mergeFields = () => {}; +calendar.month = () => {}; +calendar.monthCode = () => {}; +calendar.monthDayFromFields = () => {}; +calendar.monthsInYear = () => {}; +calendar.weekOfYear = () => {}; +calendar.year = () => {}; +calendar.yearMonthFromFields = () => {}; +calendar.yearOfWeek = () => {}; const timeZone = TemporalHelpers.timeZoneObserver(actual, "timeZone", { getOffsetNanosecondsFor(instant) { @@ -29,7 +51,7 @@ Object.defineProperty(Temporal.Calendar, 'from', { const result = Temporal.Now.zonedDateTime(calendar, timeZone); -assert.compareArray(actual, expected, 'The value of actual is expected to equal the value of expected'); +assert.compareArray(actual, expected, 'order of observable operations'); for (const property of ['hour', 'minute', 'second', 'millisecond', 'microsecond', 'nanosecond']) { assert.sameValue(result[property], 0, 'The value of result[property] is expected to be 0'); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index c247c6bb2ece..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,20 +0,0 @@ -// 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.now.zoneddatetime -description: > - A Temporal.Calendar instance passed to zonedDateTime() does not have its - 'calendar' property observably checked -features: [Temporal] ----*/ - -const arg = new Temporal.Calendar("iso8601"); -Object.defineProperty(arg, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -Temporal.Now.zonedDateTime(arg); -Temporal.Now.zonedDateTime({ calendar: arg }); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-number.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-number.js index 296ed87aa0f3..6a6578db32b2 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-number.js @@ -10,7 +10,7 @@ features: [Temporal] const arg = 19761118; const result = Temporal.Now.zonedDateTime(arg); -assert.sameValue(result.calendar.id, "iso8601", "19761118 is a valid ISO string for Calendar"); +assert.sameValue(result.calendarId, "iso8601", "19761118 is a valid ISO string for Calendar"); const numbers = [ 1, diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-object-fail-call-tostring.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-object-fail-call-tostring.js deleted file mode 100644 index 84551f311c26..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-object-fail-call-tostring.js +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-temporal.now.zoneddatetime -description: Forwards error thrown by invoking "toString" property -features: [Temporal] ----*/ - -var calendar = { - calendar: { - calendar: true, - toString: function() { - throw new Test262Error(); - }, - } -}; - -assert.throws(Test262Error, function() { - Temporal.Now.zonedDateTime(calendar); -}, 'Temporal.Now.zonedDateTime(calendar) throws a Test262Error exception'); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-object-fail-get-calendar.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-object-fail-get-calendar.js deleted file mode 100644 index e85e358ccc2f..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-object-fail-get-calendar.js +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-temporal.now.zoneddatetime -description: Forwards error thrown by retrieving value of "calendar" property -features: [Temporal] ----*/ - -var calendar = { - get calendar() { - throw new Test262Error(); - }, -}; - -assert.throws(Test262Error, function() { - Temporal.Now.zonedDateTime(calendar); -}, 'Temporal.Now.zonedDateTime(calendar) throws a Test262Error exception'); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-object-fail-has-calendar.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-object-fail-has-calendar.js deleted file mode 100644 index f92915646a39..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-object-fail-has-calendar.js +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.now.zoneddatetime -description: Forwards error thrown by checking presence of "calendar" property -features: [Proxy, Temporal] ----*/ - -var calendar = new Proxy({}, { - has: function(target, property) { - if (property === 'calendar') { - throw new Test262Error(); - } - }, -}); - -assert.throws(Test262Error, function() { - Temporal.Now.zonedDateTime(calendar); -}, 'Temporal.Now.zonedDateTime(calendar) throws a Test262Error exception'); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-object-fail-has-nested-calendar.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-object-fail-has-nested-calendar.js deleted file mode 100644 index 2a5ccfe092bc..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-object-fail-has-nested-calendar.js +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-temporal.now.zoneddatetime -description: Forwards error thrown by checking presence of nested "calendar" property -features: [Proxy, Temporal] ----*/ - -var calendar = { - calendar: new Proxy({}, { - has: function(target, property) { - if (property === 'calendar') { - throw new Test262Error(); - } - }, - }) -}; - -assert.throws(Test262Error, function() { - Temporal.Now.zonedDateTime(calendar); -}, 'Temporal.Now.zonedDateTime(calendar) throws a Test262Error exception'); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-object.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-object.js index a2e2129be8d5..284d58595bba 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-object.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-object.js @@ -9,26 +9,33 @@ features: [Proxy, Temporal] ---*/ const actual = []; -const expectedWithout = [ - 'has calendar.calendar', - 'get calendar.calendar', - 'has nestedCalendar.calendar' +const expected = [ + "has calendar.dateAdd", + "has calendar.dateFromFields", + "has calendar.dateUntil", + "has calendar.day", + "has calendar.dayOfWeek", + "has calendar.dayOfYear", + "has calendar.daysInMonth", + "has calendar.daysInWeek", + "has calendar.daysInYear", + "has calendar.fields", + "has calendar.id", + "has calendar.inLeapYear", + "has calendar.mergeFields", + "has calendar.month", + "has calendar.monthCode", + "has calendar.monthDayFromFields", + "has calendar.monthsInYear", + "has calendar.weekOfYear", + "has calendar.year", + "has calendar.yearMonthFromFields", + "has calendar.yearOfWeek", ]; -const expectedWith = [ - 'has calendar.calendar', - 'get calendar.calendar', - 'has nestedCalendar.calendar', - 'get nestedCalendar[Symbol.toPrimitive]', - 'get nestedCalendar.toString', - 'call nestedCalendar.toString' -]; -const nestedCalendar = TemporalHelpers.calendarObserver(actual, "nestedCalendar", { - toString: "iso8601", -}); + const calendar = TemporalHelpers.calendarObserver(actual, "calendar", { toString: "iso8601", }); -calendar.calendar = nestedCalendar; Object.defineProperty(Temporal.Calendar, 'from', { get() { @@ -39,11 +46,4 @@ Object.defineProperty(Temporal.Calendar, 'from', { Temporal.Now.zonedDateTime(calendar); -assert.compareArray(actual, expectedWithout, 'Observable interactions without `calendar` property'); - -actual.length = 0; -nestedCalendar.calendar = null; - -Temporal.Now.zonedDateTime(calendar); - -assert.compareArray(actual, expectedWith, 'Observable interactions with `calendar` property'); +assert.compareArray(actual, expected, 'order of observable operations'); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-string-leap-second.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-string-leap-second.js index dde4ad71fe4b..6a7bfab7a492 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-string-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-string-leap-second.js @@ -7,18 +7,10 @@ description: Leap second is a valid ISO string for Calendar features: [Temporal] ---*/ -let arg = "2016-12-31T23:59:60"; -const result1 = Temporal.Now.zonedDateTime(arg); +const arg = "2016-12-31T23:59:60"; +const result = Temporal.Now.zonedDateTime(arg); assert.sameValue( - result1.calendar.id, + result.calendarId, "iso8601", "leap second is a valid ISO string for Calendar" ); - -arg = { calendar: "2016-12-31T23:59:60" }; -const result2 = Temporal.Now.zonedDateTime(arg); -assert.sameValue( - result2.calendar.id, - "iso8601", - "leap second is a valid ISO string for Calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-string.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-string.js index 52c9084a2370..2bec05fd3f03 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-string.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-string.js @@ -10,4 +10,4 @@ features: [Temporal] const arg = "iso8601"; const result = Temporal.Now.zonedDateTime(arg); -assert.sameValue(result.calendar.id, "iso8601", `Calendar created from string "${arg}"`); +assert.sameValue(result.getISOFields().calendar, "iso8601", `Calendar created from string "${arg}"`); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-temporal-object.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-temporal-object.js index 18099078b813..f2d262cf2786 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-temporal-object.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-temporal-object.js @@ -6,7 +6,7 @@ esid: sec-temporal.now.zoneddatetime description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots info: | sec-temporal-totemporalcalendar step 1.b: - b. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then + b. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then i. Return _temporalCalendarLike_.[[Calendar]]. includes: [compareArray.js] features: [Temporal] @@ -14,12 +14,11 @@ features: [Temporal] const plainDate = new Temporal.PlainDate(2000, 5, 2); const plainDateTime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); -const plainTime = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); const plainMonthDay = new Temporal.PlainMonthDay(5, 2); const plainYearMonth = new Temporal.PlainYearMonth(2000, 5); const zonedDateTime = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); -[plainDate, plainDateTime, plainTime, plainMonthDay, plainYearMonth, zonedDateTime].forEach((arg) => { +[plainDate, plainDateTime, plainMonthDay, plainYearMonth, zonedDateTime].forEach((arg) => { const actual = []; const expected = []; @@ -33,7 +32,7 @@ const zonedDateTime = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UT }); const result = Temporal.Now.zonedDateTime(arg); - assert.sameValue(result.calendar, calendar, "Temporal object coerced to calendar"); + assert.sameValue(result.getISOFields().calendar, calendar, "Temporal object coerced to calendar"); assert.compareArray(actual, expected, "calendar getter not called"); }); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-wrong-type.js index 1a6196458a4a..ce7bbc1b7910 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/calendar-wrong-type.js @@ -15,19 +15,19 @@ const rangeErrorTests = [ ["", "empty string"], [1, "number that doesn't convert to a valid ISO string"], [1n, "bigint"], - [new Temporal.TimeZone("UTC"), "time zone instance"], ]; for (const [arg, description] of rangeErrorTests) { assert.throws(RangeError, () => Temporal.Now.zonedDateTime(arg), `${description} does not convert to a valid ISO string`); - assert.throws(RangeError, () => Temporal.Now.zonedDateTime({ calendar: arg }), `${description} does not convert to a valid ISO string (in property bag)`); } const typeErrorTests = [ [Symbol(), "symbol"], + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], ]; for (const [arg, description] of typeErrorTests) { assert.throws(TypeError, () => Temporal.Now.zonedDateTime(arg), `${description} is not a valid object and does not convert to a string`); - assert.throws(TypeError, () => Temporal.Now.zonedDateTime({ calendar: arg }), `${description} is not a valid object and does not convert to a string (in property bag)`); } diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/time-zone-undefined.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/time-zone-undefined.js index 71bc5816a27a..a24867ac0f29 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/time-zone-undefined.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/time-zone-undefined.js @@ -18,14 +18,14 @@ Object.defineProperty(Temporal.TimeZone, "from", { }, }); -const systemTimeZone = Temporal.Now.timeZone(); +const systemTimeZone = Temporal.Now.timeZoneId(); const resultExplicit = Temporal.Now.zonedDateTime('iso8601', undefined); -assert.sameValue(resultExplicit.timeZone.id, systemTimeZone.id); +assert.sameValue(resultExplicit.getISOFields().timeZone, systemTimeZone, "time zone slot should store a string"); assert.compareArray(actual, expected, "Temporal.TimeZone.from should not be called"); const resultImplicit = Temporal.Now.zonedDateTime('iso8601'); -assert.sameValue(resultImplicit.timeZone.id, systemTimeZone.id); +assert.sameValue(resultImplicit.getISOFields().timeZone, systemTimeZone, "time zone slot should store a string"); assert.compareArray(actual, expected, "Temporal.TimeZone.from should not be called"); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-case-insensitive.js index 15e596237c13..87837a94f14f 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-case-insensitive.js @@ -9,4 +9,4 @@ features: [Temporal] const timeZone = 'UtC'; const result = Temporal.Now.zonedDateTime("iso8601", timeZone); -assert.sameValue(result.timeZone.id, 'UTC', `Time zone created from string "${timeZone}"`); +assert.sameValue(result.timeZoneId, 'UTC', `Time zone created from string "${timeZone}"`); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-instance-does-not-get-timeZone-property.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-instance-does-not-get-timeZone-property.js deleted file mode 100644 index 73a27dd9f245..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-instance-does-not-get-timeZone-property.js +++ /dev/null @@ -1,20 +0,0 @@ -// 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.now.zoneddatetime -description: > - A Temporal.TimeZone instance passed to zonedDateTime() does not have its - 'timeZone' property observably checked -features: [Temporal] ----*/ - -const timeZone = new Temporal.TimeZone("UTC"); -Object.defineProperty(timeZone, "timeZone", { - get() { - throw new Test262Error("timeZone.timeZone should not be accessed"); - }, -}); - -Temporal.Now.zonedDateTime("iso8601", timeZone); -Temporal.Now.zonedDateTime("iso8601", { timeZone }); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-object-fail-call-tostring.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-object-fail-call-tostring.js deleted file mode 100644 index 0f469eb4a55a..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-object-fail-call-tostring.js +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-temporal.now.zoneddatetime -description: Forwards error thrown by invoking "toString" property -features: [Temporal] ----*/ - -var timeZone = { - timeZone: { - timeZone: true, - toString: function() { - throw new Test262Error(); - }, - } -}; - -assert.throws(Test262Error, function() { - Temporal.Now.zonedDateTime("iso8601", timeZone); -}, 'Temporal.Now.zonedDateTime("iso8601", timeZone) throws a Test262Error exception'); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-object-fail-get-timezone.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-object-fail-get-timezone.js deleted file mode 100644 index 630536cefb1f..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-object-fail-get-timezone.js +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-temporal.now.zoneddatetime -description: Forwards error thrown by retrieving value of "timeZone" property -features: [Temporal] ----*/ - -var timeZone = { - get timeZone() { - throw new Test262Error(); - }, -}; - -assert.throws(Test262Error, function() { - Temporal.Now.zonedDateTime("iso8601", timeZone); -}, 'Temporal.Now.zonedDateTime("iso8601", timeZone) throws a Test262Error exception'); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-object-fail-has-nested-timezone.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-object-fail-has-nested-timezone.js deleted file mode 100644 index 470ff62da01b..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-object-fail-has-nested-timezone.js +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-temporal.now.zoneddatetime -description: Forwards error thrown by checking presence of nested "timeZone" property -features: [Proxy, Temporal] ----*/ - -var timeZone = { - timeZone: new Proxy({}, { - has: function(target, property) { - if (property === 'timeZone') { - throw new Test262Error(); - } - }, - }) -}; - -assert.throws(Test262Error, function() { - Temporal.Now.zonedDateTime("iso8601", timeZone); -}, 'Temporal.Now.zonedDateTime("iso8601", timeZone) throws a Test262Error exception'); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-object-fail-has-timezone.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-object-fail-has-timezone.js deleted file mode 100644 index 7e1d997ca0e2..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-object-fail-has-timezone.js +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-temporal.now.zoneddatetime -description: Forwards error thrown by checking presence of "timeZone" property -features: [Proxy, Temporal] ----*/ - -var timeZone = new Proxy({}, { - has: function(target, property) { - if (property === 'timeZone') { - throw new Test262Error(); - } - }, -}); - -assert.throws(Test262Error, function() { - Temporal.Now.zonedDateTime("iso8601", timeZone); -}, 'Temporal.Now.zonedDateTime("iso8601", timeZone) throws a Test262Error exception'); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-object.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-object.js index 579d015629c7..f6f9631b5523 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-object.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-object.js @@ -7,25 +7,12 @@ includes: [compareArray.js, temporalHelpers.js] features: [BigInt, Proxy, Temporal] ---*/ const actual = []; - const expected = [ - 'has timeZone.timeZone', - 'get timeZone.timeZone', - 'has nestedTimeZone.timeZone' + "has timeZone.getOffsetNanosecondsFor", + "has timeZone.getPossibleInstantsFor", + "has timeZone.id", ]; -const nestedTimeZone = TemporalHelpers.timeZoneObserver(actual, "nestedTimeZone", { - getOffsetNanosecondsFor(instant) { - assert.sameValue( - instant instanceof Temporal.Instant, - true, - 'The result of evaluating (instant instanceof Temporal.Instant) is expected to be true' - ); - - return -Number(instant.epochNanoseconds % 86400000000000n); - } -}); - const timeZone = TemporalHelpers.timeZoneObserver(actual, "timeZone", { getOffsetNanosecondsFor(instant) { assert.sameValue( @@ -37,7 +24,6 @@ const timeZone = TemporalHelpers.timeZoneObserver(actual, "timeZone", { return -Number(instant.epochNanoseconds % 86400000000000n); } }); -timeZone.timeZone = nestedTimeZone; Object.defineProperty(Temporal.TimeZone, 'from', { get() { @@ -47,4 +33,4 @@ Object.defineProperty(Temporal.TimeZone, 'from', { }); Temporal.Now.zonedDateTime('iso8601', timeZone); -assert.compareArray(actual, expected, 'The value of actual is expected to equal the value of expected'); +assert.compareArray(actual, expected, 'order of observable operations'); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-string-datetime.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-string-datetime.js index 8a70dd655ce0..1067afa632d7 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-string-datetime.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-string-datetime.js @@ -9,34 +9,23 @@ features: [Temporal] let timeZone = "2021-08-19T17:30"; assert.throws(RangeError, () => Temporal.Now.zonedDateTime("iso8601", timeZone), "bare date-time string is not a time zone"); -assert.throws(RangeError, () => Temporal.Now.zonedDateTime("iso8601", { timeZone }), "bare date-time string is not a time zone"); timeZone = "2021-08-19T17:30Z"; const result1 = Temporal.Now.zonedDateTime("iso8601", timeZone); -assert.sameValue(result1.timeZone.id, "UTC", "date-time + Z is UTC time zone"); -const result2 = Temporal.Now.zonedDateTime("iso8601", { timeZone }); -assert.sameValue(result2.timeZone.id, "UTC", "date-time + Z is UTC time zone (string in property bag)"); +assert.sameValue(result1.timeZoneId, "UTC", "date-time + Z is UTC time zone"); timeZone = "2021-08-19T17:30-07:00"; -const result3 = Temporal.Now.zonedDateTime("iso8601", timeZone); -assert.sameValue(result3.timeZone.id, "-07:00", "date-time + offset is the offset time zone"); -const result4 = Temporal.Now.zonedDateTime("iso8601", { timeZone }); -assert.sameValue(result4.timeZone.id, "-07:00", "date-time + offset is the offset time zone (string in property bag)"); +const result2 = Temporal.Now.zonedDateTime("iso8601", timeZone); +assert.sameValue(result2.timeZoneId, "-07:00", "date-time + offset is the offset time zone"); timeZone = "2021-08-19T17:30[UTC]"; -const result5 = Temporal.Now.zonedDateTime("iso8601", timeZone); -assert.sameValue(result5.timeZone.id, "UTC", "date-time + IANA annotation is the IANA time zone"); -const result6 = Temporal.Now.zonedDateTime("iso8601", { timeZone }); -assert.sameValue(result6.timeZone.id, "UTC", "date-time + IANA annotation is the IANA time zone (string in property bag)"); +const result3 = Temporal.Now.zonedDateTime("iso8601", timeZone); +assert.sameValue(result3.timeZoneId, "UTC", "date-time + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30Z[UTC]"; -const result7 = Temporal.Now.zonedDateTime("iso8601", timeZone); -assert.sameValue(result7.timeZone.id, "UTC", "date-time + Z + IANA annotation is the IANA time zone"); -const result8 = Temporal.Now.zonedDateTime("iso8601", { timeZone }); -assert.sameValue(result8.timeZone.id, "UTC", "date-time + Z + IANA annotation is the IANA time zone (string in property bag)"); +const result4 = Temporal.Now.zonedDateTime("iso8601", timeZone); +assert.sameValue(result4.timeZoneId, "UTC", "date-time + Z + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30-07:00[UTC]"; -const result9 = Temporal.Now.zonedDateTime("iso8601", timeZone); -assert.sameValue(result9.timeZone.id, "UTC", "date-time + offset + IANA annotation is the IANA time zone"); -const result10 = Temporal.Now.zonedDateTime("iso8601", { timeZone }); -assert.sameValue(result10.timeZone.id, "UTC", "date-time + offset + IANA annotation is the IANA time zone (string in property bag)"); +const result5 = Temporal.Now.zonedDateTime("iso8601", timeZone); +assert.sameValue(result5.timeZoneId, "UTC", "date-time + offset + IANA annotation is the IANA time zone"); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-string-leap-second.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-string-leap-second.js index b91fd58cdffa..64a0f7afcaaf 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-string-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-string-leap-second.js @@ -9,11 +9,8 @@ features: [Temporal] let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; -const result1 = Temporal.Now.zonedDateTime("iso8601", timeZone); -assert.sameValue(result1.timeZone.id, "UTC", "leap second is a valid ISO string for TimeZone"); -const result2 = Temporal.Now.zonedDateTime("iso8601", { timeZone }); -assert.sameValue(result2.timeZone.id, "UTC", "leap second is a valid ISO string for TimeZone (nested property)"); +const result = Temporal.Now.zonedDateTime("iso8601", timeZone); +assert.sameValue(result.timeZoneId, "UTC", "leap second is a valid ISO string for TimeZone"); timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; assert.throws(RangeError, () => Temporal.Now.zonedDateTime("iso8601", timeZone), "leap second in time zone name not valid"); -assert.throws(RangeError, () => Temporal.Now.zonedDateTime("iso8601", { timeZone }), "leap second in time zone name not valid (nested property)"); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-string-multiple-offsets.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-string-multiple-offsets.js index a7fbcb202b1b..a3e26f66a97f 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-string-multiple-offsets.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-string-multiple-offsets.js @@ -9,7 +9,5 @@ features: [Temporal] const timeZone = "2021-08-19T17:30:45.123456789+01:46[+01:45:30.987654321]"; -const result1 = Temporal.Now.zonedDateTime("iso8601", timeZone); -assert.sameValue(result1.timeZone.id, "+01:45:30.987654321", "Time zone string determined from bracket name"); -const result2 = Temporal.Now.zonedDateTime("iso8601", { timeZone }); -assert.sameValue(result2.timeZone.id, "+01:45:30.987654321", "Time zone string determined from bracket name"); +const result = Temporal.Now.zonedDateTime("iso8601", timeZone); +assert.sameValue(result.timeZoneId, "+01:45:30.987654321", "Time zone string determined from bracket name"); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-string-year-zero.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-string-year-zero.js index e27b3f173031..130ff02af3df 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-string-year-zero.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-string-year-zero.js @@ -17,9 +17,4 @@ invalidStrings.forEach((timeZone) => { () => Temporal.Now.zonedDateTime("iso8601", timeZone), "reject minus zero as extended year" ); - assert.throws( - RangeError, - () => Temporal.Now.zonedDateTime("iso8601", { timeZone }), - "reject minus zero as extended year (nested property)" - ); }); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-string.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-string.js index 6e5e37ced60b..773fc6673597 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-string.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-string.js @@ -4,10 +4,31 @@ /*--- esid: sec-temporal.now.zoneddatetime description: Time zone IDs are valid input for a time zone +includes: [temporalHelpers.js] features: [Temporal] ---*/ +const getPossibleInstantsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getPossibleInstantsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getPossibleInstantsFor should not be looked up"); + }, +}); +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + ["UTC", "+01:30"].forEach((timeZone) => { const result = Temporal.Now.zonedDateTime("iso8601", timeZone); - assert.sameValue(result.timeZone.id, timeZone, `Time zone created from string "${timeZone}"`); + assert.sameValue(result.getISOFields().timeZone, timeZone, `Time zone created from string "${timeZone}"`); }); + +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", getPossibleInstantsForOriginal); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-wrong-type.js index 2d309942c06b..12fd8c4204cd 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTime/timezone-wrong-type.js @@ -16,22 +16,18 @@ const rangeErrorTests = [ [1, "number that doesn't convert to a valid ISO string"], [19761118, "number that would convert to a valid ISO string in other contexts"], [1n, "bigint"], - [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of rangeErrorTests) { assert.throws(RangeError, () => Temporal.Now.zonedDateTime("iso8601", timeZone), `${description} does not convert to a valid ISO string`); - assert.throws(RangeError, () => Temporal.Now.zonedDateTime("iso8601", { timeZone }), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], + [{}, "object not implementing time zone protocol"], + [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of typeErrorTests) { assert.throws(TypeError, () => Temporal.Now.zonedDateTime("iso8601", timeZone), `${description} is not a valid object and does not convert to a string`); - assert.throws(TypeError, () => Temporal.Now.zonedDateTime("iso8601", { timeZone }), `${description} is not a valid object and does not convert to a string (nested property)`); } - -const timeZone = undefined; -assert.throws(RangeError, () => Temporal.Now.zonedDateTime("iso8601", { timeZone }), `undefined is always a RangeError as nested property`); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/return-value.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/return-value.js index fe5db1af9ac0..5e8bd4ceb2d0 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/return-value.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/return-value.js @@ -8,9 +8,7 @@ features: [Temporal] ---*/ const zdt = Temporal.Now.zonedDateTimeISO(); -const tz = Temporal.Now.timeZone(); +const tz = Temporal.Now.timeZoneId(); assert(zdt instanceof Temporal.ZonedDateTime); -assert(zdt.calendar instanceof Temporal.Calendar); -assert.sameValue(zdt.calendar.id, "iso8601"); -assert(zdt.timeZone instanceof Temporal.TimeZone); -assert.sameValue(zdt.timeZone.id, tz.id); +assert.sameValue(zdt.getISOFields().calendar, "iso8601", "calendar slot should store a string"); +assert.sameValue(zdt.getISOFields().timeZone, tz, "time zone slot should store a string"); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/time-zone-undefined.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/time-zone-undefined.js index 7ed6e7b47cd2..ed290b5c0c3d 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/time-zone-undefined.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/time-zone-undefined.js @@ -18,14 +18,14 @@ Object.defineProperty(Temporal.TimeZone, "from", { }, }); -const systemTimeZone = Temporal.Now.timeZone(); +const systemTimeZone = Temporal.Now.timeZoneId(); const resultExplicit = Temporal.Now.zonedDateTimeISO(undefined); -assert.sameValue(resultExplicit.timeZone.id, systemTimeZone.id); +assert.sameValue(resultExplicit.getISOFields().timeZone, systemTimeZone, "time zone slot should store a string"); assert.compareArray(actual, expected, "Temporal.TimeZone.from should not be called"); const resultImplicit = Temporal.Now.zonedDateTimeISO(); -assert.sameValue(resultImplicit.timeZone.id, systemTimeZone.id); +assert.sameValue(resultImplicit.getISOFields().timeZone, systemTimeZone, "time zone slot should store a string"); assert.compareArray(actual, expected, "Temporal.TimeZone.from should not be called"); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-case-insensitive.js index f79f5159efdb..75d1d3d85e45 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-case-insensitive.js @@ -9,4 +9,4 @@ features: [Temporal] const timeZone = 'UtC'; const result = Temporal.Now.zonedDateTimeISO(timeZone); -assert.sameValue(result.timeZone.id, 'UTC', `Time zone created from string "${timeZone}"`); +assert.sameValue(result.timeZoneId, 'UTC', `Time zone created from string "${timeZone}"`); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-instance-does-not-get-timeZone-property.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-instance-does-not-get-timeZone-property.js deleted file mode 100644 index e65094d5e2f5..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-instance-does-not-get-timeZone-property.js +++ /dev/null @@ -1,20 +0,0 @@ -// 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.now.zoneddatetimeiso -description: > - A Temporal.TimeZone instance passed to zonedDateTimeISO() does not have its - 'timeZone' property observably checked -features: [Temporal] ----*/ - -const timeZone = new Temporal.TimeZone("UTC"); -Object.defineProperty(timeZone, "timeZone", { - get() { - throw new Test262Error("timeZone.timeZone should not be accessed"); - }, -}); - -Temporal.Now.zonedDateTimeISO(timeZone); -Temporal.Now.zonedDateTimeISO({ timeZone }); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-object-fail-call-tostring.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-object-fail-call-tostring.js deleted file mode 100644 index 3fd409a7862f..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-object-fail-call-tostring.js +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-temporal.now.zoneddatetimeiso -description: Forwards error thrown by invoking "toString" property -features: [Temporal] ----*/ - -var timeZone = { - timeZone: { - timeZone: true, - toString: function() { - throw new Test262Error(); - }, - } -}; - -assert.throws(Test262Error, function() { - Temporal.Now.zonedDateTimeISO(timeZone); -}, 'Temporal.Now.zonedDateTimeISO(timeZone) throws a Test262Error exception'); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-object-fail-get-timezone.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-object-fail-get-timezone.js deleted file mode 100644 index a060e85b74ce..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-object-fail-get-timezone.js +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-temporal.now.zoneddatetimeiso -description: Forwards error thrown by retrieving value of "timeZone" property -features: [Temporal] ----*/ - -var timeZone = { - get timeZone() { - throw new Test262Error(); - }, -}; - -assert.throws(Test262Error, function() { - Temporal.Now.zonedDateTimeISO(timeZone); -}, 'Temporal.Now.zonedDateTimeISO(timeZone) throws a Test262Error exception'); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-object-fail-has-nested-timezone.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-object-fail-has-nested-timezone.js deleted file mode 100644 index 70fac1c67a8d..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-object-fail-has-nested-timezone.js +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-temporal.now.zoneddatetimeiso -description: Forwards error thrown by checking presence of nested "timeZone" property -features: [Proxy, Temporal] ----*/ - -var timeZone = { - timeZone: new Proxy({}, { - has: function(target, property) { - if (property === 'timeZone') { - throw new Test262Error(); - } - }, - }) -}; - -assert.throws(Test262Error, function() { - Temporal.Now.zonedDateTimeISO(timeZone); -}, 'Temporal.Now.zonedDateTimeISO(timeZone) throws a Test262Error exception'); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-object-fail-has-timezone.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-object-fail-has-timezone.js deleted file mode 100644 index 19227d733383..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-object-fail-has-timezone.js +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-temporal.now.zoneddatetimeiso -description: Forwards error thrown by checking presence of "timeZone" property -features: [Proxy, Temporal] ----*/ - -var timeZone = new Proxy({}, { - has: function(target, property) { - if (property === 'timeZone') { - throw new Test262Error(); - } - }, -}); - -assert.throws(Test262Error, function() { - Temporal.Now.zonedDateTimeISO(timeZone); -}, 'Temporal.Now.zonedDateTimeISO(timeZone) throws a Test262Error exception'); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-object.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-object.js index ae3489504e30..36be882fbf6b 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-object.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-object.js @@ -7,25 +7,12 @@ includes: [compareArray.js, temporalHelpers.js] features: [BigInt, Proxy, Temporal] ---*/ const actual = []; - const expected = [ - 'has timeZone.timeZone', - 'get timeZone.timeZone', - 'has nestedTimeZone.timeZone' + "has timeZone.getOffsetNanosecondsFor", + "has timeZone.getPossibleInstantsFor", + "has timeZone.id", ]; -const nestedTimeZone = TemporalHelpers.timeZoneObserver(actual, "nestedTimeZone", { - getOffsetNanosecondsFor(instant) { - assert.sameValue( - instant instanceof Temporal.Instant, - true, - 'The result of evaluating (instant instanceof Temporal.Instant) is expected to be true' - ); - - return -Number(instant.epochNanoseconds % 86400000000000n); - } -}); - const timeZone = TemporalHelpers.timeZoneObserver(actual, "timeZone", { getOffsetNanosecondsFor(instant) { assert.sameValue( @@ -37,7 +24,6 @@ const timeZone = TemporalHelpers.timeZoneObserver(actual, "timeZone", { return -Number(instant.epochNanoseconds % 86400000000000n); } }); -timeZone.timeZone = nestedTimeZone; Object.defineProperty(Temporal.TimeZone, 'from', { get() { @@ -47,4 +33,4 @@ Object.defineProperty(Temporal.TimeZone, 'from', { }); Temporal.Now.zonedDateTimeISO(timeZone); -assert.compareArray(actual, expected, 'The value of actual is expected to equal the value of expected'); +assert.compareArray(actual, expected, 'order of observable operations'); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-string-datetime.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-string-datetime.js index 6247a77756b4..fbba3f71b87d 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-string-datetime.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-string-datetime.js @@ -9,34 +9,23 @@ features: [Temporal] let timeZone = "2021-08-19T17:30"; assert.throws(RangeError, () => Temporal.Now.zonedDateTimeISO(timeZone), "bare date-time string is not a time zone"); -assert.throws(RangeError, () => Temporal.Now.zonedDateTimeISO({ timeZone }), "bare date-time string is not a time zone"); timeZone = "2021-08-19T17:30Z"; const result1 = Temporal.Now.zonedDateTimeISO(timeZone); -assert.sameValue(result1.timeZone.id, "UTC", "date-time + Z is UTC time zone"); -const result2 = Temporal.Now.zonedDateTimeISO({ timeZone }); -assert.sameValue(result2.timeZone.id, "UTC", "date-time + Z is UTC time zone (string in property bag)"); +assert.sameValue(result1.timeZoneId, "UTC", "date-time + Z is UTC time zone"); timeZone = "2021-08-19T17:30-07:00"; -const result3 = Temporal.Now.zonedDateTimeISO(timeZone); -assert.sameValue(result3.timeZone.id, "-07:00", "date-time + offset is the offset time zone"); -const result4 = Temporal.Now.zonedDateTimeISO({ timeZone }); -assert.sameValue(result4.timeZone.id, "-07:00", "date-time + offset is the offset time zone (string in property bag)"); +const result2 = Temporal.Now.zonedDateTimeISO(timeZone); +assert.sameValue(result2.timeZoneId, "-07:00", "date-time + offset is the offset time zone"); timeZone = "2021-08-19T17:30[UTC]"; -const result5 = Temporal.Now.zonedDateTimeISO(timeZone); -assert.sameValue(result5.timeZone.id, "UTC", "date-time + IANA annotation is the IANA time zone"); -const result6 = Temporal.Now.zonedDateTimeISO({ timeZone }); -assert.sameValue(result6.timeZone.id, "UTC", "date-time + IANA annotation is the IANA time zone (string in property bag)"); +const result3 = Temporal.Now.zonedDateTimeISO(timeZone); +assert.sameValue(result3.timeZoneId, "UTC", "date-time + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30Z[UTC]"; -const result7 = Temporal.Now.zonedDateTimeISO(timeZone); -assert.sameValue(result7.timeZone.id, "UTC", "date-time + Z + IANA annotation is the IANA time zone"); -const result8 = Temporal.Now.zonedDateTimeISO({ timeZone }); -assert.sameValue(result8.timeZone.id, "UTC", "date-time + Z + IANA annotation is the IANA time zone (string in property bag)"); +const result4 = Temporal.Now.zonedDateTimeISO(timeZone); +assert.sameValue(result4.timeZoneId, "UTC", "date-time + Z + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30-07:00[UTC]"; -const result9 = Temporal.Now.zonedDateTimeISO(timeZone); -assert.sameValue(result9.timeZone.id, "UTC", "date-time + offset + IANA annotation is the IANA time zone"); -const result10 = Temporal.Now.zonedDateTimeISO({ timeZone }); -assert.sameValue(result10.timeZone.id, "UTC", "date-time + offset + IANA annotation is the IANA time zone (string in property bag)"); +const result5 = Temporal.Now.zonedDateTimeISO(timeZone); +assert.sameValue(result5.timeZoneId, "UTC", "date-time + offset + IANA annotation is the IANA time zone"); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-string-leap-second.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-string-leap-second.js index f5a1dbaf77f2..f264837e0216 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-string-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-string-leap-second.js @@ -9,11 +9,8 @@ features: [Temporal] let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; -const result1 = Temporal.Now.zonedDateTimeISO(timeZone); -assert.sameValue(result1.timeZone.id, "UTC", "leap second is a valid ISO string for TimeZone"); -const result2 = Temporal.Now.zonedDateTimeISO({ timeZone }); -assert.sameValue(result2.timeZone.id, "UTC", "leap second is a valid ISO string for TimeZone (nested property)"); +const result = Temporal.Now.zonedDateTimeISO(timeZone); +assert.sameValue(result.timeZoneId, "UTC", "leap second is a valid ISO string for TimeZone"); timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; assert.throws(RangeError, () => Temporal.Now.zonedDateTimeISO(timeZone), "leap second in time zone name not valid"); -assert.throws(RangeError, () => Temporal.Now.zonedDateTimeISO({ timeZone }), "leap second in time zone name not valid (nested property)"); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-string-multiple-offsets.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-string-multiple-offsets.js index 676e54c03c34..1ecfceaff382 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-string-multiple-offsets.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-string-multiple-offsets.js @@ -9,7 +9,5 @@ features: [Temporal] const timeZone = "2021-08-19T17:30:45.123456789+01:46[+01:45:30.987654321]"; -const result1 = Temporal.Now.zonedDateTimeISO(timeZone); -assert.sameValue(result1.timeZone.id, "+01:45:30.987654321", "Time zone string determined from bracket name"); -const result2 = Temporal.Now.zonedDateTimeISO({ timeZone }); -assert.sameValue(result2.timeZone.id, "+01:45:30.987654321", "Time zone string determined from bracket name"); +const result = Temporal.Now.zonedDateTimeISO(timeZone); +assert.sameValue(result.timeZoneId, "+01:45:30.987654321", "Time zone string determined from bracket name"); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-string-year-zero.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-string-year-zero.js index 6417c0a787d3..70be388488fe 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-string-year-zero.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-string-year-zero.js @@ -17,9 +17,4 @@ invalidStrings.forEach((timeZone) => { () => Temporal.Now.zonedDateTimeISO(timeZone), "reject minus zero as extended year" ); - assert.throws( - RangeError, - () => Temporal.Now.zonedDateTimeISO({ timeZone }), - "reject minus zero as extended year (nested property)" - ); }); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-string.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-string.js index f47fe6b3f71c..9ec4d1b278f7 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-string.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-string.js @@ -4,10 +4,31 @@ /*--- esid: sec-temporal.now.zoneddatetimeiso description: Time zone IDs are valid input for a time zone +includes: [temporalHelpers.js] features: [Temporal] ---*/ +const getPossibleInstantsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getPossibleInstantsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getPossibleInstantsFor should not be looked up"); + }, +}); +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + ["UTC", "+01:30"].forEach((timeZone) => { const result = Temporal.Now.zonedDateTimeISO(timeZone); - assert.sameValue(result.timeZone.id, timeZone, `Time zone created from string "${timeZone}"`); + assert.sameValue(result.getISOFields().timeZone, timeZone, `Time zone created from string "${timeZone}"`); }); + +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", getPossibleInstantsForOriginal); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-wrong-type.js index 19f208c05091..5b75622ed16f 100644 --- a/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/Now/zonedDateTimeISO/timezone-wrong-type.js @@ -16,22 +16,18 @@ const rangeErrorTests = [ [1, "number that doesn't convert to a valid ISO string"], [19761118, "number that would convert to a valid ISO string in other contexts"], [1n, "bigint"], - [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of rangeErrorTests) { assert.throws(RangeError, () => Temporal.Now.zonedDateTimeISO(timeZone), `${description} does not convert to a valid ISO string`); - assert.throws(RangeError, () => Temporal.Now.zonedDateTimeISO({ timeZone }), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], + [{}, "object not implementing time zone protocol"], + [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of typeErrorTests) { assert.throws(TypeError, () => Temporal.Now.zonedDateTimeISO(timeZone), `${description} is not a valid object and does not convert to a string`); - assert.throws(TypeError, () => Temporal.Now.zonedDateTimeISO({ timeZone }), `${description} is not a valid object and does not convert to a string (nested property)`); } - -const timeZone = undefined; -assert.throws(RangeError, () => Temporal.Now.zonedDateTimeISO({ timeZone }), `undefined is always a RangeError as nested property`); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/basic.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/basic.js index 11d5b4ae78fa..36f65021b6b3 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/basic.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/basic.js @@ -17,9 +17,9 @@ Object.defineProperty(Temporal.Calendar, "from", { const calendar = new Temporal.Calendar("iso8601"); const plainDateWithObject = new Temporal.PlainDate(2020, 12, 24, calendar); TemporalHelpers.assertPlainDate(plainDateWithObject, 2020, 12, "M12", 24, "with object"); -assert.sameValue(plainDateWithObject.calendar, calendar); +assert.sameValue(plainDateWithObject.getCalendar(), calendar); const plainDateWithString = new Temporal.PlainDate(2020, 12, 24, "iso8601"); TemporalHelpers.assertPlainDate(plainDateWithString, 2020, 12, "M12", 24, "with string"); -assert.sameValue(plainDateWithString.calendar.toString(), "iso8601"); -assert.notSameValue(plainDateWithString.calendar, calendar); +assert.sameValue(plainDateWithString.getISOFields().calendar, "iso8601", "calendar slot should store a string"); +assert.notSameValue(plainDateWithString.getCalendar(), calendar); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/calendar-case-insensitive.js index d0265180c9d8..ab5ef646fd89 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/calendar-case-insensitive.js @@ -10,4 +10,4 @@ features: [Temporal] const arg = "iSo8601"; const result = new Temporal.PlainDate(2000, 5, 2, arg); -assert.sameValue(result.calendar.id, "iso8601", "Calendar is case-insensitive"); +assert.sameValue(result.calendarId, "iso8601", "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 78d74ae71e01..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,20 +0,0 @@ -// 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 -description: > - A Temporal.Calendar instance passed to new PlainDate() does not have - its 'calendar' property observably checked -features: [Temporal] ----*/ - -const arg = new Temporal.Calendar("iso8601"); -Object.defineProperty(arg, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -new Temporal.PlainDate(2000, 5, 2, arg); -new Temporal.PlainDate(2000, 5, 2, { calendar: arg }); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/calendar-number.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/calendar-number.js index 8fdba7016482..be222b1c4c20 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/calendar-number.js @@ -10,7 +10,7 @@ features: [Temporal] const arg = 19761118; const result = new Temporal.PlainDate(2000, 5, 2, arg); -assert.sameValue(result.calendar.id, "iso8601", "19761118 is a valid ISO string for Calendar"); +assert.sameValue(result.calendarId, "iso8601", "19761118 is a valid ISO string for Calendar"); const numbers = [ 1, diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/calendar-string.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/calendar-string.js index 252f3ae1458a..228b6e94897a 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/calendar-string.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/calendar-string.js @@ -10,4 +10,4 @@ features: [Temporal] const arg = "iso8601"; const result = new Temporal.PlainDate(2000, 5, 2, arg); -assert.sameValue(result.calendar.id, "iso8601", `Calendar created from string "${arg}"`); +assert.sameValue(result.getISOFields().calendar, "iso8601", `Calendar created from string "${arg}"`); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/calendar-temporal-object.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/calendar-temporal-object.js index 6eb1d42f825d..57d527fb38b9 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/calendar-temporal-object.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/calendar-temporal-object.js @@ -6,7 +6,7 @@ esid: sec-temporal.plaindate description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots info: | sec-temporal-totemporalcalendar step 1.b: - b. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then + b. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then i. Return _temporalCalendarLike_.[[Calendar]]. includes: [compareArray.js] features: [Temporal] @@ -14,12 +14,11 @@ features: [Temporal] const plainDate = new Temporal.PlainDate(2000, 5, 2); const plainDateTime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); -const plainTime = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); const plainMonthDay = new Temporal.PlainMonthDay(5, 2); const plainYearMonth = new Temporal.PlainYearMonth(2000, 5); const zonedDateTime = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); -[plainDate, plainDateTime, plainTime, plainMonthDay, plainYearMonth, zonedDateTime].forEach((arg) => { +[plainDate, plainDateTime, plainMonthDay, plainYearMonth, zonedDateTime].forEach((arg) => { const actual = []; const expected = []; @@ -33,7 +32,7 @@ const zonedDateTime = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UT }); const result = new Temporal.PlainDate(2000, 5, 2, arg); - assert.sameValue(result.calendar, calendar, "Temporal object coerced to calendar"); + assert.sameValue(result.getISOFields().calendar, calendar, "Temporal object coerced to calendar"); assert.compareArray(actual, expected, "calendar getter not called"); }); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/calendar-undefined.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/calendar-undefined.js index 945fc0dd125d..bd0f7e5dd673 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/calendar-undefined.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/calendar-undefined.js @@ -16,7 +16,7 @@ Object.defineProperty(Temporal.Calendar, "from", { }); const dateExplicit = new Temporal.PlainDate(...args, undefined); -assert.sameValue(dateExplicit.calendar.toString(), "iso8601"); +assert.sameValue(dateExplicit.getISOFields().calendar, "iso8601", "calendar slot should store string"); const dateImplicit = new Temporal.PlainDate(...args); -assert.sameValue(dateImplicit.calendar.toString(), "iso8601"); +assert.sameValue(dateImplicit.getISOFields().calendar, "iso8601", "calendar slot should store string"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/calendar-wrong-type.js index 10370ab28dbe..f79b226b84f8 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/calendar-wrong-type.js @@ -23,6 +23,9 @@ for (const [arg, description] of rangeErrorTests) { const typeErrorTests = [ [Symbol(), "symbol"], + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], ]; for (const [arg, description] of typeErrorTests) { diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-case-insensitive.js index f1c81c7b1b4d..964ee7d1b416 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-case-insensitive.js @@ -9,14 +9,8 @@ features: [Temporal] const calendar = "IsO8601"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; const result1 = Temporal.PlainDate.compare(arg, new Temporal.PlainDate(1976, 11, 18)); assert.sameValue(result1, 0, "Calendar is case-insensitive (first argument)"); const result2 = Temporal.PlainDate.compare(new Temporal.PlainDate(1976, 11, 18), arg); assert.sameValue(result2, 0, "Calendar is case-insensitive (second argument)"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result3 = Temporal.PlainDate.compare(arg, new Temporal.PlainDate(1976, 11, 18)); -assert.sameValue(result3, 0, "Calendar is case-insensitive (nested property, first argument)"); -const result4 = Temporal.PlainDate.compare(new Temporal.PlainDate(1976, 11, 18), arg); -assert.sameValue(result4, 0, "Calendar is case-insensitive (nested property, second argument)"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 65dc0d458573..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,20 +0,0 @@ -// 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.compare -description: > - A Temporal.Calendar instance passed to compare() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -Temporal.PlainDate.compare(arg, arg); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-leap-second.js index 94b12a67ab79..bfe3ff02e6b7 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-leap-second.js @@ -9,14 +9,8 @@ features: [Temporal] const calendar = "2016-12-31T23:59:60"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; const result1 = Temporal.PlainDate.compare(arg, new Temporal.PlainDate(1976, 11, 18)); assert.sameValue(result1, 0, "leap second is a valid ISO string for calendar (first argument)"); const result2 = Temporal.PlainDate.compare(new Temporal.PlainDate(1976, 11, 18), arg); assert.sameValue(result2, 0, "leap second is a valid ISO string for calendar (first argument)"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result3 = Temporal.PlainDate.compare(arg, new Temporal.PlainDate(1976, 11, 18)); -assert.sameValue(result3, 0, "leap second is a valid ISO string for calendar (nested property, first argument)"); -const result4 = Temporal.PlainDate.compare(new Temporal.PlainDate(1976, 11, 18), arg); -assert.sameValue(result4, 0, "leap second is a valid ISO string for calendar (nested property, second argument)"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-number.js index debcfec9c198..6e85dcc654df 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-number.js @@ -9,18 +9,12 @@ features: [Temporal] const calendar = 19970327; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; const result1 = Temporal.PlainDate.compare(arg, new Temporal.PlainDate(1976, 11, 18)); assert.sameValue(result1, 0, "19970327 is a valid ISO string for calendar (first argument)"); const result2 = Temporal.PlainDate.compare(new Temporal.PlainDate(1976, 11, 18), arg); assert.sameValue(result2, 0, "19970327 is a valid ISO string for calendar (first argument)"); -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result3 = Temporal.PlainDate.compare(arg, new Temporal.PlainDate(1976, 11, 18)); -assert.sameValue(result3, 0, "19970327 is a valid ISO string for calendar (nested property, first argument)"); -const result4 = Temporal.PlainDate.compare(new Temporal.PlainDate(1976, 11, 18), arg); -assert.sameValue(result4, 0, "19970327 is a valid ISO string for calendar (nested property, first argument)"); - const numbers = [ 1, -19970327, @@ -28,7 +22,7 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; assert.throws( RangeError, () => Temporal.PlainDate.compare(arg, new Temporal.PlainDate(1976, 11, 18)), @@ -39,15 +33,4 @@ for (const calendar of numbers) { () => Temporal.PlainDate.compare(new Temporal.PlainDate(1976, 11, 18), arg), `Number ${calendar} does not convert to a valid ISO string for calendar (second argument)` ); - arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; - assert.throws( - RangeError, - () => Temporal.PlainDate.compare(arg, new Temporal.PlainDate(1976, 11, 18)), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property, first argument)` - ); - assert.throws( - RangeError, - () => Temporal.PlainDate.compare(new Temporal.PlainDate(1976, 11, 18), arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property, second argument)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-string.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-string.js index c400baee24a7..0556a490be6b 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-string.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-string.js @@ -4,9 +4,19 @@ /*--- esid: sec-temporal.plaindate.compare description: A calendar ID is valid input for Calendar +includes: [temporalHelpers.js] features: [Temporal] ---*/ +const dateFromFieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dateFromFields"); +Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("dateFromFields should not be looked up"); + }, +}); + const calendar = "iso8601"; const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; @@ -16,3 +26,5 @@ assert.sameValue(result1, 0, `Calendar created from string "${arg}" (first argum const result2 = Temporal.PlainDate.compare(new Temporal.PlainDate(1976, 11, 18), arg); assert.sameValue(result2, 0, `Calendar created from string "${arg}" (second argument)`); + +Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", dateFromFieldsOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-wrong-type.js index 41814c6015d2..964b88e9d832 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-wrong-type.js @@ -15,36 +15,24 @@ const rangeErrorTests = [ ["", "empty string"], [1, "number that doesn't convert to a valid ISO string"], [1n, "bigint"], - [new Temporal.TimeZone("UTC"), "time zone instance"], ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => Temporal.PlainDate.compare(arg, new Temporal.PlainDate(1976, 11, 18)), `${description} does not convert to a valid ISO string (first argument)`); assert.throws(RangeError, () => Temporal.PlainDate.compare(new Temporal.PlainDate(1976, 11, 18), arg), `${description} does not convert to a valid ISO string (second argument)`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => Temporal.PlainDate.compare(arg, new Temporal.PlainDate(1976, 11, 18)), `${description} does not convert to a valid ISO string (nested property, first argument)`); - assert.throws(RangeError, () => Temporal.PlainDate.compare(new Temporal.PlainDate(1976, 11, 18), arg), `${description} does not convert to a valid ISO string (nested property, second argument)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => Temporal.PlainDate.compare(arg, new Temporal.PlainDate(1976, 11, 18)), `${description} is not a valid property bag and does not convert to a string (first argument)`); assert.throws(TypeError, () => Temporal.PlainDate.compare(new Temporal.PlainDate(1976, 11, 18), arg), `${description} is not a valid property bag and does not convert to a string (second argument)`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => Temporal.PlainDate.compare(arg, new Temporal.PlainDate(1976, 11, 18)), `${description} is not a valid property bag and does not convert to a string (nested property, first argument)`); - assert.throws(TypeError, () => Temporal.PlainDate.compare(new Temporal.PlainDate(1976, 11, 18), arg), `${description} is not a valid property bag and does not convert to a string (nested property, second argument)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => Temporal.PlainDate.compare(arg, new Temporal.PlainDate(1976, 11, 18)), `nested undefined calendar property is always a RangeError (first argument)`); -assert.throws(RangeError, () => Temporal.PlainDate.compare(new Temporal.PlainDate(1976, 11, 18), arg), `nested undefined calendar property is always a RangeError (second argument)`); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/compare/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/compare/argument-string-calendar-annotation.js index 2b6387d693dd..96abd031e98f 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/compare/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/compare/argument-string-calendar-annotation.js @@ -15,7 +15,6 @@ const tests = [ ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; tests.forEach(([arg, description]) => { diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/compare/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/compare/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..2b6d69efe3fc --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/compare/argument-string-multiple-calendar.js @@ -0,0 +1,34 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.compare +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; + +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => Temporal.PlainDate.compare(arg, new Temporal.PlainDate(1976, 11, 18)), + `reject more than one calendar annotation if any critical: ${arg} (first argument)` + ); + assert.throws( + RangeError, + () => Temporal.PlainDate.compare(new Temporal.PlainDate(1976, 11, 18), arg), + `reject more than one calendar annotation if any critical: ${arg} (second argument)` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-plaindate.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-plaindate.js index 876d64eb2b23..e0ac9111e05d 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-plaindate.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-plaindate.js @@ -17,7 +17,7 @@ TemporalHelpers.assertPlainDate( "PlainDate is copied" ); -assert.sameValue(result.calendar, orig.calendar, "Calendar is copied"); +assert.sameValue(result.getISOFields().calendar, orig.getISOFields().calendar, "Calendar is copied"); assert.notSameValue( result, diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-plaindatetime.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-plaindatetime.js index b8b4b0fac316..498037c245f4 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-plaindatetime.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-plaindatetime.js @@ -17,5 +17,5 @@ features: [Temporal] TemporalHelpers.checkPlainDateTimeConversionFastPath((datetime, calendar) => { const result = Temporal.PlainDate.from(datetime); TemporalHelpers.assertPlainDate(result, 2000, 5, "M05", 2); - assert.sameValue(result.calendar, calendar, "calendar result"); + assert.sameValue(result.getCalendar(), calendar, "calendar result"); }); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-case-insensitive.js index e756f79c550b..a85901e4f26c 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-case-insensitive.js @@ -10,10 +10,6 @@ features: [Temporal] const calendar = "IsO8601"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = Temporal.PlainDate.from(arg); -TemporalHelpers.assertPlainDate(result1, 1976, 11, "M11", 18, "Calendar is case-insensitive"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = Temporal.PlainDate.from(arg); -TemporalHelpers.assertPlainDate(result2, 1976, 11, "M11", 18, "Calendar is case-insensitive (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = Temporal.PlainDate.from(arg); +TemporalHelpers.assertPlainDate(result, 1976, 11, "M11", 18, "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index cb48821b06e3..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,23 +0,0 @@ -// 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.from -description: > - A Temporal.Calendar instance passed to from() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -Temporal.PlainDate.from(arg); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -Temporal.PlainDate.from(arg); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-leap-second.js index 4455b5fc2fc1..b5c3020547a8 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-leap-second.js @@ -10,18 +10,10 @@ features: [Temporal] const calendar = "2016-12-31T23:59:60"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = Temporal.PlainDate.from(arg); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = Temporal.PlainDate.from(arg); TemporalHelpers.assertPlainDate( - result1, + result, 1976, 11, "M11", 18, "leap second is a valid ISO string for calendar" ); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = Temporal.PlainDate.from(arg); -TemporalHelpers.assertPlainDate( - result2, - 1976, 11, "M11", 18, - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-number.js index 634405c73458..9a1079efd13a 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-number.js @@ -10,13 +10,9 @@ features: [Temporal] const calendar = 19970327; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = Temporal.PlainDate.from(arg); -TemporalHelpers.assertPlainDate(result1, 1976, 11, "M11", 18, "19970327 is a valid ISO string for calendar"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = Temporal.PlainDate.from(arg); -TemporalHelpers.assertPlainDate(result2, 1976, 11, "M11", 18, "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = Temporal.PlainDate.from(arg); +TemporalHelpers.assertPlainDate(result, 1976, 11, "M11", 18, "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -25,16 +21,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; assert.throws( RangeError, () => Temporal.PlainDate.from(arg), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; - assert.throws( - RangeError, - () => Temporal.PlainDate.from(arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-string.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-string.js index 686f2dd05229..72bea4c95a62 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-string.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-string.js @@ -13,3 +13,4 @@ const calendar = "iso8601"; const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; const result = Temporal.PlainDate.from(arg); TemporalHelpers.assertPlainDate(result, 1976, 11, "M11", 18, `Calendar created from string "${calendar}"`); +assert.sameValue(result.getISOFields().calendar, "iso8601", "calendar slot stores a string"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-wrong-type.js index 9cb16543edba..c2e3954b7520 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-wrong-type.js @@ -18,27 +18,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => Temporal.PlainDate.from(arg), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => Temporal.PlainDate.from(arg), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => Temporal.PlainDate.from(arg), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => Temporal.PlainDate.from(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => Temporal.PlainDate.from(arg), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar.js index 8747c7ecc7ae..c1b6eb5de30c 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar.js @@ -11,4 +11,4 @@ features: [Temporal] const calendar = new Temporal.Calendar("iso8601"); const plainDate = Temporal.PlainDate.from({ year: 1976, month: 11, day: 18, calendar }); TemporalHelpers.assertPlainDate(plainDate, 1976, 11, "M11", 18); -assert.sameValue(plainDate.calendar, calendar); +assert.sameValue(plainDate.getISOFields().calendar, "iso8601", "calendar slot should store a string"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-string-calendar-annotation.js index 617ac7eb7edd..bc2ad03ebed2 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-string-calendar-annotation.js @@ -16,7 +16,6 @@ const tests = [ ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; tests.forEach(([arg, description]) => { diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..cba13a6aecc5 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.from +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; + +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => Temporal.PlainDate.from(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-zoneddatetime.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-zoneddatetime.js index 133ea14f897d..6288a5e7822e 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-zoneddatetime.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/from/argument-zoneddatetime.js @@ -19,7 +19,7 @@ TemporalHelpers.assertPlainDate( ); assert.sameValue( - result.calendar, + result.getCalendar(), calendar, "Calendar is copied" ); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/from/calendar-temporal-object.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/from/calendar-temporal-object.js index 47a50806141b..8960848b0ccf 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/from/calendar-temporal-object.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/from/calendar-temporal-object.js @@ -22,5 +22,5 @@ features: [Temporal] TemporalHelpers.checkToTemporalCalendarFastPath((temporalObject, calendar) => { const result = Temporal.PlainDate.from({ year: 2000, month: 5, day: 2, calendar: temporalObject }); - assert.sameValue(result.calendar, calendar, "Temporal object coerced to calendar"); + assert.sameValue(result.getCalendar(), calendar, "Temporal object coerced to calendar"); }); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/from/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/from/order-of-operations.js index cf7681900f4c..e0f621e891b7 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/from/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/from/order-of-operations.js @@ -10,7 +10,27 @@ features: [Temporal] const expected = [ "get fields.calendar", - "has fields.calendar.calendar", + "has fields.calendar.dateAdd", + "has fields.calendar.dateFromFields", + "has fields.calendar.dateUntil", + "has fields.calendar.day", + "has fields.calendar.dayOfWeek", + "has fields.calendar.dayOfYear", + "has fields.calendar.daysInMonth", + "has fields.calendar.daysInWeek", + "has fields.calendar.daysInYear", + "has fields.calendar.fields", + "has fields.calendar.id", + "has fields.calendar.inLeapYear", + "has fields.calendar.mergeFields", + "has fields.calendar.month", + "has fields.calendar.monthCode", + "has fields.calendar.monthDayFromFields", + "has fields.calendar.monthsInYear", + "has fields.calendar.weekOfYear", + "has fields.calendar.year", + "has fields.calendar.yearMonthFromFields", + "has fields.calendar.yearOfWeek", "get fields.calendar.fields", "call fields.calendar.fields", "get fields.day", diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/add/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/add/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..2791e757fdef --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/add/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.add +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const dateAddOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dateAdd"); +Object.defineProperty(Temporal.Calendar.prototype, "dateAdd", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("dateAdd should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDate(2000, 5, 2, "iso8601"); +instance.add(new Temporal.Duration(1)); + +Object.defineProperty(Temporal.Calendar.prototype, "dateAdd", dateAddOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/calendar/branding.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/calendar/branding.js deleted file mode 100644 index fc28805d6a55..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/calendar/branding.js +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-get-temporal.plaindate.prototype.calendar -description: Throw a TypeError if the receiver is invalid -features: [Symbol, Temporal] ----*/ - -const calendar = Object.getOwnPropertyDescriptor(Temporal.PlainDate.prototype, "calendar").get; - -assert.sameValue(typeof calendar, "function"); - -assert.throws(TypeError, () => calendar.call(undefined), "undefined"); -assert.throws(TypeError, () => calendar.call(null), "null"); -assert.throws(TypeError, () => calendar.call(true), "true"); -assert.throws(TypeError, () => calendar.call(""), "empty string"); -assert.throws(TypeError, () => calendar.call(Symbol()), "symbol"); -assert.throws(TypeError, () => calendar.call(1), "1"); -assert.throws(TypeError, () => calendar.call({}), "plain object"); -assert.throws(TypeError, () => calendar.call(Temporal.PlainDate), "Temporal.PlainDate"); -assert.throws(TypeError, () => calendar.call(Temporal.PlainDate.prototype), "Temporal.PlainDate.prototype"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/calendar/prop-desc.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/calendar/prop-desc.js deleted file mode 100644 index 6a40d4aa3c4b..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/calendar/prop-desc.js +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-get-temporal.plaindate.prototype.calendar -description: The "calendar" property of Temporal.PlainDate.prototype -features: [Temporal] ----*/ - -const descriptor = Object.getOwnPropertyDescriptor(Temporal.PlainDate.prototype, "calendar"); -assert.sameValue(typeof descriptor.get, "function"); -assert.sameValue(descriptor.set, undefined); -assert.sameValue(descriptor.enumerable, false); -assert.sameValue(descriptor.configurable, true); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/calendarId/branding.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/calendarId/branding.js new file mode 100644 index 000000000000..5a63691e87db --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/calendarId/branding.js @@ -0,0 +1,22 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-get-temporal.plaindate.prototype.calendarid +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const calendarId = Object.getOwnPropertyDescriptor(Temporal.PlainDate.prototype, "calendarId").get; + +assert.sameValue(typeof calendarId, "function"); + +assert.throws(TypeError, () => calendarId.call(undefined), "undefined"); +assert.throws(TypeError, () => calendarId.call(null), "null"); +assert.throws(TypeError, () => calendarId.call(true), "true"); +assert.throws(TypeError, () => calendarId.call(""), "empty string"); +assert.throws(TypeError, () => calendarId.call(Symbol()), "symbol"); +assert.throws(TypeError, () => calendarId.call(1), "1"); +assert.throws(TypeError, () => calendarId.call({}), "plain object"); +assert.throws(TypeError, () => calendarId.call(Temporal.PlainDate), "Temporal.PlainDate"); +assert.throws(TypeError, () => calendarId.call(Temporal.PlainDate.prototype), "Temporal.PlainDate.prototype"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/calendarId/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/calendarId/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..4f655e84d462 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/calendarId/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.calendarid +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const idOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "id"); +Object.defineProperty(Temporal.Calendar.prototype, "id", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("id should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDate(2000, 5, 2, "iso8601"); +instance.calendarId; + +Object.defineProperty(Temporal.Calendar.prototype, "id", idOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/calendarId/prop-desc.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/calendarId/prop-desc.js new file mode 100644 index 000000000000..212f06407dc4 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/calendarId/prop-desc.js @@ -0,0 +1,14 @@ +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-get-temporal.plaindate.prototype.calendarid +description: The "calendarId" property of Temporal.PlainDate.prototype +features: [Temporal] +---*/ + +const descriptor = Object.getOwnPropertyDescriptor(Temporal.PlainDate.prototype, "calendarId"); +assert.sameValue(typeof descriptor.get, "function"); +assert.sameValue(descriptor.set, undefined); +assert.sameValue(descriptor.enumerable, false); +assert.sameValue(descriptor.configurable, true); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/day/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/day/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..28fccb927429 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/day/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.day +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const dayOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "day"); +Object.defineProperty(Temporal.Calendar.prototype, "day", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("day should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDate(2000, 5, 2, "iso8601"); +instance.day; + +Object.defineProperty(Temporal.Calendar.prototype, "day", dayOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/dayOfWeek/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/dayOfWeek/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..dab5c5c6e413 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/dayOfWeek/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.dayofweek +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const dayOfWeekOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dayOfWeek"); +Object.defineProperty(Temporal.Calendar.prototype, "dayOfWeek", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("dayOfWeek should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDate(2000, 5, 2, "iso8601"); +instance.dayOfWeek; + +Object.defineProperty(Temporal.Calendar.prototype, "dayOfWeek", dayOfWeekOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/dayOfYear/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/dayOfYear/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..bfb8706e17f0 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/dayOfYear/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.dayofyear +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const dayOfYearOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dayOfYear"); +Object.defineProperty(Temporal.Calendar.prototype, "dayOfYear", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("dayOfYear should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDate(2000, 5, 2, "iso8601"); +instance.dayOfYear; + +Object.defineProperty(Temporal.Calendar.prototype, "dayOfYear", dayOfYearOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/daysInMonth/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/daysInMonth/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..e33ba86814f7 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/daysInMonth/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.daysinmonth +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const daysInMonthOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "daysInMonth"); +Object.defineProperty(Temporal.Calendar.prototype, "daysInMonth", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("daysInMonth should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDate(2000, 5, 2, "iso8601"); +instance.daysInMonth; + +Object.defineProperty(Temporal.Calendar.prototype, "daysInMonth", daysInMonthOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/daysInWeek/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/daysInWeek/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..3c00d1f77054 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/daysInWeek/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.daysinweek +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const daysInWeekOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "daysInWeek"); +Object.defineProperty(Temporal.Calendar.prototype, "daysInWeek", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("daysInWeek should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDate(2000, 5, 2, "iso8601"); +instance.daysInWeek; + +Object.defineProperty(Temporal.Calendar.prototype, "daysInWeek", daysInWeekOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/daysInYear/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/daysInYear/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..9c5337fbea3a --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/daysInYear/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.daysinyear +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const daysInYearOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "daysInYear"); +Object.defineProperty(Temporal.Calendar.prototype, "daysInYear", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("daysInYear should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDate(2000, 5, 2, "iso8601"); +instance.daysInYear; + +Object.defineProperty(Temporal.Calendar.prototype, "daysInYear", daysInYearOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/argument-object-valid.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/argument-object-valid.js index c87e6925d925..a20357f64dd4 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/argument-object-valid.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/argument-object-valid.js @@ -11,6 +11,28 @@ const instance = new Temporal.PlainDate(2000, 5, 2); assert.sameValue(instance.equals({ year: 2000, month: 5, day: 2 }), true, "same date"); assert.sameValue(instance.equals({ year: 2000, month: 5, day: 4 }), false, "different date"); -const calendar = { toString() { return "a" } }; +const calendar = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "a", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; assert.sameValue(instance.withCalendar(calendar).equals({ year: 2000, month: 5, day: 2 }), false, "different calendar"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/argument-propertybag-calendar-case-insensitive.js index 2bbc7834b36d..199fd6601b54 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/argument-propertybag-calendar-case-insensitive.js @@ -11,10 +11,6 @@ const instance = new Temporal.PlainDate(1976, 11, 18); const calendar = "IsO8601"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.equals(arg); -assert.sameValue(result1, true, "Calendar is case-insensitive"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.equals(arg); -assert.sameValue(result2, true, "Calendar is case-insensitive (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.equals(arg); +assert.sameValue(result, true, "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 863166bbfa46..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,25 +0,0 @@ -// 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.equals -description: > - A Temporal.Calendar instance passed to equals() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.PlainDate(1976, 11, 18); - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -instance.equals(arg); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -instance.equals(arg); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/argument-propertybag-calendar-leap-second.js index 2d24e808b237..e6fec068881d 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/argument-propertybag-calendar-leap-second.js @@ -11,18 +11,10 @@ const instance = new Temporal.PlainDate(1976, 11, 18); const calendar = "2016-12-31T23:59:60"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.equals(arg); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.equals(arg); assert.sameValue( - result1, + result, true, "leap second is a valid ISO string for calendar" ); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.equals(arg); -assert.sameValue( - result2, - true, - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/argument-propertybag-calendar-number.js index 22e505924f60..c8ebd39e1f46 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/argument-propertybag-calendar-number.js @@ -11,13 +11,9 @@ const instance = new Temporal.PlainDate(1976, 11, 18); const calendar = 19970327; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.equals(arg); -assert.sameValue(result1, true, "19970327 is a valid ISO string for calendar"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.equals(arg); -assert.sameValue(result2, true, "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.equals(arg); +assert.sameValue(result, true, "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -26,16 +22,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; assert.throws( RangeError, () => instance.equals(arg), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.equals(arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/argument-propertybag-calendar-wrong-type.js index 2e5f4c34bb25..13863fc0ea80 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/argument-propertybag-calendar-wrong-type.js @@ -21,27 +21,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.equals(arg), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.equals(arg), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.equals(arg), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.equals(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.equals(arg), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/argument-string-calendar-annotation.js index f92904cc57cd..5e047f19f43a 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/argument-string-calendar-annotation.js @@ -15,7 +15,6 @@ const tests = [ ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const instance = new Temporal.PlainDate(2000, 5, 2); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..3de0227eaf69 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.equals +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.PlainDate(2000, 5, 2); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.equals(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/argument-string.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/argument-string.js index 85e28ca874d2..9919d1756321 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/argument-string.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/argument-string.js @@ -11,5 +11,27 @@ const instance = new Temporal.PlainDate(2000, 5, 2); assert.sameValue(instance.equals("2000-05-02"), true, "same date"); assert.sameValue(instance.equals("2000-05-04"), false, "different date"); -const calendar = { toString() { return "a" } }; +const calendar = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "a", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; assert.sameValue(instance.withCalendar(calendar).equals("2000-05-02"), false, "different calendar"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..21b39b6353a6 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.equals +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const idOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "id"); +Object.defineProperty(Temporal.Calendar.prototype, "id", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("id should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDate(2000, 5, 2, "iso8601"); +instance.equals(new Temporal.PlainDate(2000, 5, 2)); + +Object.defineProperty(Temporal.Calendar.prototype, "id", idOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/calendar-call-different.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/calendar-call-different.js index b1e30dd71023..66be3ef1ac44 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/calendar-call-different.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/calendar-call-different.js @@ -4,27 +4,31 @@ /*--- esid: sec-temporal.plaindate.protoype.equals description: test if the calendar is compared +includes: [temporalHelpers.js] features: [Temporal] ---*/ -class CalendarTraceToString extends Temporal.Calendar { +class CalendarTraceId extends Temporal.Calendar { constructor(id) { super("iso8601"); this.id_ = id; this.calls = 0; } - toString() { + get id() { ++this.calls; return this.id_; } + toString() { + TemporalHelpers.assertUnreachable('toString should not be called'); + } }; -const calendar1 = new CalendarTraceToString("a"); +const calendar1 = new CalendarTraceId("a"); const date1 = new Temporal.PlainDate(1914, 2, 23, calendar1); -const calendar2 = new CalendarTraceToString("b"); +const calendar2 = new CalendarTraceId("b"); const date2 = new Temporal.PlainDate(1914, 2, 23, calendar2); assert.sameValue(date1.equals(date2), false, "different calendars"); -assert.sameValue(calendar1.calls, 1, "calendar1 toString() calls"); -assert.sameValue(calendar2.calls, 1, "calendar2 toString() calls"); +assert.sameValue(calendar1.calls, 1, "calendar1 id getter calls"); +assert.sameValue(calendar2.calls, 1, "calendar2 id getter calls"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/calendar-call-same.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/calendar-call-same.js index 2fea62c77e80..cf38dc08aaae 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/calendar-call-same.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/equals/calendar-call-same.js @@ -4,6 +4,7 @@ /*--- esid: sec-temporal.plaindate.protoype.equals description: test if the calendar is compared +includes: [temporalHelpers.js] features: [Temporal] ---*/ @@ -13,10 +14,13 @@ class CalendarTraceToString extends Temporal.Calendar { this.id_ = id; this.calls = 0; } - toString() { + get id() { ++this.calls; return this.id_; } + toString() { + TemporalHelpers.assertUnreachable('toString should not be called'); + } }; const calendar1 = new CalendarTraceToString("a"); @@ -26,5 +30,5 @@ const calendar2 = new CalendarTraceToString("a"); const date2 = new Temporal.PlainDate(1914, 2, 23, calendar2); assert.sameValue(date1.equals(date2), true, "same calendar id"); -assert.sameValue(calendar1.calls, 1, "calendar1 toString() calls"); -assert.sameValue(calendar2.calls, 1, "calendar2 toString() calls"); +assert.sameValue(calendar1.calls, 1, "calendar1 id getter calls"); +assert.sameValue(calendar2.calls, 1, "calendar2 id getter calls"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/getCalendar/branding.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/getCalendar/branding.js new file mode 100644 index 000000000000..c2b346989fb1 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/getCalendar/branding.js @@ -0,0 +1,22 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.getcalendar +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const getCalendar = Temporal.PlainDate.prototype.getCalendar; + +assert.sameValue(typeof getCalendar, "function"); + +assert.throws(TypeError, () => getCalendar.call(undefined), "undefined"); +assert.throws(TypeError, () => getCalendar.call(null), "null"); +assert.throws(TypeError, () => getCalendar.call(true), "true"); +assert.throws(TypeError, () => getCalendar.call(""), "empty string"); +assert.throws(TypeError, () => getCalendar.call(Symbol()), "symbol"); +assert.throws(TypeError, () => getCalendar.call(1), "1"); +assert.throws(TypeError, () => getCalendar.call({}), "plain object"); +assert.throws(TypeError, () => getCalendar.call(Temporal.PlainDate), "Temporal.PlainDate"); +assert.throws(TypeError, () => getCalendar.call(Temporal.PlainDate.prototype), "Temporal.PlainDate.prototype"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/getCalendar/builtin.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/getCalendar/builtin.js new file mode 100644 index 000000000000..08474bc03182 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/getCalendar/builtin.js @@ -0,0 +1,33 @@ +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.getcalendar +description: > + Tests that Temporal.PlainDate.prototype.getCalendar + meets the requirements for built-in objects defined by the + introduction of chapter 17 of the ECMAScript Language Specification. +info: | + Built-in functions that are not constructors do not have a "prototype" property unless + otherwise specified in the description of a particular function. + + Unless specified otherwise, a built-in object that is callable as a function is a built-in + function object with the characteristics described in 10.3. Unless specified otherwise, the + [[Extensible]] internal slot of a built-in object initially has the value true. + + Unless otherwise specified every built-in function and every built-in constructor has the + Function prototype object [...] as the value of its [[Prototype]] internal slot. +features: [Temporal] +---*/ + +assert.sameValue(Object.isExtensible(Temporal.PlainDate.prototype.getCalendar), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.PlainDate.prototype.getCalendar), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.PlainDate.prototype.getCalendar), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.PlainDate.prototype.getCalendar.hasOwnProperty("prototype"), + false, "prototype property"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/getCalendar/length.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/getCalendar/length.js new file mode 100644 index 000000000000..70b9d9017ff0 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/getCalendar/length.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.getcalendar +description: Temporal.PlainDate.prototype.getCalendar.length is 0 +info: | + Every built-in function object, including constructors, has a "length" property whose value is + an integer. Unless otherwise specified, this value is equal to the largest number of named + arguments shown in the subclause headings for the function description. Optional parameters + (which are indicated with brackets: [ ]) or rest parameters (which are shown using the form + «...name») are not included in the default argument count. + + Unless otherwise specified, the "length" property of a built-in function object has the + attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +verifyProperty(Temporal.PlainDate.prototype.getCalendar, "length", { + value: 0, + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/getCalendar/name.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/getCalendar/name.js new file mode 100644 index 000000000000..91189d8e6c7a --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/getCalendar/name.js @@ -0,0 +1,23 @@ +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.getcalendar +description: Temporal.PlainDate.prototype.getCalendar.name is "getCalendar". +info: | + Every built-in function object, including constructors, that is not identified as an anonymous + function has a "name" property whose value is a String. Unless otherwise specified, this value + is the name that is given to the function in this specification. + + Unless otherwise specified, the "name" property of a built-in function object, if it exists, + has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +verifyProperty(Temporal.PlainDate.prototype.getCalendar, "name", { + value: "getCalendar", + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/getCalendar/not-a-constructor.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/getCalendar/not-a-constructor.js new file mode 100644 index 000000000000..12675be19505 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/getCalendar/not-a-constructor.js @@ -0,0 +1,21 @@ +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.getcalendar +description: > + Temporal.PlainDate.prototype.getCalendar does not implement [[Construct]], is not new-able +info: | + Built-in function objects that are not identified as constructors do not implement the + [[Construct]] internal method unless otherwise specified in the description of a particular + function. +includes: [isConstructor.js] +features: [Reflect.construct, Temporal] +---*/ + +assert.throws(TypeError, () => { + new Temporal.PlainDate.prototype.getCalendar(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.PlainDate.prototype.getCalendar), false, + "isConstructor(Temporal.PlainDate.prototype.getCalendar)"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/getCalendar/prop-desc.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/getCalendar/prop-desc.js new file mode 100644 index 000000000000..1932c08e2f01 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/getCalendar/prop-desc.js @@ -0,0 +1,21 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.getcalendar +description: The "getCalendar" property of Temporal.PlainDate.prototype +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.PlainDate.prototype.getCalendar, + "function", + "`typeof PlainDate.prototype.getCalendar` is `function`" +); + +verifyProperty(Temporal.PlainDate.prototype, "getCalendar", { + writable: true, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/getISOFields/field-names.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/getISOFields/field-names.js index 1b8e5a944412..405459ab06eb 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/getISOFields/field-names.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/getISOFields/field-names.js @@ -13,4 +13,4 @@ const result = date.getISOFields(); assert.sameValue(result.isoYear, 2000, "isoYear result"); assert.sameValue(result.isoMonth, 5, "isoMonth result"); assert.sameValue(result.isoDay, 2, "isoDay result"); -assert.sameValue(result.calendar.id, "iso8601", "calendar result"); +assert.sameValue(result.calendar, "iso8601", "calendar result"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/inLeapYear/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/inLeapYear/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..a793bc1eef99 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/inLeapYear/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.inleapyear +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const inLeapYearOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "inLeapYear"); +Object.defineProperty(Temporal.Calendar.prototype, "inLeapYear", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("inLeapYear should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDate(2000, 5, 2, "iso8601"); +instance.inLeapYear; + +Object.defineProperty(Temporal.Calendar.prototype, "inLeapYear", inLeapYearOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/month/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/month/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..09a4464612f0 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/month/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.month +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const monthOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "month"); +Object.defineProperty(Temporal.Calendar.prototype, "month", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("month should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDate(2000, 5, 2, "iso8601"); +instance.month; + +Object.defineProperty(Temporal.Calendar.prototype, "month", monthOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/monthCode/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/monthCode/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..efe6f395f431 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/monthCode/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.monthcode +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const monthCodeOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "monthCode"); +Object.defineProperty(Temporal.Calendar.prototype, "monthCode", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("monthCode should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDate(2000, 5, 2, "iso8601"); +instance.monthCode; + +Object.defineProperty(Temporal.Calendar.prototype, "monthCode", monthCodeOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/monthsInYear/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/monthsInYear/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..896ae8f7bb09 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/monthsInYear/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.monthsinyear +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const monthsInYearOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "monthsInYear"); +Object.defineProperty(Temporal.Calendar.prototype, "monthsInYear", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("monthsInYear should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDate(2000, 5, 2, "iso8601"); +instance.monthsInYear; + +Object.defineProperty(Temporal.Calendar.prototype, "monthsInYear", monthsInYearOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-case-insensitive.js index 976d5920a3d5..3afedb0745ad 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-case-insensitive.js @@ -12,10 +12,6 @@ const instance = new Temporal.PlainDate(1976, 11, 18); const calendar = "IsO8601"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.since(arg); -TemporalHelpers.assertDuration(result1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Calendar is case-insensitive"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.since(arg); -TemporalHelpers.assertDuration(result2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Calendar is case-insensitive (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.since(arg); +TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 8a2685ebc4b4..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,25 +0,0 @@ -// 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.since -description: > - A Temporal.Calendar instance passed to since() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.PlainDate(1976, 11, 18); - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -instance.since(arg); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -instance.since(arg); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-leap-second.js index c65e3e141f37..ef6e5c44d69b 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-leap-second.js @@ -12,18 +12,10 @@ const instance = new Temporal.PlainDate(1976, 11, 18); const calendar = "2016-12-31T23:59:60"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.since(arg); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.since(arg); TemporalHelpers.assertDuration( - result1, + result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "leap second is a valid ISO string for calendar" ); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.since(arg); -TemporalHelpers.assertDuration( - result2, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-number.js index c1156c06dc25..8625ceb456cf 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-number.js @@ -12,13 +12,9 @@ const instance = new Temporal.PlainDate(1976, 11, 18); const calendar = 19970327; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.since(arg); -TemporalHelpers.assertDuration(result1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.since(arg); -TemporalHelpers.assertDuration(result2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.since(arg); +TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -27,16 +23,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; assert.throws( RangeError, () => instance.since(arg), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.since(arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-wrong-type.js index 3460f4019825..13329b627000 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-wrong-type.js @@ -21,27 +21,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.since(arg), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.since(arg), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.since(arg), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.since(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.since(arg), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/since/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/since/argument-string-calendar-annotation.js index 68279b7f3ddb..598fb0946b77 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/since/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/since/argument-string-calendar-annotation.js @@ -16,7 +16,6 @@ const tests = [ ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const instance = new Temporal.PlainDate(2000, 5, 2); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/since/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/since/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..4ea7fbfc5260 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/since/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.since +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.PlainDate(2000, 5, 2); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.since(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/since/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/since/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..9d9699cc1744 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/since/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.since +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const dateUntilOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dateUntil"); +Object.defineProperty(Temporal.Calendar.prototype, "dateUntil", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("dateUntil should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDate(2000, 5, 2, "iso8601"); +instance.since(new Temporal.PlainDate(1999, 4, 1)); + +Object.defineProperty(Temporal.Calendar.prototype, "dateUntil", dateUntilOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/since/calendar-mismatch.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/since/calendar-mismatch.js index eabfb22ad7c4..f8226f5f9c5d 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/since/calendar-mismatch.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/since/calendar-mismatch.js @@ -3,12 +3,56 @@ /*--- esid: sec-temporal.plaindate.prototype.since -description: RangeError thrown if calendars' toString results do not match +description: RangeError thrown if calendars' id properties do not match features: [Temporal] ---*/ -const calendar1 = { toString() { return "A"; } }; -const calendar2 = { toString() { return "B"; } }; +const calendar1 = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "A", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; +const calendar2 = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "B", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; const plainDate1 = new Temporal.PlainDate(2000, 1, 1, calendar1); const plainDate2 = new Temporal.PlainDate(2000, 1, 1, calendar2); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/since/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/since/order-of-operations.js index f8731590cd3a..cccbaf230c9c 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/since/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/since/order-of-operations.js @@ -11,7 +11,27 @@ features: [Temporal] const expected = [ // ToTemporalDate "get other.calendar", - "has other.calendar.calendar", + "has other.calendar.dateAdd", + "has other.calendar.dateFromFields", + "has other.calendar.dateUntil", + "has other.calendar.day", + "has other.calendar.dayOfWeek", + "has other.calendar.dayOfYear", + "has other.calendar.daysInMonth", + "has other.calendar.daysInWeek", + "has other.calendar.daysInYear", + "has other.calendar.fields", + "has other.calendar.id", + "has other.calendar.inLeapYear", + "has other.calendar.mergeFields", + "has other.calendar.month", + "has other.calendar.monthCode", + "has other.calendar.monthDayFromFields", + "has other.calendar.monthsInYear", + "has other.calendar.weekOfYear", + "has other.calendar.year", + "has other.calendar.yearMonthFromFields", + "has other.calendar.yearOfWeek", "get other.calendar.fields", "call other.calendar.fields", "get other.day", @@ -29,12 +49,8 @@ const expected = [ "get other.calendar.dateFromFields", "call other.calendar.dateFromFields", // CalendarEquals - "get this.calendar[Symbol.toPrimitive]", - "get this.calendar.toString", - "call this.calendar.toString", - "get other.calendar[Symbol.toPrimitive]", - "get other.calendar.toString", - "call other.calendar.toString", + "get this.calendar.id", + "get other.calendar.id", // CopyDataProperties "ownKeys options", "getOwnPropertyDescriptor options.roundingIncrement", diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/subtract/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/subtract/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..f23120c59174 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/subtract/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.subtract +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const dateAddOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dateAdd"); +Object.defineProperty(Temporal.Calendar.prototype, "dateAdd", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("dateAdd should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDate(2000, 5, 2, "iso8601"); +instance.subtract(new Temporal.Duration(1)); + +Object.defineProperty(Temporal.Calendar.prototype, "dateAdd", dateAddOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toJSON/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toJSON/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..bb0871ff3a50 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toJSON/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.tojson +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const idOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "id"); +Object.defineProperty(Temporal.Calendar.prototype, "id", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("id should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDate(2000, 5, 2, "iso8601"); +instance.toJSON(); + +Object.defineProperty(Temporal.Calendar.prototype, "id", idOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toLocaleString/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toLocaleString/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..7603e4557bc6 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toLocaleString/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.tolocalestring +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const idOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "id"); +Object.defineProperty(Temporal.Calendar.prototype, "id", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("id should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDate(2000, 5, 2, "iso8601"); +instance.toLocaleString(); + +Object.defineProperty(Temporal.Calendar.prototype, "id", idOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/argument-string-calendar-annotation.js index 0c6512df1af7..de2186fc6f83 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/argument-string-calendar-annotation.js @@ -21,8 +21,10 @@ const tests = [ ["1970-01-01T12:34:56.987654321[UTC][u-ca=iso8601]", "with date and time zone"], ["1970-01-01T12:34:56.987654321[!u-ca=iso8601]", "with !, date, and no time zone"], ["1970-01-01T12:34:56.987654321[UTC][!u-ca=iso8601]", "with !, date, and time zone"], + ["12:34:56.987654321[u-ca=hebrew]", "calendar annotation ignored"], + ["12:34:56.987654321[u-ca=unknown]", "calendar annotation ignored even if unknown calendar"], + ["12:34:56.987654321[!u-ca=unknown]", "calendar annotation ignored even if unknown calendar with !"], ["1970-01-01T12:34:56.987654321[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["1970-01-01T12:34:56.987654321[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const instance = new Temporal.PlainDate(2000, 5, 2); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..dec111bacac8 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.toplaindatetime +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "00:00[u-ca=iso8601][!u-ca=iso8601]", + "00:00[!u-ca=iso8601][u-ca=iso8601]", + "00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.PlainDate(2000, 5, 2); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.toPlainDateTime(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/calendar-temporal-object.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/calendar-temporal-object.js deleted file mode 100644 index 5f58688a5755..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/calendar-temporal-object.js +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (C) 2020 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.plaindate.prototype.toplaindatetime -description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots -info: | - sec-temporal.plaindate.prototype.toplaindatetime step 4: - 4. Set _temporalTime_ to ? ToTemporalTime(_temporalTime_). - sec-temporal-totemporaltime step 3.d: - d. If _calendar_ is not *undefined*, then - i. Set _calendar_ to ? ToTemporalCalendar(_calendar_). - ii. If ? ToString(_calendar_) is not *"iso8601"*, then - 1. Throw a *RangeError* exception. - sec-temporal-totemporalcalendar step 1.a: - a. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then - i. Return _temporalCalendarLike_.[[Calendar]]. -includes: [compareArray.js, temporalHelpers.js] -features: [Temporal] ----*/ - -TemporalHelpers.checkToTemporalCalendarFastPath((temporalObject) => { - const date = new Temporal.PlainDate(2000, 5, 2); - assert.throws(RangeError, () => date.toPlainDateTime({ hour: 12, minute: 30, calendar: temporalObject })); -}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/custom.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/custom.js index ead40f974c90..66a3208dd249 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/custom.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/custom.js @@ -11,4 +11,4 @@ features: [Temporal] const calendar = TemporalHelpers.calendarThrowEverything(); const plainDate = new Temporal.PlainDate(2000, 5, 2, calendar); const result = plainDate.toPlainDateTime("11:30:23"); -assert.sameValue(result.calendar, calendar, "calendar"); +assert.sameValue(result.getCalendar(), calendar, "calendar"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toPlainMonthDay/basic.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toPlainMonthDay/basic.js index 1c0001784076..c64b637bc331 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toPlainMonthDay/basic.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toPlainMonthDay/basic.js @@ -12,4 +12,4 @@ const calendar = new Temporal.Calendar("iso8601"); const pd = new Temporal.PlainDate(1970, 12, 24, calendar); const pmd = pd.toPlainMonthDay(); TemporalHelpers.assertPlainMonthDay(pmd, "M12", 24); -assert.sameValue(pmd.calendar, calendar); +assert.sameValue(pmd.getISOFields().calendar, "iso8601"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toPlainMonthDay/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toPlainMonthDay/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..961401456860 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toPlainMonthDay/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.toplainmonthday +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const monthDayFromFieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "monthDayFromFields"); +Object.defineProperty(Temporal.Calendar.prototype, "monthDayFromFields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("monthDayFromFields should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDate(2000, 5, 2, "iso8601"); +instance.toPlainMonthDay(); + +Object.defineProperty(Temporal.Calendar.prototype, "monthDayFromFields", monthDayFromFieldsOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toPlainYearMonth/basic.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toPlainYearMonth/basic.js index 1a8bb523fb50..d2c722c514d2 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toPlainYearMonth/basic.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toPlainYearMonth/basic.js @@ -12,4 +12,4 @@ const calendar = new Temporal.Calendar("iso8601"); const pd = new Temporal.PlainDate(1970, 12, 24, calendar); const pym = pd.toPlainYearMonth(); TemporalHelpers.assertPlainYearMonth(pym, 1970, 12, "M12"); -assert.sameValue(pym.calendar, calendar); +assert.sameValue(pym.getISOFields().calendar, "iso8601"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toPlainYearMonth/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toPlainYearMonth/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..9a1b0cabff7a --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toPlainYearMonth/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.toplainyearmonth +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const yearMonthFromFieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "yearMonthFromFields"); +Object.defineProperty(Temporal.Calendar.prototype, "yearMonthFromFields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("yearMonthFromFields should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDate(2000, 5, 2, "iso8601"); +instance.toPlainYearMonth(); + +Object.defineProperty(Temporal.Calendar.prototype, "yearMonthFromFields", yearMonthFromFieldsOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toString/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toString/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..fa597d0768fb --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toString/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 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: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const idOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "id"); +Object.defineProperty(Temporal.Calendar.prototype, "id", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("id should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDate(2000, 5, 2, "iso8601"); +instance.toString(); + +Object.defineProperty(Temporal.Calendar.prototype, "id", idOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toString/calendar-tostring.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toString/calendar-tostring.js index 7dd8ee3a49b2..e8f0edb7006e 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toString/calendar-tostring.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toString/calendar-tostring.js @@ -4,15 +4,39 @@ /*--- esid: sec-temporal.plaindate.protoype.tostring description: Number of observable 'toString' calls on the calendar for each value of calendarName +includes: [temporalHelpers.js] features: [Temporal] ---*/ let calls; const customCalendar = { - toString() { + get id() { ++calls; return "custom"; - } + }, + toString() { + TemporalHelpers.assertUnreachable('toString should not be called'); + }, + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, }; const date = new Temporal.PlainDate(2000, 5, 2, customCalendar); [ @@ -24,6 +48,6 @@ const date = new Temporal.PlainDate(2000, 5, 2, customCalendar); ].forEach(([calendarName, expectedResult, expectedCalls]) => { calls = 0; const result = date.toString({ calendarName }); - assert.sameValue(result, expectedResult, `toString output for calendarName = ${calendarName}`); - assert.sameValue(calls, expectedCalls, `calls to toString for calendarName = ${calendarName}`); + assert.sameValue(result, expectedResult, `id for calendarName = ${calendarName}`); + assert.sameValue(calls, expectedCalls, `calls to id getter for calendarName = ${calendarName}`); }); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toString/calendarname-always.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toString/calendarname-always.js index 607a9f660c9c..a5621276a5f4 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toString/calendarname-always.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toString/calendarname-always.js @@ -7,12 +7,35 @@ description: If calendarName is "always", the calendar ID should be included. features: [Temporal] ---*/ +const calendarMethods = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; + const tests = [ [[], "2000-05-02[u-ca=iso8601]", "built-in ISO"], - [[{ toString() { return "custom"; } }], "2000-05-02[u-ca=custom]", "custom"], - [[{ toString() { return "iso8601"; } }], "2000-05-02[u-ca=iso8601]", "custom with iso8601 toString"], - [[{ toString() { return "ISO8601"; } }], "2000-05-02[u-ca=ISO8601]", "custom with caps toString"], - [[{ toString() { return "\u0131so8601"; } }], "2000-05-02[u-ca=\u0131so8601]", "custom with dotless i toString"], + [[{ id: "custom", ...calendarMethods }], "2000-05-02[u-ca=custom]", "custom"], + [[{ id: "iso8601", ...calendarMethods }], "2000-05-02[u-ca=iso8601]", "custom with iso8601 id"], + [[{ id: "ISO8601", ...calendarMethods }], "2000-05-02[u-ca=ISO8601]", "custom with caps id"], + [[{ id: "\u0131so8601", ...calendarMethods }], "2000-05-02[u-ca=\u0131so8601]", "custom with dotless i id"], ]; for (const [args, expected, description] of tests) { diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toString/calendarname-auto.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toString/calendarname-auto.js index c5154ea8a9e7..77e8c5dd4d95 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toString/calendarname-auto.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toString/calendarname-auto.js @@ -7,12 +7,35 @@ description: If calendarName is "auto", "iso8601" should be omitted. features: [Temporal] ---*/ +const calendarMethods = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; + const tests = [ [[], "2000-05-02", "built-in ISO"], - [[{ toString() { return "custom"; } }], "2000-05-02[u-ca=custom]", "custom"], - [[{ toString() { return "iso8601"; } }], "2000-05-02", "custom with iso8601 toString"], - [[{ toString() { return "ISO8601"; } }], "2000-05-02[u-ca=ISO8601]", "custom with caps toString"], - [[{ toString() { return "\u0131so8601"; } }], "2000-05-02[u-ca=\u0131so8601]", "custom with dotless i toString"], + [[{ id: "custom", ...calendarMethods }], "2000-05-02[u-ca=custom]", "custom"], + [[{ id: "iso8601", ...calendarMethods }], "2000-05-02", "custom with iso8601 id"], + [[{ id: "ISO8601", ...calendarMethods }], "2000-05-02[u-ca=ISO8601]", "custom with caps id"], + [[{ id: "\u0131so8601", ...calendarMethods }], "2000-05-02[u-ca=\u0131so8601]", "custom with dotless i id"], ]; for (const [args, expected, description] of tests) { diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toString/calendarname-critical.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toString/calendarname-critical.js index 1a2dee05303c..dc3d37b75661 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toString/calendarname-critical.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toString/calendarname-critical.js @@ -9,12 +9,35 @@ description: > features: [Temporal] ---*/ +const calendarMethods = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; + const tests = [ [[], "2000-05-02[!u-ca=iso8601]", "built-in ISO"], - [[{ toString() { return "custom"; } }], "2000-05-02[!u-ca=custom]", "custom"], - [[{ toString() { return "iso8601"; } }], "2000-05-02[!u-ca=iso8601]", "custom with iso8601 toString"], - [[{ toString() { return "ISO8601"; } }], "2000-05-02[!u-ca=ISO8601]", "custom with caps toString"], - [[{ toString() { return "\u0131so8601"; } }], "2000-05-02[!u-ca=\u0131so8601]", "custom with dotless i toString"], + [[{ id: "custom", ...calendarMethods }], "2000-05-02[!u-ca=custom]", "custom"], + [[{ id: "iso8601", ...calendarMethods }], "2000-05-02[!u-ca=iso8601]", "custom with iso8601 id"], + [[{ id: "ISO8601", ...calendarMethods }], "2000-05-02[!u-ca=ISO8601]", "custom with caps id"], + [[{ id: "\u0131so8601", ...calendarMethods }], "2000-05-02[!u-ca=\u0131so8601]", "custom with dotless i id"], ]; for (const [args, expected, description] of tests) { diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toString/calendarname-never.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toString/calendarname-never.js index 163ab4eb10a8..1d25028717eb 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toString/calendarname-never.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toString/calendarname-never.js @@ -7,12 +7,35 @@ description: If calendarName is "never", the calendar ID should be omitted. features: [Temporal] ---*/ +const calendarMethods = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; + const tests = [ [[], "2000-05-02", "built-in ISO"], - [[{ toString() { return "custom"; } }], "2000-05-02", "custom"], - [[{ toString() { return "iso8601"; } }], "2000-05-02", "custom with iso8601 toString"], - [[{ toString() { return "ISO8601"; } }], "2000-05-02", "custom with caps toString"], - [[{ toString() { return "\u0131so8601"; } }], "2000-05-02", "custom with dotless i toString"], + [[{ id: "custom", ...calendarMethods }], "2000-05-02", "custom"], + [[{ id: "iso8601", ...calendarMethods }], "2000-05-02", "custom with iso8601 id"], + [[{ id: "ISO8601", ...calendarMethods }], "2000-05-02", "custom with caps id"], + [[{ id: "\u0131so8601", ...calendarMethods }], "2000-05-02", "custom with dotless i id"], ]; for (const [args, expected, description] of tests) { diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toString/calendarname-undefined.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toString/calendarname-undefined.js index b6b0c4f68528..fac29dcf86f6 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toString/calendarname-undefined.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toString/calendarname-undefined.js @@ -14,12 +14,35 @@ info: | features: [Temporal] ---*/ +const calendarMethods = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; + const tests = [ [[], "2000-05-02", "built-in ISO"], - [[{ toString() { return "custom"; } }], "2000-05-02[u-ca=custom]", "custom"], - [[{ toString() { return "iso8601"; } }], "2000-05-02", "custom with iso8601 toString"], - [[{ toString() { return "ISO8601"; } }], "2000-05-02[u-ca=ISO8601]", "custom with caps toString"], - [[{ toString() { return "\u0131so8601"; } }], "2000-05-02[u-ca=\u0131so8601]", "custom with dotless i toString"], + [[{ id: "custom", ...calendarMethods }], "2000-05-02[u-ca=custom]", "custom"], + [[{ id: "iso8601", ...calendarMethods }], "2000-05-02", "custom with iso8601 id"], + [[{ id: "ISO8601", ...calendarMethods }], "2000-05-02[u-ca=ISO8601]", "custom with caps id"], + [[{ id: "\u0131so8601", ...calendarMethods }], "2000-05-02[u-ca=\u0131so8601]", "custom with dotless i id"], ]; for (const [args, expected, description] of tests) { diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toString/calendarname-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toString/calendarname-wrong-type.js index c14aa25a9c58..d3718951bfe1 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toString/calendarname-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toString/calendarname-wrong-type.js @@ -16,7 +16,27 @@ features: [Temporal] ---*/ const calendar = { - toString() { return "custom"; } + id: "custom", + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, }; const date = new Temporal.PlainDate(2000, 5, 2, calendar); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toString/options-undefined.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toString/options-undefined.js index 389993ae7272..416b42fc2bac 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toString/options-undefined.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toString/options-undefined.js @@ -8,7 +8,27 @@ features: [Temporal] ---*/ const calendar = { - toString() { return "custom"; } + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "custom", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, }; const date1 = new Temporal.PlainDate(2000, 5, 2); const date2 = new Temporal.PlainDate(2000, 5, 2, calendar); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toString/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toString/order-of-operations.js index fa627943c1ad..a773a9a7925a 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toString/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toString/order-of-operations.js @@ -12,9 +12,7 @@ const expected = [ "get options.calendarName", "get options.calendarName.toString", "call options.calendarName.toString", - "get this.calendar[Symbol.toPrimitive]", - "get this.calendar.toString", - "call this.calendar.toString", + "get this.calendar.id", ]; const actual = []; diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/argument-string-calendar-annotation.js index 69563d510ebc..71908e657d2d 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/argument-string-calendar-annotation.js @@ -20,8 +20,10 @@ const tests = [ ["1970-01-01T12:34:56.987654321[UTC][u-ca=iso8601]", "with date and time zone"], ["1970-01-01T12:34:56.987654321[!u-ca=iso8601]", "with !, date, and no time zone"], ["1970-01-01T12:34:56.987654321[UTC][!u-ca=iso8601]", "with !, date, and time zone"], + ["12:34:56.987654321[u-ca=hebrew]", "calendar annotation ignored"], + ["12:34:56.987654321[u-ca=unknown]", "calendar annotation ignored even if unknown calendar"], + ["12:34:56.987654321[!u-ca=unknown]", "calendar annotation ignored even if unknown calendar with !"], ["1970-01-01T12:34:56.987654321[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["1970-01-01T12:34:56.987654321[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const instance = new Temporal.PlainDate(2000, 5, 2); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..2cec8e35905a --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.tozoneddatetime +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "00:00[u-ca=iso8601][!u-ca=iso8601]", + "00:00[!u-ca=iso8601][u-ca=iso8601]", + "00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.PlainDate(2000, 5, 2); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.toZonedDateTime({ plainTime: arg, timeZone: "UTC" }), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/calendar-temporal-object.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/calendar-temporal-object.js deleted file mode 100644 index 05324394219d..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/calendar-temporal-object.js +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (C) 2020 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.plaindate.prototype.tozoneddatetime -description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots -info: | - sec-temporal.plaindate.prototype.tozoneddatetime step 6.a: - a. Set _temporalTime_ to ? ToTemporalTime(_temporalTime_). - sec-temporal-totemporaltime step 3.d: - d. If _calendar_ is not *undefined*, then - i. Set _calendar_ to ? ToTemporalCalendar(_calendar_). - ii. If ? ToString(_calendar_) is not *"iso8601"*, then - 1. Throw a *RangeError* exception. - sec-temporal-totemporalcalendar step 1.a: - a. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then - i. Return _temporalCalendarLike_.[[Calendar]]. -includes: [compareArray.js, temporalHelpers.js] -features: [Temporal] ----*/ - -TemporalHelpers.checkToTemporalCalendarFastPath((temporalObject) => { - const date = new Temporal.PlainDate(2000, 5, 2); - assert.throws(RangeError, () => date.toZonedDateTime({ timeZone: "UTC", plainTime: { hour: 12, minute: 30, calendar: temporalObject } })); -}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/calendar.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/calendar.js index dea05bec6d1a..e2a3d12d3932 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/calendar.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/calendar.js @@ -15,5 +15,5 @@ const result = plainDate.toZonedDateTime({ plainTime: { hour: 12, minute: 30, calendar: timeCalendar }, }); assert.sameValue(result.epochNanoseconds, 957270600_000_000_000n); -assert.sameValue(result.timeZone.toString(), "UTC"); -assert.sameValue(result.calendar, calendar); +assert.sameValue(result.timeZoneId, "UTC"); +assert.sameValue(result.getCalendar(), calendar); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-case-insensitive.js index a96371d4d316..31740770fdfc 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-case-insensitive.js @@ -7,8 +7,8 @@ description: Time zone names are case insensitive features: [Temporal] ---*/ -const instance = new Temporal.PlainDate(2000, 5, 2); +const instance = new Temporal.PlainDate(2000, 5, 2); const timeZone = 'uTc'; const result = instance.toZonedDateTime(timeZone); -assert.sameValue(result.timeZone.id, 'UTC', `Time zone created from string "${timeZone}"`); +assert.sameValue(result.timeZoneId, 'UTC', `Time zone created from string "${timeZone}"`); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-getpossibleinstantsfor.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-getpossibleinstantsfor.js index 44310247158f..9386d1173087 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-getpossibleinstantsfor.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-getpossibleinstantsfor.js @@ -13,7 +13,7 @@ class CustomTimeZone extends Temporal.TimeZone { super("UTC"); } getPossibleInstantsFor(plainDateTime) { - assert.sameValue(plainDateTime.calendar, calendar); + assert.sameValue(plainDateTime.getCalendar(), calendar); return [new Temporal.Instant(987654321_000_000_000n)]; } } @@ -24,5 +24,5 @@ const result = plainDate.toZonedDateTime({ plainTime: { hour: 12, minute: 30 }, }); assert.sameValue(result.epochNanoseconds, 987654321_000_000_000n); -assert.sameValue(result.timeZone, timeZone); -assert.sameValue(result.calendar, calendar); +assert.sameValue(result.getTimeZone(), timeZone); +assert.sameValue(result.getCalendar(), calendar); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-instance-does-not-get-timeZone-property.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-instance-does-not-get-timeZone-property.js deleted file mode 100644 index 6a69b6ca7eac..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-instance-does-not-get-timeZone-property.js +++ /dev/null @@ -1,22 +0,0 @@ -// 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.tozoneddatetime -description: > - A Temporal.TimeZone instance passed to toZonedDateTime() does not have its - 'timeZone' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.PlainDate(2000, 5, 2); - -const timeZone = new Temporal.TimeZone("UTC"); -Object.defineProperty(timeZone, "timeZone", { - get() { - throw new Test262Error("timeZone.timeZone should not be accessed"); - }, -}); - -instance.toZonedDateTime(timeZone); -instance.toZonedDateTime({ timeZone }); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-string-datetime.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-string-datetime.js index d4a39fca9cfe..c85fd3da5e11 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-string-datetime.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-string-datetime.js @@ -11,34 +11,23 @@ const instance = new Temporal.PlainDate(2000, 5, 2); let timeZone = "2021-08-19T17:30"; assert.throws(RangeError, () => instance.toZonedDateTime(timeZone), "bare date-time string is not a time zone"); -assert.throws(RangeError, () => instance.toZonedDateTime({ timeZone }), "bare date-time string is not a time zone"); timeZone = "2021-08-19T17:30Z"; const result1 = instance.toZonedDateTime(timeZone); -assert.sameValue(result1.timeZone.id, "UTC", "date-time + Z is UTC time zone"); -const result2 = instance.toZonedDateTime({ timeZone }); -assert.sameValue(result2.timeZone.id, "UTC", "date-time + Z is UTC time zone (string in property bag)"); +assert.sameValue(result1.timeZoneId, "UTC", "date-time + Z is UTC time zone"); timeZone = "2021-08-19T17:30-07:00"; -const result3 = instance.toZonedDateTime(timeZone); -assert.sameValue(result3.timeZone.id, "-07:00", "date-time + offset is the offset time zone"); -const result4 = instance.toZonedDateTime({ timeZone }); -assert.sameValue(result4.timeZone.id, "-07:00", "date-time + offset is the offset time zone (string in property bag)"); +const result2 = instance.toZonedDateTime(timeZone); +assert.sameValue(result2.timeZoneId, "-07:00", "date-time + offset is the offset time zone"); timeZone = "2021-08-19T17:30[UTC]"; -const result5 = instance.toZonedDateTime(timeZone); -assert.sameValue(result5.timeZone.id, "UTC", "date-time + IANA annotation is the IANA time zone"); -const result6 = instance.toZonedDateTime({ timeZone }); -assert.sameValue(result6.timeZone.id, "UTC", "date-time + IANA annotation is the IANA time zone (string in property bag)"); +const result3 = instance.toZonedDateTime(timeZone); +assert.sameValue(result3.timeZoneId, "UTC", "date-time + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30Z[UTC]"; -const result7 = instance.toZonedDateTime(timeZone); -assert.sameValue(result7.timeZone.id, "UTC", "date-time + Z + IANA annotation is the IANA time zone"); -const result8 = instance.toZonedDateTime({ timeZone }); -assert.sameValue(result8.timeZone.id, "UTC", "date-time + Z + IANA annotation is the IANA time zone (string in property bag)"); +const result4 = instance.toZonedDateTime(timeZone); +assert.sameValue(result4.timeZoneId, "UTC", "date-time + Z + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30-07:00[UTC]"; -const result9 = instance.toZonedDateTime(timeZone); -assert.sameValue(result9.timeZone.id, "UTC", "date-time + offset + IANA annotation is the IANA time zone"); -const result10 = instance.toZonedDateTime({ timeZone }); -assert.sameValue(result10.timeZone.id, "UTC", "date-time + offset + IANA annotation is the IANA time zone (string in property bag)"); +const result5 = instance.toZonedDateTime(timeZone); +assert.sameValue(result5.timeZoneId, "UTC", "date-time + offset + IANA annotation is the IANA time zone"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-string-leap-second.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-string-leap-second.js index 7265aca26168..c5af9d74e12d 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-string-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-string-leap-second.js @@ -10,11 +10,8 @@ features: [Temporal] const instance = new Temporal.PlainDate(2000, 5, 2); let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; -const result1 = instance.toZonedDateTime(timeZone); -assert.sameValue(result1.timeZone.id, "UTC", "leap second is a valid ISO string for TimeZone"); -const result2 = instance.toZonedDateTime({ timeZone }); -assert.sameValue(result2.timeZone.id, "UTC", "leap second is a valid ISO string for TimeZone (nested property)"); +const result = instance.toZonedDateTime(timeZone); +assert.sameValue(result.timeZoneId, "UTC", "leap second is a valid ISO string for TimeZone"); timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; assert.throws(RangeError, () => instance.toZonedDateTime(timeZone), "leap second in time zone name not valid"); -assert.throws(RangeError, () => instance.toZonedDateTime({ timeZone }), "leap second in time zone name not valid (nested property)"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-string-multiple-offsets.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-string-multiple-offsets.js index 5b3dcdbf3b68..bc5705086631 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-string-multiple-offsets.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-string-multiple-offsets.js @@ -10,7 +10,5 @@ features: [Temporal] const instance = new Temporal.PlainDate(2000, 5, 2); const timeZone = "2021-08-19T17:30:45.123456789+01:46[+01:45:30.987654321]"; -const result1 = instance.toZonedDateTime(timeZone); -assert.sameValue(result1.timeZone.id, "+01:45:30.987654321", "Time zone string determined from bracket name"); -const result2 = instance.toZonedDateTime({ timeZone }); -assert.sameValue(result2.timeZone.id, "+01:45:30.987654321", "Time zone string determined from bracket name"); +const result = instance.toZonedDateTime(timeZone); +assert.sameValue(result.timeZoneId, "+01:45:30.987654321", "Time zone string determined from bracket name"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-string-year-zero.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-string-year-zero.js index 62e499eb4fcc..e565c5ef7e35 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-string-year-zero.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-string-year-zero.js @@ -18,9 +18,4 @@ invalidStrings.forEach((timeZone) => { () => instance.toZonedDateTime(timeZone), "reject minus zero as extended year" ); - assert.throws( - RangeError, - () => instance.toZonedDateTime({ timeZone }), - "reject minus zero as extended year (nested property)" - ); }); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-string.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-string.js index fe86a5ac077c..6e4036ef43f2 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-string.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-string.js @@ -4,12 +4,33 @@ /*--- esid: sec-temporal.plaindate.prototype.tozoneddatetime description: Time zone IDs are valid input for a time zone +includes: [temporalHelpers.js] features: [Temporal] ---*/ +const getPossibleInstantsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getPossibleInstantsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getPossibleInstantsFor should not be looked up"); + }, +}); +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + const instance = new Temporal.PlainDate(2000, 5, 2); ["UTC", "+01:30"].forEach((timeZone) => { const result = instance.toZonedDateTime(timeZone); - assert.sameValue(result.timeZone.id, timeZone, `Time zone created from string "${timeZone}"`); + assert.sameValue(result.getISOFields().timeZone, timeZone, `time zone slot should store string "${timeZone}"`); }); + +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", getPossibleInstantsForOriginal); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-wrong-type.js index cfeb1f3e0025..a54d302728b7 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-wrong-type.js @@ -18,22 +18,18 @@ const rangeErrorTests = [ [1, "number that doesn't convert to a valid ISO string"], [19761118, "number that would convert to a valid ISO string in other contexts"], [1n, "bigint"], - [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of rangeErrorTests) { assert.throws(RangeError, () => instance.toZonedDateTime(timeZone), `${description} does not convert to a valid ISO string`); - assert.throws(RangeError, () => instance.toZonedDateTime({ timeZone }), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], + [{}, "object not implementing time zone protocol"], + [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of typeErrorTests) { assert.throws(TypeError, () => instance.toZonedDateTime(timeZone), `${description} is not a valid object and does not convert to a string`); - assert.throws(TypeError, () => instance.toZonedDateTime({ timeZone }), `${description} is not a valid object and does not convert to a string (nested property)`); } - -const timeZone = undefined; -assert.throws(RangeError, () => instance.toZonedDateTime({ timeZone }), `undefined is always a RangeError as nested property`); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/until/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/until/argument-propertybag-calendar-case-insensitive.js index db2b4d76ba3f..71a5dd19f8dd 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/until/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/until/argument-propertybag-calendar-case-insensitive.js @@ -12,10 +12,6 @@ const instance = new Temporal.PlainDate(1976, 11, 18); const calendar = "IsO8601"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.until(arg); -TemporalHelpers.assertDuration(result1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Calendar is case-insensitive"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.until(arg); -TemporalHelpers.assertDuration(result2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Calendar is case-insensitive (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.until(arg); +TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/until/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/until/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 0d3331731354..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/until/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,25 +0,0 @@ -// 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.until -description: > - A Temporal.Calendar instance passed to until() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.PlainDate(1976, 11, 18); - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -instance.until(arg); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -instance.until(arg); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/until/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/until/argument-propertybag-calendar-leap-second.js index a0a12252ccc7..d250a6195af7 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/until/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/until/argument-propertybag-calendar-leap-second.js @@ -12,18 +12,10 @@ const instance = new Temporal.PlainDate(1976, 11, 18); const calendar = "2016-12-31T23:59:60"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.until(arg); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.until(arg); TemporalHelpers.assertDuration( - result1, + result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "leap second is a valid ISO string for calendar" ); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.until(arg); -TemporalHelpers.assertDuration( - result2, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/until/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/until/argument-propertybag-calendar-number.js index 2a73bffd8d50..c050c717b017 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/until/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/until/argument-propertybag-calendar-number.js @@ -12,13 +12,9 @@ const instance = new Temporal.PlainDate(1976, 11, 18); const calendar = 19970327; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.until(arg); -TemporalHelpers.assertDuration(result1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.until(arg); -TemporalHelpers.assertDuration(result2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.until(arg); +TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -27,16 +23,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; assert.throws( RangeError, () => instance.until(arg), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.until(arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/until/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/until/argument-propertybag-calendar-wrong-type.js index 36bf6986ea25..9b59cff47da3 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/until/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/until/argument-propertybag-calendar-wrong-type.js @@ -21,27 +21,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.until(arg), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.until(arg), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.until(arg), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.until(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.until(arg), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/until/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/until/argument-string-calendar-annotation.js index a32427322201..07e858c04325 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/until/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/until/argument-string-calendar-annotation.js @@ -16,7 +16,6 @@ const tests = [ ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const instance = new Temporal.PlainDate(2000, 5, 2); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/until/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/until/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..a94fbe8d56bc --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/until/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.until +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.PlainDate(2000, 5, 2); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.until(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/until/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/until/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..6b13d151ef6c --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/until/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.until +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const dateUntilOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dateUntil"); +Object.defineProperty(Temporal.Calendar.prototype, "dateUntil", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("dateUntil should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDate(2000, 5, 2, "iso8601"); +instance.until(new Temporal.PlainDate(2001, 6, 13)); + +Object.defineProperty(Temporal.Calendar.prototype, "dateUntil", dateUntilOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/until/calendar-mismatch.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/until/calendar-mismatch.js index 481fff4f3950..05c96de8c966 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/until/calendar-mismatch.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/until/calendar-mismatch.js @@ -3,12 +3,56 @@ /*--- esid: sec-temporal.plaindate.prototype.until -description: RangeError thrown if calendars' toString results do not match +description: RangeError thrown if calendars' id properties do not match features: [Temporal] ---*/ -const calendar1 = { toString() { return "A"; } }; -const calendar2 = { toString() { return "B"; } }; +const calendar1 = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "A", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; +const calendar2 = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "B", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; const plainDate1 = new Temporal.PlainDate(2000, 1, 1, calendar1); const plainDate2 = new Temporal.PlainDate(2000, 1, 1, calendar2); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/until/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/until/order-of-operations.js index 382a9ed13c04..602f08936ec7 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/until/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/until/order-of-operations.js @@ -11,7 +11,27 @@ features: [Temporal] const expected = [ // ToTemporalDate "get other.calendar", - "has other.calendar.calendar", + "has other.calendar.dateAdd", + "has other.calendar.dateFromFields", + "has other.calendar.dateUntil", + "has other.calendar.day", + "has other.calendar.dayOfWeek", + "has other.calendar.dayOfYear", + "has other.calendar.daysInMonth", + "has other.calendar.daysInWeek", + "has other.calendar.daysInYear", + "has other.calendar.fields", + "has other.calendar.id", + "has other.calendar.inLeapYear", + "has other.calendar.mergeFields", + "has other.calendar.month", + "has other.calendar.monthCode", + "has other.calendar.monthDayFromFields", + "has other.calendar.monthsInYear", + "has other.calendar.weekOfYear", + "has other.calendar.year", + "has other.calendar.yearMonthFromFields", + "has other.calendar.yearOfWeek", "get other.calendar.fields", "call other.calendar.fields", "get other.day", @@ -29,12 +49,8 @@ const expected = [ "get other.calendar.dateFromFields", "call other.calendar.dateFromFields", // CalendarEquals - "get this.calendar[Symbol.toPrimitive]", - "get this.calendar.toString", - "call this.calendar.toString", - "get other.calendar[Symbol.toPrimitive]", - "get other.calendar.toString", - "call other.calendar.toString", + "get this.calendar.id", + "get other.calendar.id", // CopyDataProperties "ownKeys options", "getOwnPropertyDescriptor options.roundingIncrement", diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/weekOfYear/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/weekOfYear/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..1605f26aca1e --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/weekOfYear/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.weekofyear +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const weekOfYearOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "weekOfYear"); +Object.defineProperty(Temporal.Calendar.prototype, "weekOfYear", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("weekOfYear should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDate(2000, 5, 2, "iso8601"); +instance.weekOfYear; + +Object.defineProperty(Temporal.Calendar.prototype, "weekOfYear", weekOfYearOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/with/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/with/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..1880e425f6b2 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/with/builtin-calendar-no-observable-calls.js @@ -0,0 +1,43 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.with +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const fieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "fields"); +Object.defineProperty(Temporal.Calendar.prototype, "fields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("fields should not be looked up"); + }, +}); +const mergeFieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "mergeFields"); +Object.defineProperty(Temporal.Calendar.prototype, "mergeFields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("mergeFields should not be looked up"); + }, +}); +const dateFromFieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dateFromFields"); +Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("dateFromFields should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDate(2000, 5, 2, "iso8601"); +instance.with({ year: 2001 }); + +Object.defineProperty(Temporal.Calendar.prototype, "fields", fieldsOriginal); +Object.defineProperty(Temporal.Calendar.prototype, "mergeFields", mergeFieldsOriginal); +Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", dateFromFieldsOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/withCalendar/basic.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/withCalendar/basic.js index 2dd1adb537fa..cdf6f3807c0b 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/withCalendar/basic.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/withCalendar/basic.js @@ -14,15 +14,15 @@ const calendar = Temporal.Calendar.from("iso8601"); const objectResult = plainDate.withCalendar(calendar); assert.notSameValue(objectResult, plainDate, "object: new object"); TemporalHelpers.assertPlainDate(objectResult, 1976, 11, "M11", 18, "object"); -assert.sameValue(objectResult.calendar, calendar, "object: calendar"); +assert.sameValue(objectResult.getCalendar(), calendar, "object: calendar"); const stringResult = plainDate.withCalendar("iso8601"); assert.notSameValue(stringResult, plainDate, "string: new object"); TemporalHelpers.assertPlainDate(stringResult, 1976, 11, "M11", 18, "string"); -assert.sameValue(stringResult.calendar.id, "iso8601", "string: calendar"); +assert.sameValue(stringResult.getISOFields().calendar, "iso8601", "string: calendar slot stores a string"); -const originalCalendar = plainDate.calendar; +const originalCalendar = plainDate.getCalendar(); const sameResult = plainDate.withCalendar(originalCalendar); assert.notSameValue(sameResult, plainDate, "original: new object"); TemporalHelpers.assertPlainDate(sameResult, 1976, 11, "M11", 18, "original"); -assert.sameValue(sameResult.calendar, originalCalendar, "original: calendar"); +assert.sameValue(sameResult.getCalendar(), originalCalendar, "original: calendar slot stores and object"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/withCalendar/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/withCalendar/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..4c2a9524d811 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/withCalendar/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.withcalendar +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const idOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "id"); +Object.defineProperty(Temporal.Calendar.prototype, "id", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("id should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDate(2000, 5, 2, "iso8601"); +instance.withCalendar("iso8601"); + +Object.defineProperty(Temporal.Calendar.prototype, "id", idOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-case-insensitive.js index 2199a02baccd..511b0df4f467 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-case-insensitive.js @@ -7,8 +7,30 @@ description: Calendar names are case-insensitive features: [Temporal] ---*/ -const instance = new Temporal.PlainDate(1976, 11, 18, { id: "replace-me" }); +const instance = new Temporal.PlainDate(1976, 11, 18, { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "replace-me", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}); const arg = "iSo8601"; const result = instance.withCalendar(arg); -assert.sameValue(result.calendar.id, "iso8601", "Calendar is case-insensitive"); +assert.sameValue(result.calendarId, "iso8601", "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 5169231ac39d..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,22 +0,0 @@ -// 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.withcalendar -description: > - A Temporal.Calendar instance passed to withCalendar() does not have its - 'calendar' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.PlainDate(1976, 11, 18, { id: "replace-me" }); - -const arg = new Temporal.Calendar("iso8601"); -Object.defineProperty(arg, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -instance.withCalendar(arg); -instance.withCalendar({ calendar: arg }); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-number.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-number.js index 1ff8a50d695b..750acb3230d8 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-number.js @@ -7,12 +7,34 @@ description: A number is converted to a string, then to Temporal.Calendar features: [Temporal] ---*/ -const instance = new Temporal.PlainDate(1976, 11, 18, { id: "replace-me" }); +const instance = new Temporal.PlainDate(1976, 11, 18, { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "replace-me", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}); const arg = 19761118; const result = instance.withCalendar(arg); -assert.sameValue(result.calendar.id, "iso8601", "19761118 is a valid ISO string for Calendar"); +assert.sameValue(result.calendarId, "iso8601", "19761118 is a valid ISO string for Calendar"); const numbers = [ 1, diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-string-leap-second.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-string-leap-second.js index 7bd95a80cdf8..604f6085381c 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-string-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-string-leap-second.js @@ -7,20 +7,34 @@ description: Leap second is a valid ISO string for Calendar features: [Temporal] ---*/ -const instance = new Temporal.PlainDate(1976, 11, 18, { id: "replace-me" }); +const instance = new Temporal.PlainDate(1976, 11, 18, { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "replace-me", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}); -let arg = "2016-12-31T23:59:60"; -const result1 = instance.withCalendar(arg); +const arg = "2016-12-31T23:59:60"; +const result = instance.withCalendar(arg); assert.sameValue( - result1.calendar.id, + result.calendarId, "iso8601", "leap second is a valid ISO string for Calendar" ); - -arg = { calendar: "2016-12-31T23:59:60" }; -const result2 = instance.withCalendar(arg); -assert.sameValue( - result2.calendar.id, - "iso8601", - "leap second is a valid ISO string for Calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-string.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-string.js index 928e2979ca20..90a2149df6c8 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-string.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-string.js @@ -7,9 +7,31 @@ description: A calendar ID is valid input for Calendar features: [Temporal] ---*/ -const instance = new Temporal.PlainDate(1976, 11, 18, { id: "replace-me" }); +const instance = new Temporal.PlainDate(1976, 11, 18, { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "replace-me", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}); const arg = "iso8601"; const result = instance.withCalendar(arg); -assert.sameValue(result.calendar.id, "iso8601", `Calendar created from string "${arg}"`); +assert.sameValue(result.getISOFields().calendar, "iso8601", `Calendar created from string "${arg}"`); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-temporal-object.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-temporal-object.js index 278e2d7e2390..24ba4c7d1ebb 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-temporal-object.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-temporal-object.js @@ -6,7 +6,7 @@ esid: sec-temporal.plaindate.prototype.withcalendar description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots info: | sec-temporal-totemporalcalendar step 1.b: - b. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then + b. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then i. Return _temporalCalendarLike_.[[Calendar]]. includes: [compareArray.js] features: [Temporal] @@ -14,12 +14,11 @@ features: [Temporal] const plainDate = new Temporal.PlainDate(2000, 5, 2); const plainDateTime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); -const plainTime = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); const plainMonthDay = new Temporal.PlainMonthDay(5, 2); const plainYearMonth = new Temporal.PlainYearMonth(2000, 5); const zonedDateTime = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); -[plainDate, plainDateTime, plainTime, plainMonthDay, plainYearMonth, zonedDateTime].forEach((arg) => { +[plainDate, plainDateTime, plainMonthDay, plainYearMonth, zonedDateTime].forEach((arg) => { const actual = []; const expected = []; @@ -32,9 +31,31 @@ const zonedDateTime = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UT }, }); - const instance = new Temporal.PlainDate(1976, 11, 18, { id: "replace-me" }); + const instance = new Temporal.PlainDate(1976, 11, 18, { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "replace-me", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}); const result = instance.withCalendar(arg); - assert.sameValue(result.calendar, calendar, "Temporal object coerced to calendar"); + assert.sameValue(result.getISOFields().calendar, calendar, "Temporal object coerced to calendar"); assert.compareArray(actual, expected, "calendar getter not called"); }); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-wrong-type.js index 110b49a3e6be..95df5e7cc591 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-wrong-type.js @@ -9,7 +9,29 @@ description: > features: [BigInt, Symbol, Temporal] ---*/ -const instance = new Temporal.PlainDate(1976, 11, 18, { id: "replace-me" }); +const instance = new Temporal.PlainDate(1976, 11, 18, { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "replace-me", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}); const rangeErrorTests = [ [null, "null"], @@ -17,19 +39,19 @@ const rangeErrorTests = [ ["", "empty string"], [1, "number that doesn't convert to a valid ISO string"], [1n, "bigint"], - [new Temporal.TimeZone("UTC"), "time zone instance"], ]; for (const [arg, description] of rangeErrorTests) { assert.throws(RangeError, () => instance.withCalendar(arg), `${description} does not convert to a valid ISO string`); - assert.throws(RangeError, () => instance.withCalendar({ calendar: arg }), `${description} does not convert to a valid ISO string (in property bag)`); } const typeErrorTests = [ [Symbol(), "symbol"], + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], ]; for (const [arg, description] of typeErrorTests) { assert.throws(TypeError, () => instance.withCalendar(arg), `${description} is not a valid object and does not convert to a string`); - assert.throws(TypeError, () => instance.withCalendar({ calendar: arg }), `${description} is not a valid object and does not convert to a string (in property bag)`); } diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/withCalendar/subclassing-ignored.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/withCalendar/subclassing-ignored.js index f8dce94d5157..5c0595831dc2 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/withCalendar/subclassing-ignored.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/withCalendar/subclassing-ignored.js @@ -15,7 +15,24 @@ const customCalendar = { month() { return 2; }, monthCode() { return "M02"; }, day() { return 5; }, + id: "custom-calendar", toString() { return "custom-calendar"; }, + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, }; TemporalHelpers.checkSubclassingIgnored( @@ -25,6 +42,6 @@ TemporalHelpers.checkSubclassingIgnored( [customCalendar], (result) => { TemporalHelpers.assertPlainDate(result, 1900, 2, "M02", 5); - assert.sameValue(result.calendar, customCalendar, "calendar result"); + assert.sameValue(result.getCalendar(), customCalendar, "calendar result"); }, ); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/year/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/year/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..55f6be8a71d4 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/year/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.year +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const yearOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "year"); +Object.defineProperty(Temporal.Calendar.prototype, "year", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("year should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDate(2000, 5, 2, "iso8601"); +instance.year; + +Object.defineProperty(Temporal.Calendar.prototype, "year", yearOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/yearOfWeek/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/yearOfWeek/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..a56c732cf3e9 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDate/prototype/yearOfWeek/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.yearofweek +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const yearOfWeekOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "yearOfWeek"); +Object.defineProperty(Temporal.Calendar.prototype, "yearOfWeek", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("yearOfWeek should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDate(2000, 5, 2, "iso8601"); +instance.yearOfWeek; + +Object.defineProperty(Temporal.Calendar.prototype, "yearOfWeek", yearOfWeekOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/calendar-case-insensitive.js index b1528db05142..2f096dd8543a 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/calendar-case-insensitive.js @@ -10,4 +10,4 @@ features: [Temporal] const arg = "iSo8601"; const result = new Temporal.PlainDateTime(2000, 5, 2, 15, 23, 30, 987, 654, 321, arg); -assert.sameValue(result.calendar.id, "iso8601", "Calendar is case-insensitive"); +assert.sameValue(result.calendarId, "iso8601", "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 0e7bcf6fc72a..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,20 +0,0 @@ -// 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 -description: > - A Temporal.Calendar instance passed to new PlainDateTime() does not have - its 'calendar' property observably checked -features: [Temporal] ----*/ - -const arg = new Temporal.Calendar("iso8601"); -Object.defineProperty(arg, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -new Temporal.PlainDateTime(2000, 5, 2, 15, 23, 30, 987, 654, 321, arg); -new Temporal.PlainDateTime(2000, 5, 2, 15, 23, 30, 987, 654, 321, { calendar: arg }); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/calendar-number.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/calendar-number.js index c44989eaeb39..b22994919322 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/calendar-number.js @@ -10,7 +10,7 @@ features: [Temporal] const arg = 19761118; const result = new Temporal.PlainDateTime(2000, 5, 2, 15, 23, 30, 987, 654, 321, arg); -assert.sameValue(result.calendar.id, "iso8601", "19761118 is a valid ISO string for Calendar"); +assert.sameValue(result.calendarId, "iso8601", "19761118 is a valid ISO string for Calendar"); const numbers = [ 1, diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/calendar-string.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/calendar-string.js index bde22b76bd34..450c24c3a591 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/calendar-string.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/calendar-string.js @@ -10,4 +10,4 @@ features: [Temporal] const arg = "iso8601"; const result = new Temporal.PlainDateTime(2000, 5, 2, 15, 23, 30, 987, 654, 321, arg); -assert.sameValue(result.calendar.id, "iso8601", `Calendar created from string "${arg}"`); +assert.sameValue(result.getISOFields().calendar, "iso8601", `Calendar created from string "${arg}"`); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/calendar-temporal-object.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/calendar-temporal-object.js index 7a8f6b640bc2..0ef5ca40a893 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/calendar-temporal-object.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/calendar-temporal-object.js @@ -6,7 +6,7 @@ esid: sec-temporal.plaindatetime description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots info: | sec-temporal-totemporalcalendar step 1.b: - b. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then + b. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then i. Return _temporalCalendarLike_.[[Calendar]]. includes: [compareArray.js] features: [Temporal] @@ -14,12 +14,11 @@ features: [Temporal] const plainDate = new Temporal.PlainDate(2000, 5, 2); const plainDateTime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); -const plainTime = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); const plainMonthDay = new Temporal.PlainMonthDay(5, 2); const plainYearMonth = new Temporal.PlainYearMonth(2000, 5); const zonedDateTime = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); -[plainDate, plainDateTime, plainTime, plainMonthDay, plainYearMonth, zonedDateTime].forEach((arg) => { +[plainDate, plainDateTime, plainMonthDay, plainYearMonth, zonedDateTime].forEach((arg) => { const actual = []; const expected = []; @@ -33,7 +32,7 @@ const zonedDateTime = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UT }); const result = new Temporal.PlainDateTime(2000, 5, 2, 15, 23, 30, 987, 654, 321, arg); - assert.sameValue(result.calendar, calendar, "Temporal object coerced to calendar"); + assert.sameValue(result.getISOFields().calendar, calendar, "Temporal object coerced to calendar"); assert.compareArray(actual, expected, "calendar getter not called"); }); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/calendar-undefined.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/calendar-undefined.js index 553405752814..e4a692d26326 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/calendar-undefined.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/calendar-undefined.js @@ -16,7 +16,7 @@ Object.defineProperty(Temporal.Calendar, "from", { }); const dateTimeExplicit = new Temporal.PlainDateTime(...dateTimeArgs, undefined); -assert.sameValue(dateTimeExplicit.calendar.toString(), "iso8601"); +assert.sameValue(dateTimeExplicit.calendarId, "iso8601"); const dateTimeImplicit = new Temporal.PlainDateTime(...dateTimeArgs); -assert.sameValue(dateTimeImplicit.calendar.toString(), "iso8601"); +assert.sameValue(dateTimeImplicit.calendarId, "iso8601"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/calendar-wrong-type.js index 61fc252ddca5..4cdea027e479 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/calendar-wrong-type.js @@ -23,6 +23,9 @@ for (const [arg, description] of rangeErrorTests) { const typeErrorTests = [ [Symbol(), "symbol"], + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], ]; for (const [arg, description] of typeErrorTests) { diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-case-insensitive.js index 094f2748388d..5ecd1cd2ef59 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-case-insensitive.js @@ -9,14 +9,8 @@ features: [Temporal] const calendar = "IsO8601"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; const result1 = Temporal.PlainDateTime.compare(arg, new Temporal.PlainDateTime(1976, 11, 18)); assert.sameValue(result1, 0, "Calendar is case-insensitive (first argument)"); const result2 = Temporal.PlainDateTime.compare(new Temporal.PlainDateTime(1976, 11, 18), arg); assert.sameValue(result2, 0, "Calendar is case-insensitive (second argument)"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result3 = Temporal.PlainDateTime.compare(arg, new Temporal.PlainDateTime(1976, 11, 18)); -assert.sameValue(result3, 0, "Calendar is case-insensitive (nested property, first argument)"); -const result4 = Temporal.PlainDateTime.compare(new Temporal.PlainDateTime(1976, 11, 18), arg); -assert.sameValue(result4, 0, "Calendar is case-insensitive (nested property, second argument)"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 22437da13a4f..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,20 +0,0 @@ -// 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.compare -description: > - A Temporal.Calendar instance passed to compare() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -Temporal.PlainDateTime.compare(arg, arg); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-leap-second.js index 37547e3272f6..b5ccdfb7325c 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-leap-second.js @@ -9,15 +9,8 @@ features: [Temporal] const calendar = "2016-12-31T23:59:60"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; const result1 = Temporal.PlainDateTime.compare(arg, new Temporal.PlainDateTime(1976, 11, 18)); assert.sameValue(result1, 0, "leap second is a valid ISO string for calendar (first argument)"); const result2 = Temporal.PlainDateTime.compare(new Temporal.PlainDateTime(1976, 11, 18), arg); assert.sameValue(result2, 0, "leap second is a valid ISO string for calendar (second argument)"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result3 = Temporal.PlainDateTime.compare(arg, new Temporal.PlainDateTime(1976, 11, 18)); -assert.sameValue(result3, 0, "leap second is a valid ISO string for calendar (nested property, first argument)"); -const result4 = Temporal.PlainDateTime.compare(new Temporal.PlainDateTime(1976, 11, 18), arg); -assert.sameValue(result4, 0, "leap second is a valid ISO string for calendar (nested property, second argument)"); - diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-number.js index eb830da34f0d..1a765d6bf193 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-number.js @@ -9,18 +9,12 @@ features: [Temporal] const calendar = 19970327; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; const result1 = Temporal.PlainDateTime.compare(arg, new Temporal.PlainDateTime(1976, 11, 18)); assert.sameValue(result1, 0, "19970327 is a valid ISO string for calendar (first argument)"); const result2 = Temporal.PlainDateTime.compare(new Temporal.PlainDateTime(1976, 11, 18), arg); assert.sameValue(result2, 0, "19970327 is a valid ISO string for calendar (second argument)"); -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result3 = Temporal.PlainDateTime.compare(arg, new Temporal.PlainDateTime(1976, 11, 18)); -assert.sameValue(result3, 0, "19970327 is a valid ISO string for calendar (nested property, first argument)"); -const result4 = Temporal.PlainDateTime.compare(new Temporal.PlainDateTime(1976, 11, 18), arg); -assert.sameValue(result4, 0, "19970327 is a valid ISO string for calendar (nested property, second argument)"); - const numbers = [ 1, -19970327, @@ -28,7 +22,7 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; assert.throws( RangeError, () => Temporal.PlainDateTime.compare(arg, new Temporal.PlainDateTime(1976, 11, 18)), @@ -39,15 +33,4 @@ for (const calendar of numbers) { () => Temporal.PlainDateTime.compare(new Temporal.PlainDateTime(1976, 11, 18), arg), `Number ${calendar} does not convert to a valid ISO string for calendar (second argument)` ); - arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; - assert.throws( - RangeError, - () => Temporal.PlainDateTime.compare(arg, new Temporal.PlainDateTime(1976, 11, 18)), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property, first argument)` - ); - assert.throws( - RangeError, - () => Temporal.PlainDateTime.compare(new Temporal.PlainDateTime(1976, 11, 18), arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property, second argument)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-string.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-string.js index 4fada99c0b31..c5b7858472f1 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-string.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-string.js @@ -4,9 +4,19 @@ /*--- esid: sec-temporal.plaindatetime.compare description: A calendar ID is valid input for Calendar +includes: [temporalHelpers.js] features: [Temporal] ---*/ +const dateFromFieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dateFromFields"); +Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("dateFromFields should not be looked up"); + }, +}); + const calendar = "iso8601"; const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; @@ -16,3 +26,5 @@ assert.sameValue(result1, 0, `Calendar created from string "${arg}" (first argum const result2 = Temporal.PlainDateTime.compare(new Temporal.PlainDateTime(1976, 11, 18), arg); assert.sameValue(result2, 0, `Calendar created from string "${arg}" (second argument)`); + +Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", dateFromFieldsOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-wrong-type.js index 5ef7ce833d66..a1c9159a0a73 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-wrong-type.js @@ -15,36 +15,24 @@ const rangeErrorTests = [ ["", "empty string"], [1, "number that doesn't convert to a valid ISO string"], [1n, "bigint"], - [new Temporal.TimeZone("UTC"), "time zone instance"], ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => Temporal.PlainDateTime.compare(arg, new Temporal.PlainDateTime(1976, 11, 18)), `${description} does not convert to a valid ISO string (first argument)`); assert.throws(RangeError, () => Temporal.PlainDateTime.compare(new Temporal.PlainDateTime(1976, 11, 18), arg), `${description} does not convert to a valid ISO string (second argument)`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => Temporal.PlainDateTime.compare(arg, new Temporal.PlainDateTime(1976, 11, 18)), `${description} does not convert to a valid ISO string (nested property, first argument)`); - assert.throws(RangeError, () => Temporal.PlainDateTime.compare(new Temporal.PlainDateTime(1976, 11, 18), arg), `${description} does not convert to a valid ISO string (nested property, second argument)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => Temporal.PlainDateTime.compare(arg, new Temporal.PlainDateTime(1976, 11, 18)), `${description} is not a valid property bag and does not convert to a string (first argument)`); assert.throws(TypeError, () => Temporal.PlainDateTime.compare(new Temporal.PlainDateTime(1976, 11, 18), arg), `${description} is not a valid property bag and does not convert to a string (second argument)`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => Temporal.PlainDateTime.compare(arg, new Temporal.PlainDateTime(1976, 11, 18)), `${description} is not a valid property bag and does not convert to a string (nested property, first argument)`); - assert.throws(TypeError, () => Temporal.PlainDateTime.compare(new Temporal.PlainDateTime(1976, 11, 18), arg), `${description} is not a valid property bag and does not convert to a string (nested property, second argument)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => Temporal.PlainDateTime.compare(arg, new Temporal.PlainDateTime(1976, 11, 18)), `nested undefined calendar property is always a RangeError (first argument)`); -assert.throws(RangeError, () => Temporal.PlainDateTime.compare(new Temporal.PlainDateTime(1976, 11, 18), arg), `nested undefined calendar property is always a RangeError (second argument)`); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/compare/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/compare/argument-string-calendar-annotation.js index f98f1b7757c7..cab70a321655 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/compare/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/compare/argument-string-calendar-annotation.js @@ -13,7 +13,6 @@ const tests = [ ["1976-11-18T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["1976-11-18T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["1976-11-18T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["1976-11-18T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; tests.forEach(([arg, description]) => { diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/compare/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/compare/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..50b2d4ff51a5 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/compare/argument-string-multiple-calendar.js @@ -0,0 +1,34 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.compare +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; + +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => Temporal.PlainDateTime.compare(arg, new Temporal.PlainDateTime(1976, 11, 18)), + `reject more than one calendar annotation if any critical: ${arg} (first argument)` + ); + assert.throws( + RangeError, + () => Temporal.PlainDateTime.compare(new Temporal.PlainDateTime(1976, 11, 18), arg), + `reject more than one calendar annotation if any critical: ${arg} (second argument)` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/compare/calendar-ignored.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/compare/calendar-ignored.js index 9f197ae0a627..42b53741fa36 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/compare/calendar-ignored.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/compare/calendar-ignored.js @@ -4,11 +4,12 @@ /*--- esid: sec-temporal.plaindatetime.compare description: Calendar is not taken into account for the comparison. +includes: [temporalHelpers.js] features: [Temporal] ---*/ -const calendar1 = { toString() { throw new Test262Error("should not call calendar1.toString") } }; -const calendar2 = { toString() { throw new Test262Error("should not call calendar2.toString") } }; +const calendar1 = TemporalHelpers.calendarThrowEverything(); +const calendar2 = TemporalHelpers.calendarThrowEverything(); const dt1 = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789, calendar1); const dt2 = new Temporal.PlainDateTime(2019, 10, 29, 10, 46, 38, 271, 986, 102, calendar1); const dt3 = new Temporal.PlainDateTime(2019, 10, 29, 10, 46, 38, 271, 986, 102, calendar1); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/constructor-full.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/constructor-full.js index 8715f22122f3..677ac59c19ce 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/constructor-full.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/constructor-full.js @@ -17,7 +17,7 @@ TemporalHelpers.assertPlainDateTime(datetime, ); assert.sameValue( - datetime.calendar, + datetime.getCalendar(), calendar, "calendar supplied in constructor can be extracted and is unchanged" ); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/argument-plaindate.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/argument-plaindate.js index 1994043454ce..693abbdb65dd 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/argument-plaindate.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/argument-plaindate.js @@ -17,5 +17,5 @@ features: [Temporal] TemporalHelpers.checkToTemporalPlainDateTimeFastPath((date, calendar) => { const result = Temporal.PlainDateTime.from(date); TemporalHelpers.assertPlainDateTime(result, 2000, 5, "M05", 2, 0, 0, 0, 0, 0, 0, "midnight is assumed"); - assert.sameValue(result.calendar, calendar, "calendar result"); + assert.sameValue(result.getCalendar(), calendar, "calendar result"); }); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/argument-plaindatetime.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/argument-plaindatetime.js index 9cefe93e6541..ea0a21bf238b 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/argument-plaindatetime.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/argument-plaindatetime.js @@ -17,7 +17,7 @@ TemporalHelpers.assertPlainDateTime( "PlainDateTime is copied" ); -assert.sameValue(result.calendar, orig.calendar, "Calendar is copied"); +assert.sameValue(result.getISOFields().calendar, orig.getISOFields().calendar, "Calendar is copied"); assert.notSameValue( result, diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-case-insensitive.js index 349075e6f601..d2ae9dfc0ab3 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-case-insensitive.js @@ -10,10 +10,6 @@ features: [Temporal] const calendar = "IsO8601"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = Temporal.PlainDateTime.from(arg); -TemporalHelpers.assertPlainDateTime(result1, 1976, 11, "M11", 18, 0, 0, 0, 0, 0, 0, "Calendar is case-insensitive"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = Temporal.PlainDateTime.from(arg); -TemporalHelpers.assertPlainDateTime(result2, 1976, 11, "M11", 18, 0, 0, 0, 0, 0, 0, "Calendar is case-insensitive (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = Temporal.PlainDateTime.from(arg); +TemporalHelpers.assertPlainDateTime(result, 1976, 11, "M11", 18, 0, 0, 0, 0, 0, 0, "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 8ac5e5a6210c..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,23 +0,0 @@ -// 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.from -description: > - A Temporal.Calendar instance passed to from() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -Temporal.PlainDateTime.from(arg); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -Temporal.PlainDateTime.from(arg); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-leap-second.js index 4e19d8ac56c9..f37bc1c9b3d8 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-leap-second.js @@ -10,18 +10,10 @@ features: [Temporal] const calendar = "2016-12-31T23:59:60"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = Temporal.PlainDateTime.from(arg); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = Temporal.PlainDateTime.from(arg); TemporalHelpers.assertPlainDateTime( - result1, + result, 1976, 11, "M11", 18, 0, 0, 0, 0, 0, 0, "leap second is a valid ISO string for calendar" ); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = Temporal.PlainDateTime.from(arg); -TemporalHelpers.assertPlainDateTime( - result2, - 1976, 11, "M11", 18, 0, 0, 0, 0, 0, 0, - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-number.js index ae00e596a0d9..7de68bd5c77e 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-number.js @@ -10,13 +10,9 @@ features: [Temporal] const calendar = 19970327; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = Temporal.PlainDateTime.from(arg); -TemporalHelpers.assertPlainDateTime(result1, 1976, 11, "M11", 18, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = Temporal.PlainDateTime.from(arg); -TemporalHelpers.assertPlainDateTime(result2, 1976, 11, "M11", 18, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = Temporal.PlainDateTime.from(arg); +TemporalHelpers.assertPlainDateTime(result, 1976, 11, "M11", 18, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -25,16 +21,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; assert.throws( RangeError, () => Temporal.PlainDateTime.from(arg), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; - assert.throws( - RangeError, - () => Temporal.PlainDateTime.from(arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-string.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-string.js index 8d5818e0ebc9..70ff0507f68e 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-string.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-string.js @@ -13,3 +13,4 @@ const calendar = "iso8601"; const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; const result = Temporal.PlainDateTime.from(arg); TemporalHelpers.assertPlainDateTime(result, 1976, 11, "M11", 18, 0, 0, 0, 0, 0, 0, `Calendar created from string "${calendar}"`); +assert.sameValue(result.getISOFields().calendar, "iso8601", "calendar slot stores a string"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-wrong-type.js index e81f58d4b476..095682c77b21 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-wrong-type.js @@ -18,27 +18,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => Temporal.PlainDateTime.from(arg), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => Temporal.PlainDateTime.from(arg), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => Temporal.PlainDateTime.from(arg), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => Temporal.PlainDateTime.from(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => Temporal.PlainDateTime.from(arg), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/argument-string-calendar-annotation.js index e5709ad371ee..adda0087569b 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/argument-string-calendar-annotation.js @@ -14,7 +14,6 @@ const tests = [ ["1976-11-18T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["1976-11-18T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["1976-11-18T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["1976-11-18T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; tests.forEach(([arg, description]) => { diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..94e3228adf7e --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.from +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; + +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => Temporal.PlainDateTime.from(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/calendar-temporal-object.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/calendar-temporal-object.js index 6b76c86e5922..3659a257c81d 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/calendar-temporal-object.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/calendar-temporal-object.js @@ -22,5 +22,5 @@ features: [Temporal] TemporalHelpers.checkToTemporalCalendarFastPath((temporalObject, calendar) => { const result = Temporal.PlainDateTime.from({ year: 2000, month: 5, day: 2, calendar: temporalObject }); - assert.sameValue(result.calendar, calendar, "Temporal object coerced to calendar"); + assert.sameValue(result.getCalendar(), calendar, "Temporal object coerced to calendar"); }); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/order-of-operations.js index 8b8de6958956..ad11f628b947 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/from/order-of-operations.js @@ -9,9 +9,29 @@ features: [Temporal] ---*/ const expected = [ - // GetTemporalCalendarWithISODefault + // GetTemporalCalendarSlotValueWithISODefault "get fields.calendar", - "has fields.calendar.calendar", + "has fields.calendar.dateAdd", + "has fields.calendar.dateFromFields", + "has fields.calendar.dateUntil", + "has fields.calendar.day", + "has fields.calendar.dayOfWeek", + "has fields.calendar.dayOfYear", + "has fields.calendar.daysInMonth", + "has fields.calendar.daysInWeek", + "has fields.calendar.daysInYear", + "has fields.calendar.fields", + "has fields.calendar.id", + "has fields.calendar.inLeapYear", + "has fields.calendar.mergeFields", + "has fields.calendar.month", + "has fields.calendar.monthCode", + "has fields.calendar.monthDayFromFields", + "has fields.calendar.monthsInYear", + "has fields.calendar.weekOfYear", + "has fields.calendar.year", + "has fields.calendar.yearMonthFromFields", + "has fields.calendar.yearOfWeek", // CalendarFields "get fields.calendar.fields", "call fields.calendar.fields", diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/add/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/add/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..64aedee8e736 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/add/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.add +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const dateAddOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dateAdd"); +Object.defineProperty(Temporal.Calendar.prototype, "dateAdd", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("dateAdd should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, "iso8601"); +instance.add(new Temporal.Duration(1)); + +Object.defineProperty(Temporal.Calendar.prototype, "dateAdd", dateAddOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/calendar/branding.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/calendar/branding.js deleted file mode 100644 index bd6f81d6105c..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/calendar/branding.js +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-get-temporal.plaindatetime.prototype.calendar -description: Throw a TypeError if the receiver is invalid -features: [Symbol, Temporal] ----*/ - -const calendar = Object.getOwnPropertyDescriptor(Temporal.PlainDateTime.prototype, "calendar").get; - -assert.sameValue(typeof calendar, "function"); - -assert.throws(TypeError, () => calendar.call(undefined), "undefined"); -assert.throws(TypeError, () => calendar.call(null), "null"); -assert.throws(TypeError, () => calendar.call(true), "true"); -assert.throws(TypeError, () => calendar.call(""), "empty string"); -assert.throws(TypeError, () => calendar.call(Symbol()), "symbol"); -assert.throws(TypeError, () => calendar.call(1), "1"); -assert.throws(TypeError, () => calendar.call({}), "plain object"); -assert.throws(TypeError, () => calendar.call(Temporal.PlainDateTime), "Temporal.PlainDateTime"); -assert.throws(TypeError, () => calendar.call(Temporal.PlainDateTime.prototype), "Temporal.PlainDateTime.prototype"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/calendar/prop-desc.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/calendar/prop-desc.js deleted file mode 100644 index 9d3342896cb8..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/calendar/prop-desc.js +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-get-temporal.plaindatetime.prototype.calendar -description: The "calendar" property of Temporal.PlainDateTime.prototype -features: [Temporal] ----*/ - -const descriptor = Object.getOwnPropertyDescriptor(Temporal.PlainDateTime.prototype, "calendar"); -assert.sameValue(typeof descriptor.get, "function"); -assert.sameValue(descriptor.set, undefined); -assert.sameValue(descriptor.enumerable, false); -assert.sameValue(descriptor.configurable, true); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/calendarId/branding.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/calendarId/branding.js new file mode 100644 index 000000000000..d3413c78ecf3 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/calendarId/branding.js @@ -0,0 +1,22 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-get-temporal.plaindatetime.prototype.calendarid +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const calendarId = Object.getOwnPropertyDescriptor(Temporal.PlainDateTime.prototype, "calendarId").get; + +assert.sameValue(typeof calendarId, "function"); + +assert.throws(TypeError, () => calendarId.call(undefined), "undefined"); +assert.throws(TypeError, () => calendarId.call(null), "null"); +assert.throws(TypeError, () => calendarId.call(true), "true"); +assert.throws(TypeError, () => calendarId.call(""), "empty string"); +assert.throws(TypeError, () => calendarId.call(Symbol()), "symbol"); +assert.throws(TypeError, () => calendarId.call(1), "1"); +assert.throws(TypeError, () => calendarId.call({}), "plain object"); +assert.throws(TypeError, () => calendarId.call(Temporal.PlainDateTime), "Temporal.PlainDateTime"); +assert.throws(TypeError, () => calendarId.call(Temporal.PlainDateTime.prototype), "Temporal.PlainDateTime.prototype"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/calendarId/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/calendarId/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..404ce8f1bd9a --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/calendarId/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.calendarid +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const idOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "id"); +Object.defineProperty(Temporal.Calendar.prototype, "id", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("id should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, "iso8601"); +instance.calendarId; + +Object.defineProperty(Temporal.Calendar.prototype, "id", idOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/calendarId/prop-desc.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/calendarId/prop-desc.js new file mode 100644 index 000000000000..2f9a40413ad1 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/calendarId/prop-desc.js @@ -0,0 +1,14 @@ +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-get-temporal.plaindatetime.prototype.calendarid +description: The "calendarId" property of Temporal.PlainDateTime.prototype +features: [Temporal] +---*/ + +const descriptor = Object.getOwnPropertyDescriptor(Temporal.PlainDateTime.prototype, "calendarId"); +assert.sameValue(typeof descriptor.get, "function"); +assert.sameValue(descriptor.set, undefined); +assert.sameValue(descriptor.enumerable, false); +assert.sameValue(descriptor.configurable, true); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/day/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/day/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..fcafe7d67296 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/day/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.day +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const dayOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "day"); +Object.defineProperty(Temporal.Calendar.prototype, "day", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("day should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, "iso8601"); +instance.day; + +Object.defineProperty(Temporal.Calendar.prototype, "day", dayOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/dayOfWeek/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/dayOfWeek/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..1d692b7bdde6 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/dayOfWeek/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.dayofweek +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const dayOfWeekOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dayOfWeek"); +Object.defineProperty(Temporal.Calendar.prototype, "dayOfWeek", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("dayOfWeek should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, "iso8601"); +instance.dayOfWeek; + +Object.defineProperty(Temporal.Calendar.prototype, "dayOfWeek", dayOfWeekOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/dayOfYear/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/dayOfYear/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..99bbe5fc7aa5 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/dayOfYear/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.dayofyear +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const dayOfYearOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dayOfYear"); +Object.defineProperty(Temporal.Calendar.prototype, "dayOfYear", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("dayOfYear should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, "iso8601"); +instance.dayOfYear; + +Object.defineProperty(Temporal.Calendar.prototype, "dayOfYear", dayOfYearOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/daysInMonth/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/daysInMonth/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..e88de1affa6c --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/daysInMonth/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.daysinmonth +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const daysInMonthOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "daysInMonth"); +Object.defineProperty(Temporal.Calendar.prototype, "daysInMonth", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("daysInMonth should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, "iso8601"); +instance.daysInMonth; + +Object.defineProperty(Temporal.Calendar.prototype, "daysInMonth", daysInMonthOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/daysInWeek/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/daysInWeek/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..43d327af3d09 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/daysInWeek/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.daysinweek +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const daysInWeekOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "daysInWeek"); +Object.defineProperty(Temporal.Calendar.prototype, "daysInWeek", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("daysInWeek should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, "iso8601"); +instance.daysInWeek; + +Object.defineProperty(Temporal.Calendar.prototype, "daysInWeek", daysInWeekOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/daysInYear/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/daysInYear/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..f4ffd20eb144 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/daysInYear/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.daysinyear +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const daysInYearOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "daysInYear"); +Object.defineProperty(Temporal.Calendar.prototype, "daysInYear", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("daysInYear should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, "iso8601"); +instance.daysInYear; + +Object.defineProperty(Temporal.Calendar.prototype, "daysInYear", daysInYearOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/equals/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/equals/argument-propertybag-calendar-case-insensitive.js index 7d1f00f5fd23..b0ed162f6f87 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/equals/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/equals/argument-propertybag-calendar-case-insensitive.js @@ -11,10 +11,6 @@ const instance = new Temporal.PlainDateTime(1976, 11, 18); const calendar = "IsO8601"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.equals(arg); -assert.sameValue(result1, true, "Calendar is case-insensitive"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.equals(arg); -assert.sameValue(result2, true, "Calendar is case-insensitive (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.equals(arg); +assert.sameValue(result, true, "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/equals/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/equals/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index b9c52f4d0cb1..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/equals/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,25 +0,0 @@ -// 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.equals -description: > - A Temporal.Calendar instance passed to equals() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.PlainDateTime(1976, 11, 18); - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -instance.equals(arg); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -instance.equals(arg); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/equals/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/equals/argument-propertybag-calendar-leap-second.js index 2ef93da20c01..018b01f2c74e 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/equals/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/equals/argument-propertybag-calendar-leap-second.js @@ -11,18 +11,10 @@ const instance = new Temporal.PlainDateTime(1976, 11, 18); const calendar = "2016-12-31T23:59:60"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.equals(arg); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.equals(arg); assert.sameValue( - result1, + result, true, "leap second is a valid ISO string for calendar" ); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.equals(arg); -assert.sameValue( - result2, - true, - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/equals/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/equals/argument-propertybag-calendar-number.js index 347888b944a1..65f079bfd669 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/equals/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/equals/argument-propertybag-calendar-number.js @@ -11,13 +11,9 @@ const instance = new Temporal.PlainDateTime(1976, 11, 18); const calendar = 19970327; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.equals(arg); -assert.sameValue(result1, true, "19970327 is a valid ISO string for calendar"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.equals(arg); -assert.sameValue(result2, true, "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.equals(arg); +assert.sameValue(result, true, "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -26,16 +22,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; assert.throws( RangeError, () => instance.equals(arg), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.equals(arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/equals/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/equals/argument-propertybag-calendar-wrong-type.js index bfbdcec9462e..b98b48b43ea6 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/equals/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/equals/argument-propertybag-calendar-wrong-type.js @@ -21,27 +21,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.equals(arg), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.equals(arg), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.equals(arg), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.equals(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.equals(arg), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/equals/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/equals/argument-string-calendar-annotation.js index 1a09f0aad5c8..c5bb3fcb7bfc 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/equals/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/equals/argument-string-calendar-annotation.js @@ -13,7 +13,6 @@ const tests = [ ["1976-11-18T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["1976-11-18T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["1976-11-18T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["1976-11-18T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const instance = new Temporal.PlainDateTime(1976, 11, 18, 15, 23); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/equals/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/equals/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..a2d403dd13b8 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/equals/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.equals +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.equals(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/equals/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/equals/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..74b5c6dfae9d --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/equals/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.equals +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const idOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "id"); +Object.defineProperty(Temporal.Calendar.prototype, "id", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("id should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, "iso8601"); +instance.equals(new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321)); + +Object.defineProperty(Temporal.Calendar.prototype, "id", idOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/equals/calendar-checked.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/equals/calendar-checked.js index 0fe41c264cc4..bd13a761865f 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/equals/calendar-checked.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/equals/calendar-checked.js @@ -9,26 +9,99 @@ features: [Temporal] ---*/ const actual = []; -const calendar1 = TemporalHelpers.toPrimitiveObserver(actual, "A", "calendar1"); -const calendar2 = TemporalHelpers.toPrimitiveObserver(actual, "A", "calendar2"); -const calendar3 = TemporalHelpers.toPrimitiveObserver(actual, "B", "calendar3"); + +function makeCalendar(id, objectName) { + const calendar = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, + }; + TemporalHelpers.observeProperty(actual, calendar, "id", id, objectName); + return calendar; +} + +const calendar1 = makeCalendar("A", "calendar1"); +const calendar2 = makeCalendar("A", "calendar2"); +const calendar3 = makeCalendar("B", "calendar3"); const dt1 = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789, calendar1); const dt1b = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789, calendar1); const dt2 = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789, calendar2); const dt3 = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789, calendar3); +actual.splice(0); // disregard the HasProperty checks done in the constructor assert.sameValue(dt1.equals(dt1b), true, "same calendar object"); assert.compareArray(actual, []); assert.sameValue(dt1.equals(dt2), true, "same calendar string"); -assert.compareArray(actual, ["get calendar1.toString", "call calendar1.toString", "get calendar2.toString", "call calendar2.toString"]); +assert.compareArray(actual, ["get calendar1.id", "get calendar2.id"]); actual.splice(0); // empty it for the next check assert.sameValue(dt1.equals(dt3), false, "different calendar string"); -assert.compareArray(actual, ["get calendar1.toString", "call calendar1.toString", "get calendar3.toString", "call calendar3.toString"]); +assert.compareArray(actual, ["get calendar1.id", "get calendar3.id"]); -const calendar4 = { toString() { throw new Test262Error("should not call calendar4.toString") } }; -const calendar5 = { toString() { throw new Test262Error("should not call calendar5.toString") } }; +const calendar4 = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + get id() { TemporalHelpers.assertUnreachable('should not get calendar4.id'); }, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; +const calendar5 = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + get id() { TemporalHelpers.assertUnreachable('should not get calendar5.id'); }, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; const dt4 = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789, calendar4); const dt5 = new Temporal.PlainDateTime(2019, 10, 29, 10, 46, 38, 271, 986, 102, calendar4); const dt6 = new Temporal.PlainDateTime(2019, 10, 29, 10, 46, 38, 271, 986, 102, calendar5); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/getCalendar/branding.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/getCalendar/branding.js new file mode 100644 index 000000000000..556f515cde17 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/getCalendar/branding.js @@ -0,0 +1,22 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.getcalendar +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const getCalendar = Temporal.PlainDateTime.prototype.getCalendar; + +assert.sameValue(typeof getCalendar, "function"); + +assert.throws(TypeError, () => getCalendar.call(undefined), "undefined"); +assert.throws(TypeError, () => getCalendar.call(null), "null"); +assert.throws(TypeError, () => getCalendar.call(true), "true"); +assert.throws(TypeError, () => getCalendar.call(""), "empty string"); +assert.throws(TypeError, () => getCalendar.call(Symbol()), "symbol"); +assert.throws(TypeError, () => getCalendar.call(1), "1"); +assert.throws(TypeError, () => getCalendar.call({}), "plain object"); +assert.throws(TypeError, () => getCalendar.call(Temporal.PlainDateTime), "Temporal.PlainDateTime"); +assert.throws(TypeError, () => getCalendar.call(Temporal.PlainDateTime.prototype), "Temporal.PlainDateTime.prototype"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/getCalendar/builtin.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/getCalendar/builtin.js new file mode 100644 index 000000000000..8073d1423d37 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/getCalendar/builtin.js @@ -0,0 +1,33 @@ +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.getcalendar +description: > + Tests that Temporal.PlainDateTime.prototype.getCalendar + meets the requirements for built-in objects defined by the + introduction of chapter 17 of the ECMAScript Language Specification. +info: | + Built-in functions that are not constructors do not have a "prototype" property unless + otherwise specified in the description of a particular function. + + Unless specified otherwise, a built-in object that is callable as a function is a built-in + function object with the characteristics described in 10.3. Unless specified otherwise, the + [[Extensible]] internal slot of a built-in object initially has the value true. + + Unless otherwise specified every built-in function and every built-in constructor has the + Function prototype object [...] as the value of its [[Prototype]] internal slot. +features: [Temporal] +---*/ + +assert.sameValue(Object.isExtensible(Temporal.PlainDateTime.prototype.getCalendar), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.PlainDateTime.prototype.getCalendar), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.PlainDateTime.prototype.getCalendar), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.PlainDateTime.prototype.getCalendar.hasOwnProperty("prototype"), + false, "prototype property"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/getCalendar/length.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/getCalendar/length.js new file mode 100644 index 000000000000..4aa0b2f9e584 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/getCalendar/length.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.getcalendar +description: Temporal.PlainDateTime.prototype.getCalendar.length is 0 +info: | + Every built-in function object, including constructors, has a "length" property whose value is + an integer. Unless otherwise specified, this value is equal to the largest number of named + arguments shown in the subclause headings for the function description. Optional parameters + (which are indicated with brackets: [ ]) or rest parameters (which are shown using the form + «...name») are not included in the default argument count. + + Unless otherwise specified, the "length" property of a built-in function object has the + attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +verifyProperty(Temporal.PlainDateTime.prototype.getCalendar, "length", { + value: 0, + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/getCalendar/name.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/getCalendar/name.js new file mode 100644 index 000000000000..55a49aa11fb7 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/getCalendar/name.js @@ -0,0 +1,23 @@ +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.getcalendar +description: Temporal.PlainDateTime.prototype.getCalendar.name is "getCalendar". +info: | + Every built-in function object, including constructors, that is not identified as an anonymous + function has a "name" property whose value is a String. Unless otherwise specified, this value + is the name that is given to the function in this specification. + + Unless otherwise specified, the "name" property of a built-in function object, if it exists, + has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +verifyProperty(Temporal.PlainDateTime.prototype.getCalendar, "name", { + value: "getCalendar", + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/getCalendar/not-a-constructor.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/getCalendar/not-a-constructor.js new file mode 100644 index 000000000000..1500ff41ce17 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/getCalendar/not-a-constructor.js @@ -0,0 +1,21 @@ +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.getcalendar +description: > + Temporal.PlainDateTime.prototype.getCalendar does not implement [[Construct]], is not new-able +info: | + Built-in function objects that are not identified as constructors do not implement the + [[Construct]] internal method unless otherwise specified in the description of a particular + function. +includes: [isConstructor.js] +features: [Reflect.construct, Temporal] +---*/ + +assert.throws(TypeError, () => { + new Temporal.PlainDateTime.prototype.getCalendar(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.PlainDateTime.prototype.getCalendar), false, + "isConstructor(Temporal.PlainDateTime.prototype.getCalendar)"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/getCalendar/prop-desc.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/getCalendar/prop-desc.js new file mode 100644 index 000000000000..0896290df60b --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/getCalendar/prop-desc.js @@ -0,0 +1,21 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.getcalendar +description: The "getCalendar" property of Temporal.PlainDateTime.prototype +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.PlainDateTime.prototype.getCalendar, + "function", + "`typeof PlainDateTime.prototype.getCalendar` is `function`" +); + +verifyProperty(Temporal.PlainDateTime.prototype, "getCalendar", { + writable: true, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/getISOFields/field-names.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/getISOFields/field-names.js index f444e829d572..d34f56f6d528 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/getISOFields/field-names.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/getISOFields/field-names.js @@ -19,4 +19,4 @@ assert.sameValue(result.isoSecond, 56, "isoSecond result"); assert.sameValue(result.isoMillisecond, 987, "isoMillisecond result"); assert.sameValue(result.isoMicrosecond, 654, "isoMicrosecond result"); assert.sameValue(result.isoNanosecond, 321, "isoNanosecond result"); -assert.sameValue(result.calendar.id, "iso8601", "calendar result"); +assert.sameValue(result.calendar, "iso8601", "calendar result"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/inLeapYear/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/inLeapYear/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..f14f52befbaa --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/inLeapYear/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.inleapyear +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const inLeapYearOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "inLeapYear"); +Object.defineProperty(Temporal.Calendar.prototype, "inLeapYear", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("inLeapYear should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, "iso8601"); +instance.inLeapYear; + +Object.defineProperty(Temporal.Calendar.prototype, "inLeapYear", inLeapYearOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/month/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/month/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..0e2b4b866897 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/month/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.month +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const monthOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "month"); +Object.defineProperty(Temporal.Calendar.prototype, "month", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("month should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, "iso8601"); +instance.month; + +Object.defineProperty(Temporal.Calendar.prototype, "month", monthOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/monthCode/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/monthCode/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..705187ff7e27 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/monthCode/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.monthcode +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const monthCodeOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "monthCode"); +Object.defineProperty(Temporal.Calendar.prototype, "monthCode", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("monthCode should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, "iso8601"); +instance.monthCode; + +Object.defineProperty(Temporal.Calendar.prototype, "monthCode", monthCodeOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/monthsInYear/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/monthsInYear/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..2ea990acbaf7 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/monthsInYear/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.monthsinyear +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const monthsInYearOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "monthsInYear"); +Object.defineProperty(Temporal.Calendar.prototype, "monthsInYear", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("monthsInYear should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, "iso8601"); +instance.monthsInYear; + +Object.defineProperty(Temporal.Calendar.prototype, "monthsInYear", monthsInYearOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-case-insensitive.js index b9ec567572f1..1f8bac6a786b 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-case-insensitive.js @@ -12,10 +12,6 @@ const instance = new Temporal.PlainDateTime(1976, 11, 18); const calendar = "IsO8601"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.since(arg); -TemporalHelpers.assertDuration(result1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Calendar is case-insensitive"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.since(arg); -TemporalHelpers.assertDuration(result2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Calendar is case-insensitive (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.since(arg); +TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 253e512efbca..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,25 +0,0 @@ -// 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.since -description: > - A Temporal.Calendar instance passed to since() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.PlainDateTime(1976, 11, 18); - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -instance.since(arg); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -instance.since(arg); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-leap-second.js index dd989748cced..7a1f7672bd60 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-leap-second.js @@ -12,18 +12,10 @@ const instance = new Temporal.PlainDateTime(1976, 11, 18); const calendar = "2016-12-31T23:59:60"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.since(arg); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.since(arg); TemporalHelpers.assertDuration( - result1, + result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "leap second is a valid ISO string for calendar" ); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.since(arg); -TemporalHelpers.assertDuration( - result2, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-number.js index e12a26b7351a..3f116e5ade9c 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-number.js @@ -12,13 +12,9 @@ const instance = new Temporal.PlainDateTime(1976, 11, 18); const calendar = 19970327; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.since(arg); -TemporalHelpers.assertDuration(result1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.since(arg); -TemporalHelpers.assertDuration(result2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.since(arg); +TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -27,16 +23,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; assert.throws( RangeError, () => instance.since(arg), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.since(arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-wrong-type.js index 42f638759c2c..65d510b3a23f 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-wrong-type.js @@ -21,27 +21,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.since(arg), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.since(arg), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.since(arg), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.since(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.since(arg), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/argument-string-calendar-annotation.js index aa14181bf7f7..320a373038d5 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/argument-string-calendar-annotation.js @@ -14,7 +14,6 @@ const tests = [ ["1976-11-18T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["1976-11-18T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["1976-11-18T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["1976-11-18T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const instance = new Temporal.PlainDateTime(1976, 11, 18, 15, 23); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..3168687432d4 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.since +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.since(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..1eb71403dd55 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.since +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const dateUntilOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dateUntil"); +Object.defineProperty(Temporal.Calendar.prototype, "dateUntil", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("dateUntil should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, "iso8601"); +instance.since(new Temporal.PlainDateTime(1999, 4, 1)); + +Object.defineProperty(Temporal.Calendar.prototype, "dateUntil", dateUntilOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/calendar-dateuntil-called-with-plaindate-calendar.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/calendar-dateuntil-called-with-plaindate-calendar.js index 69f335a7235f..4ed21f10f71f 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/calendar-dateuntil-called-with-plaindate-calendar.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/calendar-dateuntil-called-with-plaindate-calendar.js @@ -19,8 +19,8 @@ class Calendar extends Temporal.Calendar { } dateUntil(d1, d2) { - assert.sameValue(d1.calendar, this, "d1.calendar"); - assert.sameValue(d2.calendar, this, "d2.calendar"); + assert.sameValue(d1.getCalendar(), this, "d1.calendar"); + assert.sameValue(d2.getCalendar(), this, "d2.calendar"); return new Temporal.Duration(); } } diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/different-calendars-throws.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/different-calendars-throws.js index 6312b4748c4b..19c34416c28b 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/different-calendars-throws.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/different-calendars-throws.js @@ -8,7 +8,29 @@ features: [Temporal] ---*/ const dt1 = new Temporal.PlainDateTime(2000, 1, 1, 0, 0, 0, 0, 0, 0); -const dt2 = new Temporal.PlainDateTime(2000, 1, 1, 0, 0, 0, 0, 0, 0, {}); +const dt2 = new Temporal.PlainDateTime(2000, 1, 1, 0, 0, 0, 0, 0, 0, { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "custom", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}); assert.throws( RangeError, diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/order-of-operations.js index ff3b818c4b69..e1b7deb4e60d 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/since/order-of-operations.js @@ -11,7 +11,27 @@ features: [Temporal] const expected = [ // ToTemporalDateTime "get other.calendar", - "has other.calendar.calendar", + "has other.calendar.dateAdd", + "has other.calendar.dateFromFields", + "has other.calendar.dateUntil", + "has other.calendar.day", + "has other.calendar.dayOfWeek", + "has other.calendar.dayOfYear", + "has other.calendar.daysInMonth", + "has other.calendar.daysInWeek", + "has other.calendar.daysInYear", + "has other.calendar.fields", + "has other.calendar.id", + "has other.calendar.inLeapYear", + "has other.calendar.mergeFields", + "has other.calendar.month", + "has other.calendar.monthCode", + "has other.calendar.monthDayFromFields", + "has other.calendar.monthsInYear", + "has other.calendar.weekOfYear", + "has other.calendar.year", + "has other.calendar.yearMonthFromFields", + "has other.calendar.yearOfWeek", "get other.calendar.fields", "call other.calendar.fields", "get other.day", @@ -47,12 +67,8 @@ const expected = [ "get other.calendar.dateFromFields", "call other.calendar.dateFromFields", // CalendarEquals - "get this.calendar[Symbol.toPrimitive]", - "get this.calendar.toString", - "call this.calendar.toString", - "get other.calendar[Symbol.toPrimitive]", - "get other.calendar.toString", - "call other.calendar.toString", + "get this.calendar.id", + "get other.calendar.id", // CopyDataProperties "ownKeys options", "getOwnPropertyDescriptor options.roundingIncrement", diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/subtract/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/subtract/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..962a000bef87 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/subtract/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.subtract +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const dateAddOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dateAdd"); +Object.defineProperty(Temporal.Calendar.prototype, "dateAdd", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("dateAdd should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, "iso8601"); +instance.subtract(new Temporal.Duration(1)); + +Object.defineProperty(Temporal.Calendar.prototype, "dateAdd", dateAddOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toJSON/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toJSON/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..cc9cca96dcea --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toJSON/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.tojson +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const idOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "id"); +Object.defineProperty(Temporal.Calendar.prototype, "id", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("id should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, "iso8601"); +instance.toJSON(); + +Object.defineProperty(Temporal.Calendar.prototype, "id", idOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toLocaleString/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toLocaleString/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..e19393fd33aa --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toLocaleString/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.tolocalestring +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const idOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "id"); +Object.defineProperty(Temporal.Calendar.prototype, "id", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("id should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, "iso8601"); +instance.toLocaleString(); + +Object.defineProperty(Temporal.Calendar.prototype, "id", idOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toPlainMonthDay/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toPlainMonthDay/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..15a3b27d55dd --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toPlainMonthDay/builtin-calendar-no-observable-calls.js @@ -0,0 +1,34 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.toplainmonthday +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const fieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "fields"); +Object.defineProperty(Temporal.Calendar.prototype, "fields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("fields should not be looked up"); + }, +}); +const monthDayFromFieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "monthDayFromFields"); +Object.defineProperty(Temporal.Calendar.prototype, "monthDayFromFields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("monthDayFromFields should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, "iso8601"); +instance.toPlainMonthDay(); + +Object.defineProperty(Temporal.Calendar.prototype, "fields", fieldsOriginal); +Object.defineProperty(Temporal.Calendar.prototype, "monthDayFromFields", monthDayFromFieldsOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toPlainYearMonth/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toPlainYearMonth/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..10bfc19fe3e8 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toPlainYearMonth/builtin-calendar-no-observable-calls.js @@ -0,0 +1,34 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.toplainyearmonth +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const fieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "fields"); +Object.defineProperty(Temporal.Calendar.prototype, "fields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("fields should not be looked up"); + }, +}); +const yearMonthFromFieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "yearMonthFromFields"); +Object.defineProperty(Temporal.Calendar.prototype, "yearMonthFromFields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("yearMonthFromFields should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, "iso8601"); +instance.toPlainYearMonth(); + +Object.defineProperty(Temporal.Calendar.prototype, "fields", fieldsOriginal); +Object.defineProperty(Temporal.Calendar.prototype, "yearMonthFromFields", yearMonthFromFieldsOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toString/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toString/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..2203f6dba1a4 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toString/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 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: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const idOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "id"); +Object.defineProperty(Temporal.Calendar.prototype, "id", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("id should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, "iso8601"); +instance.toString(); + +Object.defineProperty(Temporal.Calendar.prototype, "id", idOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toString/calendar-tostring.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toString/calendar-tostring.js index 14538ab4cb1c..a105b5f5136b 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toString/calendar-tostring.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toString/calendar-tostring.js @@ -4,15 +4,39 @@ /*--- esid: sec-temporal.plaindatetime.protoype.tostring description: Number of observable 'toString' calls on the calendar for each value of calendarName +includes: [temporalHelpers.js] features: [Temporal] ---*/ let calls; const customCalendar = { - toString() { + get id() { ++calls; return "custom"; - } + }, + toString() { + TemporalHelpers.assertUnreachable('toString should not be called'); + }, + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, }; const date = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, customCalendar); [ @@ -24,6 +48,6 @@ const date = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, c ].forEach(([calendarName, expectedResult, expectedCalls]) => { calls = 0; const result = date.toString({ calendarName }); - assert.sameValue(result, expectedResult, `toString output for calendarName = ${calendarName}`); - assert.sameValue(calls, expectedCalls, `calls to toString for calendarName = ${calendarName}`); + assert.sameValue(result, expectedResult, `id for calendarName = ${calendarName}`); + assert.sameValue(calls, expectedCalls, `calls to id getter for calendarName = ${calendarName}`); }); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-always.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-always.js index a66b1995d312..53659c46445b 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-always.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-always.js @@ -7,12 +7,35 @@ description: If calendarName is "always", the calendar ID should be included. features: [Temporal] ---*/ +const calendarMethods = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; + const tests = [ [[], "1976-11-18T15:23:00[u-ca=iso8601]", "built-in ISO"], - [[{ toString() { return "custom"; } }], "1976-11-18T15:23:00[u-ca=custom]", "custom"], - [[{ toString() { return "iso8601"; } }], "1976-11-18T15:23:00[u-ca=iso8601]", "custom with iso8601 toString"], - [[{ toString() { return "ISO8601"; } }], "1976-11-18T15:23:00[u-ca=ISO8601]", "custom with caps toString"], - [[{ toString() { return "\u0131so8601"; } }], "1976-11-18T15:23:00[u-ca=\u0131so8601]", "custom with dotless i toString"], + [[{ id: "custom", ...calendarMethods }], "1976-11-18T15:23:00[u-ca=custom]", "custom"], + [[{ id: "iso8601", ...calendarMethods }], "1976-11-18T15:23:00[u-ca=iso8601]", "custom with iso8601 id"], + [[{ id: "ISO8601", ...calendarMethods }], "1976-11-18T15:23:00[u-ca=ISO8601]", "custom with caps id"], + [[{ id: "\u0131so8601", ...calendarMethods }], "1976-11-18T15:23:00[u-ca=\u0131so8601]", "custom with dotless i id"], ]; for (const [args, expected, description] of tests) { diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-auto.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-auto.js index c8945caf9b16..31f669617ccc 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-auto.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-auto.js @@ -7,12 +7,35 @@ description: If calendarName is "auto", "iso8601" should be omitted. features: [Temporal] ---*/ +const calendarMethods = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; + const tests = [ [[], "1976-11-18T15:23:00", "built-in ISO"], - [[{ toString() { return "custom"; } }], "1976-11-18T15:23:00[u-ca=custom]", "custom"], - [[{ toString() { return "iso8601"; } }], "1976-11-18T15:23:00", "custom with iso8601 toString"], - [[{ toString() { return "ISO8601"; } }], "1976-11-18T15:23:00[u-ca=ISO8601]", "custom with caps toString"], - [[{ toString() { return "\u0131so8601"; } }], "1976-11-18T15:23:00[u-ca=\u0131so8601]", "custom with dotless i toString"], + [[{ id: "custom", ...calendarMethods }], "1976-11-18T15:23:00[u-ca=custom]", "custom"], + [[{ id: "iso8601", ...calendarMethods }], "1976-11-18T15:23:00", "custom with iso8601 id"], + [[{ id: "ISO8601", ...calendarMethods }], "1976-11-18T15:23:00[u-ca=ISO8601]", "custom with caps id"], + [[{ id: "\u0131so8601", ...calendarMethods }], "1976-11-18T15:23:00[u-ca=\u0131so8601]", "custom with dotless i id"], ]; for (const [args, expected, description] of tests) { diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-critical.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-critical.js index 69bbe1add4cf..e3face2fc1e3 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-critical.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-critical.js @@ -9,12 +9,35 @@ description: > features: [Temporal] ---*/ +const calendarMethods = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; + const tests = [ [[], "1976-11-18T15:23:00[!u-ca=iso8601]", "built-in ISO"], - [[{ toString() { return "custom"; } }], "1976-11-18T15:23:00[!u-ca=custom]", "custom"], - [[{ toString() { return "iso8601"; } }], "1976-11-18T15:23:00[!u-ca=iso8601]", "custom with iso8601 toString"], - [[{ toString() { return "ISO8601"; } }], "1976-11-18T15:23:00[!u-ca=ISO8601]", "custom with caps toString"], - [[{ toString() { return "\u0131so8601"; } }], "1976-11-18T15:23:00[!u-ca=\u0131so8601]", "custom with dotless i toString"], + [[{ id: "custom", ...calendarMethods }], "1976-11-18T15:23:00[!u-ca=custom]", "custom"], + [[{ id: "iso8601", ...calendarMethods }], "1976-11-18T15:23:00[!u-ca=iso8601]", "custom with iso8601 id"], + [[{ id: "ISO8601", ...calendarMethods }], "1976-11-18T15:23:00[!u-ca=ISO8601]", "custom with caps id"], + [[{ id: "\u0131so8601", ...calendarMethods }], "1976-11-18T15:23:00[!u-ca=\u0131so8601]", "custom with dotless i id"], ]; for (const [args, expected, description] of tests) { diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-never.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-never.js index cd06f152fa9f..5cc5a4d24b2b 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-never.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-never.js @@ -7,12 +7,35 @@ description: If calendarName is "never", the calendar ID should be omitted. features: [Temporal] ---*/ +const calendarMethods = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; + const tests = [ [[], "1976-11-18T15:23:00", "built-in ISO"], - [[{ toString() { return "custom"; } }], "1976-11-18T15:23:00", "custom"], - [[{ toString() { return "iso8601"; } }], "1976-11-18T15:23:00", "custom with iso8601 toString"], - [[{ toString() { return "ISO8601"; } }], "1976-11-18T15:23:00", "custom with caps toString"], - [[{ toString() { return "\u0131so8601"; } }], "1976-11-18T15:23:00", "custom with dotless i toString"], + [[{ id: "custom", ...calendarMethods }], "1976-11-18T15:23:00", "custom"], + [[{ id: "iso8601", ...calendarMethods }], "1976-11-18T15:23:00", "custom with iso8601 id"], + [[{ id: "ISO8601", ...calendarMethods }], "1976-11-18T15:23:00", "custom with caps id"], + [[{ id: "\u0131so8601", ...calendarMethods }], "1976-11-18T15:23:00", "custom with dotless i id"], ]; for (const [args, expected, description] of tests) { diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-undefined.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-undefined.js index 800fac39da5a..fee3b9200531 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-undefined.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-undefined.js @@ -14,12 +14,35 @@ info: | features: [Temporal] ---*/ +const calendarMethods = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; + const tests = [ [[], "1976-11-18T15:23:00", "built-in ISO"], - [[{ toString() { return "custom"; } }], "1976-11-18T15:23:00[u-ca=custom]", "custom"], - [[{ toString() { return "iso8601"; } }], "1976-11-18T15:23:00", "custom with iso8601 toString"], - [[{ toString() { return "ISO8601"; } }], "1976-11-18T15:23:00[u-ca=ISO8601]", "custom with caps toString"], - [[{ toString() { return "\u0131so8601"; } }], "1976-11-18T15:23:00[u-ca=\u0131so8601]", "custom with dotless i toString"], + [[{ id: "custom", ...calendarMethods }], "1976-11-18T15:23:00[u-ca=custom]", "custom"], + [[{ id: "iso8601", ...calendarMethods }], "1976-11-18T15:23:00", "custom with iso8601 id"], + [[{ id: "ISO8601", ...calendarMethods }], "1976-11-18T15:23:00[u-ca=ISO8601]", "custom with caps id"], + [[{ id: "\u0131so8601", ...calendarMethods }], "1976-11-18T15:23:00[u-ca=\u0131so8601]", "custom with dotless i id"], ]; for (const [args, expected, description] of tests) { diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-wrong-type.js index a452be5bdba4..2786a47bb432 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-wrong-type.js @@ -16,7 +16,27 @@ features: [Temporal] ---*/ const calendar = { - toString() { return "custom"; } + id: "custom", + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, }; const datetime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, calendar); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toString/options-undefined.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toString/options-undefined.js index 0f19b561d29d..daa6083232d9 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toString/options-undefined.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toString/options-undefined.js @@ -8,7 +8,27 @@ features: [Temporal] ---*/ const calendar = { - toString() { return "custom"; } + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "custom", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, }; const datetime1 = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 650, 0); const datetime2 = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 650, 0, calendar); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toString/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toString/order-of-operations.js index 5596255315b5..231721be9028 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toString/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toString/order-of-operations.js @@ -21,9 +21,7 @@ const expected = [ "get options.smallestUnit", "get options.smallestUnit.toString", "call options.smallestUnit.toString", - "get this.calendar[Symbol.toPrimitive]", - "get this.calendar.toString", - "call this.calendar.toString", + "get this.calendar.id", ]; const actual = []; @@ -55,9 +53,7 @@ const expectedForFractionalSecondDigits = [ "get options.roundingMode.toString", "call options.roundingMode.toString", "get options.smallestUnit", - "get this.calendar[Symbol.toPrimitive]", - "get this.calendar.toString", - "call this.calendar.toString", + "get this.calendar.id", ]; instance.toString( diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/basic.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/basic.js index 78d23ba94233..6f26fe372d7d 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/basic.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/basic.js @@ -11,5 +11,5 @@ const dt = new Temporal.PlainDateTime(2020, 1, 1, 0, 0); const zdt = dt.toZonedDateTime("UTC"); assert.sameValue(zdt.epochNanoseconds, 1577836800000000000n, "nanoseconds"); -assert.sameValue(zdt.calendar.toString(), "iso8601", "calendar"); -assert.sameValue(zdt.timeZone.toString(), "UTC", "timezone"); +assert.sameValue(zdt.calendarId, "iso8601", "calendar"); +assert.sameValue(zdt.timeZoneId, "UTC", "timezone"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/order-of-operations.js index 166c4e377de7..813aaaac68dd 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/order-of-operations.js @@ -9,8 +9,10 @@ features: [Temporal] ---*/ const expected = [ - // ToTemporalTimeZone - "has timeZone.timeZone", + // ToTemporalTimeZoneSlotValue + "has timeZone.getOffsetNanosecondsFor", + "has timeZone.getPossibleInstantsFor", + "has timeZone.id", // ToTemporalDisambiguation "get options.disambiguation", "get options.disambiguation.toString", diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/plain-custom-timezone.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/plain-custom-timezone.js index 9549832a30e7..77e507cbfd6d 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/plain-custom-timezone.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/plain-custom-timezone.js @@ -10,7 +10,9 @@ features: [Temporal] const actual = []; const expected = [ - "has timeZone.timeZone", + "has timeZone.getOffsetNanosecondsFor", + "has timeZone.getPossibleInstantsFor", + "has timeZone.id", "get options.disambiguation", "get options.disambiguation.toString", "call options.disambiguation.toString", @@ -39,7 +41,8 @@ const timeZone = TemporalHelpers.timeZoneObserver(actual, "timeZone", { const result = dateTime.toZonedDateTime(timeZone, options); assert.sameValue(result.epochNanoseconds, instant.epochNanoseconds); -assert.sameValue(result.timeZone, timeZone); -assert.sameValue(result.calendar, dateTime.calendar); +assert.sameValue(result.getTimeZone(), timeZone); assert.compareArray(actual, expected); + +assert.sameValue(result.getISOFields().calendar, dateTime.getISOFields().calendar); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-case-insensitive.js index 4d0c3849811f..ad2532b30ec1 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-case-insensitive.js @@ -7,8 +7,8 @@ description: Time zone names are case insensitive features: [Temporal] ---*/ -const instance = new Temporal.PlainDateTime(2000, 5, 2); +const instance = new Temporal.PlainDateTime(2000, 5, 2); const timeZone = 'uTc'; const result = instance.toZonedDateTime(timeZone); -assert.sameValue(result.timeZone.id, 'UTC', `Time zone created from string "${timeZone}"`); +assert.sameValue(result.timeZoneId, 'UTC', `Time zone created from string "${timeZone}"`); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-instance-does-not-get-timeZone-property.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-instance-does-not-get-timeZone-property.js deleted file mode 100644 index f9f6a4ede12a..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-instance-does-not-get-timeZone-property.js +++ /dev/null @@ -1,22 +0,0 @@ -// 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: > - A Temporal.TimeZone instance passed to toZonedDateTime() does not have its - 'timeZone' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.PlainDateTime(2000, 5, 2); - -const timeZone = new Temporal.TimeZone("UTC"); -Object.defineProperty(timeZone, "timeZone", { - get() { - throw new Test262Error("timeZone.timeZone should not be accessed"); - }, -}); - -instance.toZonedDateTime(timeZone); -instance.toZonedDateTime({ timeZone }); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-string-datetime.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-string-datetime.js index eb953d36f51d..5ae2b549faf9 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-string-datetime.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-string-datetime.js @@ -11,34 +11,23 @@ const instance = new Temporal.PlainDateTime(2000, 5, 2); let timeZone = "2021-08-19T17:30"; assert.throws(RangeError, () => instance.toZonedDateTime(timeZone), "bare date-time string is not a time zone"); -assert.throws(RangeError, () => instance.toZonedDateTime({ timeZone }), "bare date-time string is not a time zone"); timeZone = "2021-08-19T17:30Z"; const result1 = instance.toZonedDateTime(timeZone); -assert.sameValue(result1.timeZone.id, "UTC", "date-time + Z is UTC time zone"); -const result2 = instance.toZonedDateTime({ timeZone }); -assert.sameValue(result2.timeZone.id, "UTC", "date-time + Z is UTC time zone (string in property bag)"); +assert.sameValue(result1.timeZoneId, "UTC", "date-time + Z is UTC time zone"); timeZone = "2021-08-19T17:30-07:00"; -const result3 = instance.toZonedDateTime(timeZone); -assert.sameValue(result3.timeZone.id, "-07:00", "date-time + offset is the offset time zone"); -const result4 = instance.toZonedDateTime({ timeZone }); -assert.sameValue(result4.timeZone.id, "-07:00", "date-time + offset is the offset time zone (string in property bag)"); +const result2 = instance.toZonedDateTime(timeZone); +assert.sameValue(result2.timeZoneId, "-07:00", "date-time + offset is the offset time zone"); timeZone = "2021-08-19T17:30[UTC]"; -const result5 = instance.toZonedDateTime(timeZone); -assert.sameValue(result5.timeZone.id, "UTC", "date-time + IANA annotation is the IANA time zone"); -const result6 = instance.toZonedDateTime({ timeZone }); -assert.sameValue(result6.timeZone.id, "UTC", "date-time + IANA annotation is the IANA time zone (string in property bag)"); +const result3 = instance.toZonedDateTime(timeZone); +assert.sameValue(result3.timeZoneId, "UTC", "date-time + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30Z[UTC]"; -const result7 = instance.toZonedDateTime(timeZone); -assert.sameValue(result7.timeZone.id, "UTC", "date-time + Z + IANA annotation is the IANA time zone"); -const result8 = instance.toZonedDateTime({ timeZone }); -assert.sameValue(result8.timeZone.id, "UTC", "date-time + Z + IANA annotation is the IANA time zone (string in property bag)"); +const result4 = instance.toZonedDateTime(timeZone); +assert.sameValue(result4.timeZoneId, "UTC", "date-time + Z + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30-07:00[UTC]"; -const result9 = instance.toZonedDateTime(timeZone); -assert.sameValue(result9.timeZone.id, "UTC", "date-time + offset + IANA annotation is the IANA time zone"); -const result10 = instance.toZonedDateTime({ timeZone }); -assert.sameValue(result10.timeZone.id, "UTC", "date-time + offset + IANA annotation is the IANA time zone (string in property bag)"); +const result5 = instance.toZonedDateTime(timeZone); +assert.sameValue(result5.timeZoneId, "UTC", "date-time + offset + IANA annotation is the IANA time zone"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-string-leap-second.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-string-leap-second.js index 9b02984eb902..e017519c3d1c 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-string-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-string-leap-second.js @@ -10,11 +10,8 @@ features: [Temporal] const instance = new Temporal.PlainDateTime(2000, 5, 2); let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; -const result1 = instance.toZonedDateTime(timeZone); -assert.sameValue(result1.timeZone.id, "UTC", "leap second is a valid ISO string for TimeZone"); -const result2 = instance.toZonedDateTime({ timeZone }); -assert.sameValue(result2.timeZone.id, "UTC", "leap second is a valid ISO string for TimeZone (nested property)"); +const result = instance.toZonedDateTime(timeZone); +assert.sameValue(result.timeZoneId, "UTC", "leap second is a valid ISO string for TimeZone"); timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; assert.throws(RangeError, () => instance.toZonedDateTime(timeZone), "leap second in time zone name not valid"); -assert.throws(RangeError, () => instance.toZonedDateTime({ timeZone }), "leap second in time zone name not valid (nested property)"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-string-multiple-offsets.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-string-multiple-offsets.js index 5e089b44d9d4..7c8c9a081925 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-string-multiple-offsets.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-string-multiple-offsets.js @@ -10,7 +10,5 @@ features: [Temporal] const instance = new Temporal.PlainDateTime(2000, 5, 2); const timeZone = "2021-08-19T17:30:45.123456789+01:46[+01:45:30.987654321]"; -const result1 = instance.toZonedDateTime(timeZone); -assert.sameValue(result1.timeZone.id, "+01:45:30.987654321", "Time zone string determined from bracket name"); -const result2 = instance.toZonedDateTime({ timeZone }); -assert.sameValue(result2.timeZone.id, "+01:45:30.987654321", "Time zone string determined from bracket name"); +const result = instance.toZonedDateTime(timeZone); +assert.sameValue(result.timeZoneId, "+01:45:30.987654321", "Time zone string determined from bracket name"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-string-year-zero.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-string-year-zero.js index 79caa639eb31..fe43b14d9866 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-string-year-zero.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-string-year-zero.js @@ -18,9 +18,4 @@ invalidStrings.forEach((timeZone) => { () => instance.toZonedDateTime(timeZone), "reject minus zero as extended year" ); - assert.throws( - RangeError, - () => instance.toZonedDateTime({ timeZone }), - "reject minus zero as extended year (nested property)" - ); }); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-string.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-string.js index 4447e4492edb..c685234e9c56 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-string.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-string.js @@ -4,12 +4,33 @@ /*--- esid: sec-temporal.plaindatetime.prototype.tozoneddatetime description: Time zone IDs are valid input for a time zone +includes: [temporalHelpers.js] features: [Temporal] ---*/ +const getPossibleInstantsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getPossibleInstantsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getPossibleInstantsFor should not be looked up"); + }, +}); +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + const instance = new Temporal.PlainDateTime(2000, 5, 2); ["UTC", "+01:30"].forEach((timeZone) => { const result = instance.toZonedDateTime(timeZone); - assert.sameValue(result.timeZone.id, timeZone, `Time zone created from string "${timeZone}"`); + assert.sameValue(result.getISOFields().timeZone, timeZone, `time zone slot should store string "${timeZone}"`); }); + +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", getPossibleInstantsForOriginal); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-wrong-type.js index 22889a713249..4538ced085f9 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-wrong-type.js @@ -18,22 +18,18 @@ const rangeErrorTests = [ [1, "number that doesn't convert to a valid ISO string"], [19761118, "number that would convert to a valid ISO string in other contexts"], [1n, "bigint"], - [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of rangeErrorTests) { assert.throws(RangeError, () => instance.toZonedDateTime(timeZone), `${description} does not convert to a valid ISO string`); - assert.throws(RangeError, () => instance.toZonedDateTime({ timeZone }), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], + [{}, "object not implementing time zone protocol"], + [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of typeErrorTests) { assert.throws(TypeError, () => instance.toZonedDateTime(timeZone), `${description} is not a valid object and does not convert to a string`); - assert.throws(TypeError, () => instance.toZonedDateTime({ timeZone }), `${description} is not a valid object and does not convert to a string (nested property)`); } - -const timeZone = undefined; -assert.throws(RangeError, () => instance.toZonedDateTime({ timeZone }), `undefined is always a RangeError as nested property`); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/argument-propertybag-calendar-case-insensitive.js index d0f739e30d07..2d9dd762cec9 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/argument-propertybag-calendar-case-insensitive.js @@ -12,10 +12,6 @@ const instance = new Temporal.PlainDateTime(1976, 11, 18); const calendar = "IsO8601"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.until(arg); -TemporalHelpers.assertDuration(result1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Calendar is case-insensitive"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.until(arg); -TemporalHelpers.assertDuration(result2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Calendar is case-insensitive (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.until(arg); +TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 1dfb4e252a92..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,25 +0,0 @@ -// 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.until -description: > - A Temporal.Calendar instance passed to until() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.PlainDateTime(1976, 11, 18); - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -instance.until(arg); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -instance.until(arg); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/argument-propertybag-calendar-leap-second.js index b49bd1593dcb..b50e3d3f41d0 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/argument-propertybag-calendar-leap-second.js @@ -12,18 +12,10 @@ const instance = new Temporal.PlainDateTime(1976, 11, 18); const calendar = "2016-12-31T23:59:60"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.until(arg); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.until(arg); TemporalHelpers.assertDuration( - result1, + result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "leap second is a valid ISO string for calendar" ); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.until(arg); -TemporalHelpers.assertDuration( - result2, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/argument-propertybag-calendar-number.js index 8cf4915c7f68..2ebeeaf99604 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/argument-propertybag-calendar-number.js @@ -12,13 +12,9 @@ const instance = new Temporal.PlainDateTime(1976, 11, 18); const calendar = 19970327; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.until(arg); -TemporalHelpers.assertDuration(result1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.until(arg); -TemporalHelpers.assertDuration(result2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.until(arg); +TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -27,16 +23,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; assert.throws( RangeError, () => instance.until(arg), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.until(arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/argument-propertybag-calendar-wrong-type.js index 611f6724cc09..12be4ae7ef27 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/argument-propertybag-calendar-wrong-type.js @@ -21,27 +21,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.until(arg), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.until(arg), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.until(arg), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.until(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.until(arg), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/argument-string-calendar-annotation.js index 56d241fdd57e..8ce263c82a29 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/argument-string-calendar-annotation.js @@ -14,7 +14,6 @@ const tests = [ ["1976-11-18T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["1976-11-18T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["1976-11-18T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["1976-11-18T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const instance = new Temporal.PlainDateTime(1976, 11, 18, 15, 23); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..021f66ecde05 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.until +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.until(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..3bf1018a697f --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.until +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const dateUntilOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dateUntil"); +Object.defineProperty(Temporal.Calendar.prototype, "dateUntil", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("dateUntil should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, "iso8601"); +instance.until(new Temporal.PlainDateTime(2001, 6, 13)); + +Object.defineProperty(Temporal.Calendar.prototype, "dateUntil", dateUntilOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/calendar-dateuntil-called-with-plaindate-calendar.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/calendar-dateuntil-called-with-plaindate-calendar.js index 7f255df452d3..ba28347ed662 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/calendar-dateuntil-called-with-plaindate-calendar.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/calendar-dateuntil-called-with-plaindate-calendar.js @@ -19,8 +19,8 @@ class Calendar extends Temporal.Calendar { } dateUntil(d1, d2) { - assert.sameValue(d1.calendar, this, "d1.calendar"); - assert.sameValue(d2.calendar, this, "d2.calendar"); + assert.sameValue(d1.getCalendar(), this, "d1.calendar"); + assert.sameValue(d2.getCalendar(), this, "d2.calendar"); return new Temporal.Duration(); } } diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/different-calendars-throws.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/different-calendars-throws.js index 1fe7a721911f..a644ccbd65a3 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/different-calendars-throws.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/different-calendars-throws.js @@ -8,7 +8,29 @@ features: [Temporal] ---*/ const dt1 = new Temporal.PlainDateTime(2000, 1, 1, 0, 0, 0, 0, 0, 0); -const dt2 = new Temporal.PlainDateTime(2000, 1, 1, 0, 0, 0, 0, 0, 0, {}); +const dt2 = new Temporal.PlainDateTime(2000, 1, 1, 0, 0, 0, 0, 0, 0, { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "custom", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}); assert.throws( RangeError, diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/order-of-operations.js index df5143b24a6b..43ea0733d9be 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/until/order-of-operations.js @@ -11,7 +11,27 @@ features: [Temporal] const expected = [ // ToTemporalDateTime "get other.calendar", - "has other.calendar.calendar", + "has other.calendar.dateAdd", + "has other.calendar.dateFromFields", + "has other.calendar.dateUntil", + "has other.calendar.day", + "has other.calendar.dayOfWeek", + "has other.calendar.dayOfYear", + "has other.calendar.daysInMonth", + "has other.calendar.daysInWeek", + "has other.calendar.daysInYear", + "has other.calendar.fields", + "has other.calendar.id", + "has other.calendar.inLeapYear", + "has other.calendar.mergeFields", + "has other.calendar.month", + "has other.calendar.monthCode", + "has other.calendar.monthDayFromFields", + "has other.calendar.monthsInYear", + "has other.calendar.weekOfYear", + "has other.calendar.year", + "has other.calendar.yearMonthFromFields", + "has other.calendar.yearOfWeek", "get other.calendar.fields", "call other.calendar.fields", "get other.day", @@ -47,12 +67,8 @@ const expected = [ "get other.calendar.dateFromFields", "call other.calendar.dateFromFields", // CalendarEquals - "get this.calendar[Symbol.toPrimitive]", - "get this.calendar.toString", - "call this.calendar.toString", - "get other.calendar[Symbol.toPrimitive]", - "get other.calendar.toString", - "call other.calendar.toString", + "get this.calendar.id", + "get other.calendar.id", // CopyDataProperties "ownKeys options", "getOwnPropertyDescriptor options.roundingIncrement", diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/weekOfYear/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/weekOfYear/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..ac2f66133aec --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/weekOfYear/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.weekofyear +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const weekOfYearOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "weekOfYear"); +Object.defineProperty(Temporal.Calendar.prototype, "weekOfYear", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("weekOfYear should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, "iso8601"); +instance.weekOfYear; + +Object.defineProperty(Temporal.Calendar.prototype, "weekOfYear", weekOfYearOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/with/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/with/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..27b0e439fe83 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/with/builtin-calendar-no-observable-calls.js @@ -0,0 +1,43 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.with +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const fieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "fields"); +Object.defineProperty(Temporal.Calendar.prototype, "fields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("fields should not be looked up"); + }, +}); +const mergeFieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "mergeFields"); +Object.defineProperty(Temporal.Calendar.prototype, "mergeFields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("mergeFields should not be looked up"); + }, +}); +const dateFromFieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dateFromFields"); +Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("dateFromFields should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, "iso8601"); +instance.with({ year: 2001 }); + +Object.defineProperty(Temporal.Calendar.prototype, "fields", fieldsOriginal); +Object.defineProperty(Temporal.Calendar.prototype, "mergeFields", mergeFieldsOriginal); +Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", dateFromFieldsOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/with/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/with/order-of-operations.js index 8029d4fc9502..3d2e6afef28a 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/with/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/with/order-of-operations.js @@ -18,10 +18,16 @@ const expected = [ // PrepareTemporalFields on receiver "get this.calendar.day", "call this.calendar.day", + "get this.hour", + "get this.microsecond", + "get this.millisecond", + "get this.minute", "get this.calendar.month", "call this.calendar.month", "get this.calendar.monthCode", "call this.calendar.monthCode", + "get this.nanosecond", + "get this.second", "get this.calendar.year", "call this.calendar.year", // PrepareTemporalFields on argument @@ -76,6 +82,13 @@ const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 32 // clear observable operations that occurred during the constructor call actual.splice(0); +TemporalHelpers.observeProperty(actual, instance, "hour", 12, "this"); +TemporalHelpers.observeProperty(actual, instance, "minute", 34, "this"); +TemporalHelpers.observeProperty(actual, instance, "second", 56, "this"); +TemporalHelpers.observeProperty(actual, instance, "millisecond", 987, "this"); +TemporalHelpers.observeProperty(actual, instance, "microsecond", 654, "this"); +TemporalHelpers.observeProperty(actual, instance, "nanosecond", 321, "this"); + const fields = TemporalHelpers.propertyBagObserver(actual, { year: 1.7, month: 1.7, diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/argument-string.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/argument-string.js index b75ace828f85..249c69712f04 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/argument-string.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/argument-string.js @@ -9,7 +9,28 @@ includes: [temporalHelpers.js] ---*/ const calendar = { - toString() { return "something special"; } + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "something special", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + toString() { return "something special"; }, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, }; const dt = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789, calendar); const result = dt.withCalendar("iso8601"); @@ -20,16 +41,12 @@ TemporalHelpers.assertPlainDateTime( "'iso8601' is a recognizable calendar" ); -const resultCalendar = result.calendar; - assert.sameValue( - resultCalendar instanceof Temporal.Calendar, - true, - "underlying calendar is no longer a plain object" + result.getISOFields().calendar, + "iso8601", + "underlying calendar has changed and calendar slot stores a string" ); -assert.sameValue(resultCalendar.toString(), "iso8601", "underlying calendar has changed"); - assert.throws( RangeError, () => dt.withCalendar("this will fail"), diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/basic.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/basic.js index 318f552ab542..3e5f2f4bc88a 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/basic.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/basic.js @@ -19,4 +19,4 @@ TemporalHelpers.assertPlainDateTime( "works" ); -assert.sameValue(result.calendar, calendar, "underlying calendar is unchanged"); +assert.sameValue(result.getCalendar(), calendar, "underlying calendar is unchanged"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..dda94fb31fa3 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.withcalendar +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const idOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "id"); +Object.defineProperty(Temporal.Calendar.prototype, "id", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("id should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, "iso8601"); +instance.withCalendar("iso8601"); + +Object.defineProperty(Temporal.Calendar.prototype, "id", idOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-case-insensitive.js index cdca3fe44f95..9af65170f6b1 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-case-insensitive.js @@ -7,8 +7,30 @@ description: Calendar names are case-insensitive features: [Temporal] ---*/ -const instance = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789, { id: "replace-me" }); +const instance = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789, { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "replace-me", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}); const arg = "iSo8601"; const result = instance.withCalendar(arg); -assert.sameValue(result.calendar.id, "iso8601", "Calendar is case-insensitive"); +assert.sameValue(result.calendarId, "iso8601", "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 423e131faab9..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,22 +0,0 @@ -// 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.withcalendar -description: > - A Temporal.Calendar instance passed to withCalendar() does not have its - 'calendar' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789, { id: "replace-me" }); - -const arg = new Temporal.Calendar("iso8601"); -Object.defineProperty(arg, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -instance.withCalendar(arg); -instance.withCalendar({ calendar: arg }); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-number.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-number.js index 3289014fc493..e06e31bd52d2 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-number.js @@ -7,12 +7,34 @@ description: A number is converted to a string, then to Temporal.Calendar features: [Temporal] ---*/ -const instance = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789, { id: "replace-me" }); +const instance = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789, { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "replace-me", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}); const arg = 19761118; const result = instance.withCalendar(arg); -assert.sameValue(result.calendar.id, "iso8601", "19761118 is a valid ISO string for Calendar"); +assert.sameValue(result.calendarId, "iso8601", "19761118 is a valid ISO string for Calendar"); const numbers = [ 1, diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-string-leap-second.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-string-leap-second.js index 02ea408591f6..e6f877f4ab2b 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-string-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-string-leap-second.js @@ -7,20 +7,34 @@ description: Leap second is a valid ISO string for Calendar features: [Temporal] ---*/ -const instance = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789, { id: "replace-me" }); +const instance = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789, { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "replace-me", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}); -let arg = "2016-12-31T23:59:60"; -const result1 = instance.withCalendar(arg); +const arg = "2016-12-31T23:59:60"; +const result = instance.withCalendar(arg); assert.sameValue( - result1.calendar.id, + result.calendarId, "iso8601", "leap second is a valid ISO string for Calendar" ); - -arg = { calendar: "2016-12-31T23:59:60" }; -const result2 = instance.withCalendar(arg); -assert.sameValue( - result2.calendar.id, - "iso8601", - "leap second is a valid ISO string for Calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-string.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-string.js index 68f1313e47fc..6f570a53b7c1 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-string.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-string.js @@ -7,9 +7,31 @@ description: A calendar ID is valid input for Calendar features: [Temporal] ---*/ -const instance = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789, { id: "replace-me" }); +const instance = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789, { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "replace-me", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}); const arg = "iso8601"; const result = instance.withCalendar(arg); -assert.sameValue(result.calendar.id, "iso8601", `Calendar created from string "${arg}"`); +assert.sameValue(result.getISOFields().calendar, "iso8601", `Calendar created from string "${arg}"`); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-temporal-object.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-temporal-object.js index e69ed75dccb8..d7dc08986686 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-temporal-object.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-temporal-object.js @@ -6,7 +6,7 @@ esid: sec-temporal.plaindatetime.prototype.withcalendar description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots info: | sec-temporal-totemporalcalendar step 1.b: - b. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then + b. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then i. Return _temporalCalendarLike_.[[Calendar]]. includes: [compareArray.js] features: [Temporal] @@ -14,12 +14,11 @@ features: [Temporal] const plainDate = new Temporal.PlainDate(2000, 5, 2); const plainDateTime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); -const plainTime = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); const plainMonthDay = new Temporal.PlainMonthDay(5, 2); const plainYearMonth = new Temporal.PlainYearMonth(2000, 5); const zonedDateTime = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); -[plainDate, plainDateTime, plainTime, plainMonthDay, plainYearMonth, zonedDateTime].forEach((arg) => { +[plainDate, plainDateTime, plainMonthDay, plainYearMonth, zonedDateTime].forEach((arg) => { const actual = []; const expected = []; @@ -32,9 +31,31 @@ const zonedDateTime = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UT }, }); - const instance = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789, { id: "replace-me" }); + const instance = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789, { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "replace-me", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}); const result = instance.withCalendar(arg); - assert.sameValue(result.calendar, calendar, "Temporal object coerced to calendar"); + assert.sameValue(result.getISOFields().calendar, calendar, "Temporal object coerced to calendar"); assert.compareArray(actual, expected, "calendar getter not called"); }); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-wrong-type.js index d1573af2d1c3..a6c8fdd6e4e6 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-wrong-type.js @@ -9,7 +9,29 @@ description: > features: [BigInt, Symbol, Temporal] ---*/ -const instance = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789, { id: "replace-me" }); +const instance = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789, { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "replace-me", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}); const rangeErrorTests = [ [null, "null"], @@ -17,19 +39,19 @@ const rangeErrorTests = [ ["", "empty string"], [1, "number that doesn't convert to a valid ISO string"], [1n, "bigint"], - [new Temporal.TimeZone("UTC"), "time zone instance"], ]; for (const [arg, description] of rangeErrorTests) { assert.throws(RangeError, () => instance.withCalendar(arg), `${description} does not convert to a valid ISO string`); - assert.throws(RangeError, () => instance.withCalendar({ calendar: arg }), `${description} does not convert to a valid ISO string (in property bag)`); } const typeErrorTests = [ [Symbol(), "symbol"], + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], ]; for (const [arg, description] of typeErrorTests) { assert.throws(TypeError, () => instance.withCalendar(arg), `${description} is not a valid object and does not convert to a string`); - assert.throws(TypeError, () => instance.withCalendar({ calendar: arg }), `${description} is not a valid object and does not convert to a string (in property bag)`); } diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/subclassing-ignored.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/subclassing-ignored.js index 749bdd6694de..2cff05a4dc4a 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/subclassing-ignored.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/subclassing-ignored.js @@ -15,7 +15,24 @@ const customCalendar = { month() { return 2; }, monthCode() { return "M02"; }, day() { return 5; }, + id: "custom-calendar", toString() { return "custom-calendar"; }, + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, }; TemporalHelpers.checkSubclassingIgnored( @@ -25,6 +42,6 @@ TemporalHelpers.checkSubclassingIgnored( [customCalendar], (result) => { TemporalHelpers.assertPlainDateTime(result, 1900, 2, "M02", 5, 12, 34, 56, 987, 654, 321); - assert.sameValue(result.calendar, customCalendar, "calendar result"); + assert.sameValue(result.getCalendar(), customCalendar, "calendar result"); }, ); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-noniso.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-noniso.js index 548a9378a652..c578cfd538f9 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-noniso.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-noniso.js @@ -16,10 +16,26 @@ const cal = { year() { return 2008; }, month() { return 9; }, monthCode() { return "M09"; }, - day() { return 6; } + day() { return 6; }, + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, }; const pdt = new Temporal.PlainDateTime(1995, 12, 7, 3, 24, 30, 0, 0, 0); -assert.sameValue(pdt.calendar.toString(), "iso8601", "PlainDateTime with ISO calendar"); +assert.sameValue(pdt.calendarId, "iso8601", "PlainDateTime with ISO calendar"); const pd = new Temporal.PlainDate(2010, 11, 12, cal); const shifted = pdt.withPlainDate(pd); @@ -31,7 +47,7 @@ TemporalHelpers.assertPlainDateTime( ); assert.sameValue( - shifted.calendar, + shifted.getCalendar(), cal, "calendar is changed if receiver has ISO calendar (2)" ); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-same-id.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-same-id.js index 7abc86730ece..bfe7155e3545 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-same-id.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-same-id.js @@ -9,17 +9,54 @@ includes: [temporalHelpers.js] ---*/ const cal1 = { - toString() { return "this is a string"; }, + id: "this is a string", + toString() { return "this is another string"; }, + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, }; const cal2 = { - id: 'thisisnotiso', + id: "this is a string", era() { return undefined; }, eraYear() { return undefined; }, - toString() { return "this is a string"; }, + toString() { return "thisisnotiso"; }, year() { return 2008; }, month() { return 9; }, monthCode() { return "M09"; }, - day() { return 6; } + day() { return 6; }, + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, }; const pdt = new Temporal.PlainDateTime(1995, 12, 7, 3, 24, 30, 0, 0, 0, cal1); const pd = new Temporal.PlainDate(2010, 11, 12, cal2); @@ -33,7 +70,7 @@ TemporalHelpers.assertPlainDateTime( ); assert.sameValue( - shifted.calendar, + shifted.getCalendar(), cal2, "calendar is changed with same id (2)" ); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-same-object.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-same-object.js index bfe7f3755c15..f57041ffb40e 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-same-object.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-same-object.js @@ -20,7 +20,23 @@ const cal = { year() { return 2008; }, month() { return 9; }, monthCode() { return "M09"; }, - day() { return 6; } + day() { return 6; }, + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, }; const pdt = new Temporal.PlainDateTime(1995, 12, 7, 3, 24, 30, 0, 0, 0, cal); const pd = new Temporal.PlainDate(2010, 11, 12, cal); @@ -34,7 +50,7 @@ TemporalHelpers.assertPlainDateTime( ); assert.sameValue( - shifted.calendar, + shifted.getCalendar(), cal, "calendar is unchanged with same calendars (2)" ); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar.js index 58864db07d40..6544aafdab66 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar.js @@ -16,11 +16,27 @@ const cal = { year() { return 2008; }, month() { return 9; }, monthCode() { return "M09"; }, - day() { return 6; } + day() { return 6; }, + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, }; const pdt = new Temporal.PlainDateTime(1995, 12, 7, 3, 24, 30, 0, 0, 0, cal); const pd = new Temporal.PlainDate(2010, 11, 12); -assert.sameValue(pd.calendar.toString(), "iso8601", "PlainDate with ISO calendar"); +assert.sameValue(pd.calendarId, "iso8601", "PlainDate with ISO calendar"); const shifted = pdt.withPlainDate(pd); TemporalHelpers.assertPlainDateTime( @@ -31,7 +47,7 @@ TemporalHelpers.assertPlainDateTime( ); assert.sameValue( - shifted.calendar, + shifted.getCalendar(), cal, "calendar is unchanged if input has ISO calendar (2)" ); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-propertybag-calendar-case-insensitive.js index de04c1e692f8..9a08d720a262 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-propertybag-calendar-case-insensitive.js @@ -12,10 +12,6 @@ const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 32 const calendar = "IsO8601"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.withPlainDate(arg); -TemporalHelpers.assertPlainDateTime(result1, 1976, 11, "M11", 18, 12, 34, 56, 987, 654, 321, "Calendar is case-insensitive"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.withPlainDate(arg); -TemporalHelpers.assertPlainDateTime(result2, 1976, 11, "M11", 18, 12, 34, 56, 987, 654, 321, "Calendar is case-insensitive (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.withPlainDate(arg); +TemporalHelpers.assertPlainDateTime(result, 1976, 11, "M11", 18, 12, 34, 56, 987, 654, 321, "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 60f5a2097916..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,25 +0,0 @@ -// 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.withplaindate -description: > - A Temporal.Calendar instance passed to withPlainDate() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -instance.withPlainDate(arg); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -instance.withPlainDate(arg); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-propertybag-calendar-leap-second.js index db9a51215e7d..64a98af2e262 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-propertybag-calendar-leap-second.js @@ -12,18 +12,10 @@ const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 32 const calendar = "2016-12-31T23:59:60"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.withPlainDate(arg); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.withPlainDate(arg); TemporalHelpers.assertPlainDateTime( - result1, + result, 1976, 11, "M11", 18, 12, 34, 56, 987, 654, 321, "leap second is a valid ISO string for calendar" ); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.withPlainDate(arg); -TemporalHelpers.assertPlainDateTime( - result2, - 1976, 11, "M11", 18, 12, 34, 56, 987, 654, 321, - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-propertybag-calendar-number.js index c9ae96691543..af4f9cc7f172 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-propertybag-calendar-number.js @@ -12,13 +12,9 @@ const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 32 const calendar = 19970327; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.withPlainDate(arg); -TemporalHelpers.assertPlainDateTime(result1, 1976, 11, "M11", 18, 12, 34, 56, 987, 654, 321, "19970327 is a valid ISO string for calendar"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.withPlainDate(arg); -TemporalHelpers.assertPlainDateTime(result2, 1976, 11, "M11", 18, 12, 34, 56, 987, 654, 321, "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.withPlainDate(arg); +TemporalHelpers.assertPlainDateTime(result, 1976, 11, "M11", 18, 12, 34, 56, 987, 654, 321, "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -27,16 +23,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; assert.throws( RangeError, () => instance.withPlainDate(arg), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.withPlainDate(arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-propertybag-calendar-wrong-type.js index 7fbae64fc59a..9d5c5491ec75 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-propertybag-calendar-wrong-type.js @@ -21,27 +21,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.withPlainDate(arg), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.withPlainDate(arg), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.withPlainDate(arg), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.withPlainDate(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.withPlainDate(arg), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-string-calendar-annotation.js index aa414240bf03..6aed52f85dd5 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-string-calendar-annotation.js @@ -16,7 +16,6 @@ const tests = [ ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const instance = new Temporal.PlainDateTime(1976, 11, 18, 15, 23); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-string-iso-calendar.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-string-iso-calendar.js index 45e3d8bf07cc..5cec5467a758 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-string-iso-calendar.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-string-iso-calendar.js @@ -16,7 +16,23 @@ const cal = { year() { return 2008; }, month() { return 9; }, monthCode() { return "M09"; }, - day() { return 6; } + day() { return 6; }, + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, }; const dt = new Temporal.PlainDateTime(1995, 12, 7, 3, 24, 30, 0, 0, 0, cal); const shifted = dt.withPlainDate("2010-11-12"); @@ -29,7 +45,7 @@ TemporalHelpers.assertPlainDateTime( ); assert.sameValue( - shifted.calendar, + shifted.getCalendar(), cal, "calendar is unchanged if input has ISO calendar (2)" ); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..7d236f9fe5f3 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.withplaindate +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.withPlainDate(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..a3aed1214d04 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.withplaindate +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const idOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "id"); +Object.defineProperty(Temporal.Calendar.prototype, "id", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("id should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, "iso8601"); +instance.withPlainDate(new Temporal.PlainDate(2001, 6, 13)); + +Object.defineProperty(Temporal.Calendar.prototype, "id", idOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/calendar-temporal-object.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/calendar-temporal-object.js index b2c9b06eb1f3..779b2d18123a 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/calendar-temporal-object.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/calendar-temporal-object.js @@ -24,5 +24,5 @@ TemporalHelpers.checkToTemporalCalendarFastPath((temporalObject, calendar) => { const datetime = new Temporal.PlainDateTime(2000, 5, 3, 13, 3, 27, 123, 456, 789); // the PlainDate's calendar will override the PlainDateTime's ISO calendar const result = datetime.withPlainDate({ year: 2001, month: 6, day: 4, calendar: temporalObject }); - assert.sameValue(result.calendar, calendar, "Temporal object coerced to calendar"); + assert.sameValue(result.getCalendar(), calendar, "Temporal object coerced to calendar"); }); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/non-compatible-calendars-throw.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/non-compatible-calendars-throw.js index 9e3920d2bb06..4a691cf608c1 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/non-compatible-calendars-throw.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/non-compatible-calendars-throw.js @@ -7,9 +7,33 @@ description: If two non-ISO calendars are involved, an error is raised features: [Temporal] ---*/ +const calendarMethods = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; + const cal = { id: "foo", toString() { return "this is a string"; }, + ...calendarMethods, }; const dt = new Temporal.PlainDateTime(1995, 12, 7, 3, 24, 30, 0, 0, 0, cal); @@ -17,6 +41,7 @@ const dt = new Temporal.PlainDateTime(1995, 12, 7, 3, 24, 30, 0, 0, 0, cal); const anotherCal = { id: "bar", toString() { return "this is another string"; }, + ...calendarMethods, }; const date = new Temporal.PlainDate(2008, 9, 6, anotherCal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainTime/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainTime/argument-string-calendar-annotation.js index 08450416e585..9994b2d60ac5 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainTime/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainTime/argument-string-calendar-annotation.js @@ -21,8 +21,10 @@ const tests = [ ["1970-01-01T12:34:56.987654321[UTC][u-ca=iso8601]", "with date and time zone"], ["1970-01-01T12:34:56.987654321[!u-ca=iso8601]", "with !, date, and no time zone"], ["1970-01-01T12:34:56.987654321[UTC][!u-ca=iso8601]", "with !, date, and time zone"], + ["12:34:56.987654321[u-ca=hebrew]", "calendar annotation ignored"], + ["12:34:56.987654321[u-ca=unknown]", "calendar annotation ignored even if unknown calendar"], + ["12:34:56.987654321[!u-ca=unknown]", "calendar annotation ignored even if unknown calendar with !"], ["1970-01-01T12:34:56.987654321[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["1970-01-01T12:34:56.987654321[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const instance = new Temporal.PlainDateTime(1976, 11, 18, 15, 23); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainTime/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainTime/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..9a7fed3df435 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainTime/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.withplaintime +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "00:00[u-ca=iso8601][!u-ca=iso8601]", + "00:00[!u-ca=iso8601][u-ca=iso8601]", + "00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.withPlainTime(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainTime/calendar-temporal-object.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainTime/calendar-temporal-object.js deleted file mode 100644 index ddf67ab2fe0d..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/withPlainTime/calendar-temporal-object.js +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.zoneddatetime.prototype.withplaintime -description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots -info: | - sec-temporal.zoneddatetime.prototype.withplaintime step 4.a: - a. Let _plainTime_ be ? ToTemporalTime(_plainTimeLike_). - sec-temporal-totemporaltime step 3.d: - d. If _calendar_ is not *undefined*, then - i. Set _calendar_ to ? ToTemporalCalendar(_calendar_). - ii. If ? ToString(_calendar_) is not *"iso8601"*, then - 1. Throw a *RangeError* exception. - sec-temporal-totemporalcalendar step 1.a: - a. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then - i. Return _temporalCalendarLike_.[[Calendar]]. -includes: [compareArray.js, temporalHelpers.js] -features: [Temporal] ----*/ - -TemporalHelpers.checkToTemporalCalendarFastPath((temporalObject) => { - const datetime = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); - assert.throws(RangeError, () => datetime.withPlainTime({ hour: 12, minute: 30, calendar: temporalObject })); -}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/year/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/year/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..0ed38f01ff02 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/year/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.year +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const yearOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "year"); +Object.defineProperty(Temporal.Calendar.prototype, "year", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("year should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, "iso8601"); +instance.year; + +Object.defineProperty(Temporal.Calendar.prototype, "year", yearOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/yearOfWeek/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/yearOfWeek/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..b0ce17cc24e7 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainDateTime/prototype/yearOfWeek/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.yearofweek +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const yearOfWeekOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "yearOfWeek"); +Object.defineProperty(Temporal.Calendar.prototype, "yearOfWeek", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("yearOfWeek should not be looked up"); + }, +}); + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, "iso8601"); +instance.yearOfWeek; + +Object.defineProperty(Temporal.Calendar.prototype, "yearOfWeek", yearOfWeekOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/basic.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/basic.js index f854cfb450d0..6eb362da1ce7 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/basic.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/basic.js @@ -10,12 +10,12 @@ features: [Temporal] const leapDay = new Temporal.PlainMonthDay(2, 29); TemporalHelpers.assertPlainMonthDay(leapDay, "M02", 29, "leap day is supported"); -assert.sameValue(leapDay.calendar.id, "iso8601", "leap day calendar"); +assert.sameValue(leapDay.calendarId, "iso8601", "leap day calendar"); const beforeEpoch = new Temporal.PlainMonthDay(12, 2, "iso8601", 1920); TemporalHelpers.assertPlainMonthDay(beforeEpoch, "M12", 2, "reference year before epoch", 1920); -assert.sameValue(beforeEpoch.calendar.id, "iso8601", "reference year before epoch calendar"); +assert.sameValue(beforeEpoch.calendarId, "iso8601", "reference year before epoch calendar"); const afterEpoch = new Temporal.PlainMonthDay(1, 7, "iso8601", 1980); TemporalHelpers.assertPlainMonthDay(afterEpoch, "M01", 7, "reference year after epoch", 1980); -assert.sameValue(afterEpoch.calendar.id, "iso8601", "reference year after epoch calendar"); +assert.sameValue(afterEpoch.calendarId, "iso8601", "reference year after epoch calendar"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/calendar-case-insensitive.js index 7edc60b92271..e42d4d19c40e 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/calendar-case-insensitive.js @@ -10,4 +10,4 @@ features: [Temporal] const arg = "iSo8601"; const result = new Temporal.PlainMonthDay(12, 15, arg, 1972); -assert.sameValue(result.calendar.id, "iso8601", "Calendar is case-insensitive"); +assert.sameValue(result.calendarId, "iso8601", "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 6f5bba578bd5..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,20 +0,0 @@ -// 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 -description: > - A Temporal.Calendar instance passed to new PlainMonthDay() does not have - its 'calendar' property observably checked -features: [Temporal] ----*/ - -const arg = new Temporal.Calendar("iso8601"); -Object.defineProperty(arg, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -new Temporal.PlainMonthDay(12, 15, arg, 1972); -new Temporal.PlainMonthDay(12, 15, { calendar: arg }, 1972); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/calendar-number.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/calendar-number.js index bc2edac62fab..99f99d9c2b44 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/calendar-number.js @@ -10,7 +10,7 @@ features: [Temporal] const arg = 19761118; const result = new Temporal.PlainMonthDay(12, 15, arg, 1972); -assert.sameValue(result.calendar.id, "iso8601", "19761118 is a valid ISO string for Calendar"); +assert.sameValue(result.calendarId, "iso8601", "19761118 is a valid ISO string for Calendar"); const numbers = [ 1, diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/calendar-string.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/calendar-string.js index cc41c4d0eb9b..222645121f77 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/calendar-string.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/calendar-string.js @@ -10,4 +10,4 @@ features: [Temporal] const arg = "iso8601"; const result = new Temporal.PlainMonthDay(12, 15, arg, 1972); -assert.sameValue(result.calendar.id, "iso8601", `Calendar created from string "${arg}"`); +assert.sameValue(result.getISOFields().calendar, "iso8601", `Calendar created from string "${arg}"`); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/calendar-temporal-object.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/calendar-temporal-object.js index d7aab9f32f70..fa1fa9ba33d0 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/calendar-temporal-object.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/calendar-temporal-object.js @@ -6,7 +6,7 @@ esid: sec-temporal.plainmonthday description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots info: | sec-temporal-totemporalcalendar step 1.b: - b. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then + b. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then i. Return _temporalCalendarLike_.[[Calendar]]. includes: [compareArray.js] features: [Temporal] @@ -14,12 +14,11 @@ features: [Temporal] const plainDate = new Temporal.PlainDate(2000, 5, 2); const plainDateTime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); -const plainTime = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); const plainMonthDay = new Temporal.PlainMonthDay(5, 2); const plainYearMonth = new Temporal.PlainYearMonth(2000, 5); const zonedDateTime = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); -[plainDate, plainDateTime, plainTime, plainMonthDay, plainYearMonth, zonedDateTime].forEach((arg) => { +[plainDate, plainDateTime, plainMonthDay, plainYearMonth, zonedDateTime].forEach((arg) => { const actual = []; const expected = []; @@ -33,7 +32,7 @@ const zonedDateTime = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UT }); const result = new Temporal.PlainMonthDay(12, 15, arg, 1972); - assert.sameValue(result.calendar, calendar, "Temporal object coerced to calendar"); + assert.sameValue(result.getISOFields().calendar, calendar, "Temporal object coerced to calendar"); assert.compareArray(actual, expected, "calendar getter not called"); }); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/calendar-undefined.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/calendar-undefined.js index 2b7d1d6db24f..442da5e73502 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/calendar-undefined.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/calendar-undefined.js @@ -16,7 +16,7 @@ Object.defineProperty(Temporal.Calendar, "from", { }); const dateExplicit = new Temporal.PlainMonthDay(...args, undefined); -assert.sameValue(dateExplicit.calendar.toString(), "iso8601"); +assert.sameValue(dateExplicit.calendarId, "iso8601"); const dateImplicit = new Temporal.PlainMonthDay(...args); -assert.sameValue(dateImplicit.calendar.toString(), "iso8601"); +assert.sameValue(dateImplicit.calendarId, "iso8601"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/calendar-wrong-type.js index d2f303853947..f05d07c4e943 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/calendar-wrong-type.js @@ -23,6 +23,9 @@ for (const [arg, description] of rangeErrorTests) { const typeErrorTests = [ [Symbol(), "symbol"], + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], ]; for (const [arg, description] of typeErrorTests) { diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/argument-plainmonthday.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/argument-plainmonthday.js index 214c541e45cf..760ae71fd1db 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/argument-plainmonthday.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/argument-plainmonthday.js @@ -18,7 +18,7 @@ TemporalHelpers.assertPlainMonthDay( /* isoYear = */ 2000 ); -assert.sameValue(result.calendar, orig.calendar, "Calendar is copied"); +assert.sameValue(result.getISOFields().calendar, orig.getISOFields().calendar, "Calendar is copied"); assert.notSameValue( result, diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-case-insensitive.js index 1f18ec3246e8..bdd4634474dd 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-case-insensitive.js @@ -10,10 +10,6 @@ features: [Temporal] const calendar = "IsO8601"; -let arg = { monthCode: "M11", day: 18, calendar }; -const result1 = Temporal.PlainMonthDay.from(arg); -TemporalHelpers.assertPlainMonthDay(result1, "M11", 18, "Calendar is case-insensitive"); - -arg = { monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = Temporal.PlainMonthDay.from(arg); -TemporalHelpers.assertPlainMonthDay(result2, "M11", 18, "Calendar is case-insensitive (nested property)"); +const arg = { monthCode: "M11", day: 18, calendar }; +const result = Temporal.PlainMonthDay.from(arg); +TemporalHelpers.assertPlainMonthDay(result, "M11", 18, "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index a2f287eb9c83..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,23 +0,0 @@ -// 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.from -description: > - A Temporal.Calendar instance passed to from() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -let arg = { monthCode: "M11", day: 18, calendar }; -Temporal.PlainMonthDay.from(arg); - -arg = { monthCode: "M11", day: 18, calendar: { calendar } }; -Temporal.PlainMonthDay.from(arg); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-leap-second.js index 1a2d2cd042ce..d26496124039 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-leap-second.js @@ -10,18 +10,10 @@ features: [Temporal] const calendar = "2016-12-31T23:59:60"; -let arg = { monthCode: "M11", day: 18, calendar }; -const result1 = Temporal.PlainMonthDay.from(arg); +const arg = { monthCode: "M11", day: 18, calendar }; +const result = Temporal.PlainMonthDay.from(arg); TemporalHelpers.assertPlainMonthDay( - result1, + result, "M11", 18, "leap second is a valid ISO string for calendar" ); - -arg = { monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = Temporal.PlainMonthDay.from(arg); -TemporalHelpers.assertPlainMonthDay( - result2, - "M11", 18, - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-number.js index 56eec0c4271c..0b6664972326 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-number.js @@ -10,13 +10,9 @@ features: [Temporal] const calendar = 19970327; -let arg = { monthCode: "M11", day: 18, calendar }; -const result1 = Temporal.PlainMonthDay.from(arg); -TemporalHelpers.assertPlainMonthDay(result1, "M11", 18, "19970327 is a valid ISO string for calendar"); - -arg = { monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = Temporal.PlainMonthDay.from(arg); -TemporalHelpers.assertPlainMonthDay(result2, "M11", 18, "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { monthCode: "M11", day: 18, calendar }; +const result = Temporal.PlainMonthDay.from(arg); +TemporalHelpers.assertPlainMonthDay(result, "M11", 18, "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -25,16 +21,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { monthCode: "M11", day: 18, calendar }; + const arg = { monthCode: "M11", day: 18, calendar }; assert.throws( RangeError, () => Temporal.PlainMonthDay.from(arg), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { monthCode: "M11", day: 18, calendar: { calendar } }; - assert.throws( - RangeError, - () => Temporal.PlainMonthDay.from(arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-string.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-string.js index 083758e03403..f1357d0c67ac 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-string.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-string.js @@ -13,3 +13,4 @@ const calendar = "iso8601"; const arg = { monthCode: "M11", day: 18, calendar }; const result = Temporal.PlainMonthDay.from(arg); TemporalHelpers.assertPlainMonthDay(result, "M11", 18, `Calendar created from string "${calendar}"`); +assert.sameValue(result.getISOFields().calendar, "iso8601", "calendar slot stores a string"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-wrong-type.js index fceeb50eabbe..8464fa0729a2 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-wrong-type.js @@ -18,27 +18,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => Temporal.PlainMonthDay.from(arg), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => Temporal.PlainMonthDay.from(arg), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => Temporal.PlainMonthDay.from(arg), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => Temporal.PlainMonthDay.from(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => Temporal.PlainMonthDay.from(arg), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/argument-string-calendar-annotation.js index 54dcdfe9e202..9fbe773924e4 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/argument-string-calendar-annotation.js @@ -14,7 +14,6 @@ const tests = [ ["1976-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["1976-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["1976-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["1976-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; tests.forEach(([arg, description]) => { diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..31b45f094668 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday.from +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; + +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => Temporal.PlainMonthDay.from(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/calendar-monthdayfromfields-called-with-options-undefined.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/calendar-monthdayfromfields-called-with-options-undefined.js deleted file mode 100644 index aa302eb1aba1..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/calendar-monthdayfromfields-called-with-options-undefined.js +++ /dev/null @@ -1,23 +0,0 @@ -// 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.from -description: > - Calendar.monthDayFromFields method is called with undefined as the options - value when call originates internally -features: [Temporal] ----*/ - -const realMonthDayFromFields = Temporal.Calendar.prototype.monthDayFromFields; -let monthDayFromFieldsCallCount = 0; -Temporal.Calendar.prototype.monthDayFromFields = function (fields, options) { - monthDayFromFieldsCallCount++; - assert.sameValue(options, undefined, "monthDayFromFields shouldn't be called with options"); - return realMonthDayFromFields.call(this, fields, options); -} - -Temporal.PlainMonthDay.from("2000-05-02"); -assert.sameValue(monthDayFromFieldsCallCount, 1); - -Temporal.Calendar.prototype.monthDayFromFields = realMonthDayFromFields; diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/calendar-temporal-object.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/calendar-temporal-object.js index 98a61cf22157..5746c980150d 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/calendar-temporal-object.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/calendar-temporal-object.js @@ -22,5 +22,5 @@ features: [Temporal] TemporalHelpers.checkToTemporalCalendarFastPath((temporalObject, calendar) => { const result = Temporal.PlainMonthDay.from({ monthCode: "M05", day: 2, calendar: temporalObject }); - assert.sameValue(result.calendar, calendar, "Temporal object coerced to calendar"); + assert.sameValue(result.getCalendar(), calendar, "Temporal object coerced to calendar"); }); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/fields-object.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/fields-object.js index b8a903849233..ed5b26325d62 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/fields-object.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/fields-object.js @@ -22,5 +22,5 @@ for (const [argument, description = argument] of tests) { const plainMonthDay = Temporal.PlainMonthDay.from(argument); assert.notSameValue(plainMonthDay, argument, `from ${description} converts`); TemporalHelpers.assertPlainMonthDay(plainMonthDay, "M10", 1, `from ${description}`); - assert.sameValue(plainMonthDay.calendar.id, "iso8601", `from ${description} calendar`); + assert.sameValue(plainMonthDay.calendarId, "iso8601", `from ${description} calendar`); } diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/fields-string.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/fields-string.js index 007d629ed442..9248f77e3ffc 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/fields-string.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/fields-string.js @@ -12,7 +12,7 @@ for (const argument of TemporalHelpers.ISO.plainMonthDayStringsValid()) { const plainMonthDay = Temporal.PlainMonthDay.from(argument); assert.notSameValue(plainMonthDay, argument, `from ${argument} converts`); TemporalHelpers.assertPlainMonthDay(plainMonthDay, "M10", 1, `from ${argument}`); - assert.sameValue(plainMonthDay.calendar.id, "iso8601", `from ${argument} calendar`); + assert.sameValue(plainMonthDay.calendarId, "iso8601", `from ${argument} calendar`); } for (const arg of TemporalHelpers.ISO.plainMonthDayStringsInvalid()) { diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/order-of-operations.js index a6f3c7fcfece..043b3461cebb 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/from/order-of-operations.js @@ -10,8 +10,27 @@ features: [Temporal] const expected = [ "get fields.calendar", - // ToTemporalCalendarWithISODefault - "has fields.calendar.calendar", + "has fields.calendar.dateAdd", + "has fields.calendar.dateFromFields", + "has fields.calendar.dateUntil", + "has fields.calendar.day", + "has fields.calendar.dayOfWeek", + "has fields.calendar.dayOfYear", + "has fields.calendar.daysInMonth", + "has fields.calendar.daysInWeek", + "has fields.calendar.daysInYear", + "has fields.calendar.fields", + "has fields.calendar.id", + "has fields.calendar.inLeapYear", + "has fields.calendar.mergeFields", + "has fields.calendar.month", + "has fields.calendar.monthCode", + "has fields.calendar.monthDayFromFields", + "has fields.calendar.monthsInYear", + "has fields.calendar.weekOfYear", + "has fields.calendar.year", + "has fields.calendar.yearMonthFromFields", + "has fields.calendar.yearOfWeek", // CalendarFields "get fields.calendar.fields", "call fields.calendar.fields", diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/calendar/branding.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/calendar/branding.js deleted file mode 100644 index adf20ff9aea5..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/calendar/branding.js +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-get-temporal.plainmonthday.prototype.calendar -description: Throw a TypeError if the receiver is invalid -features: [Symbol, Temporal] ----*/ - -const calendar = Object.getOwnPropertyDescriptor(Temporal.PlainMonthDay.prototype, "calendar").get; - -assert.sameValue(typeof calendar, "function"); - -assert.throws(TypeError, () => calendar.call(undefined), "undefined"); -assert.throws(TypeError, () => calendar.call(null), "null"); -assert.throws(TypeError, () => calendar.call(true), "true"); -assert.throws(TypeError, () => calendar.call(""), "empty string"); -assert.throws(TypeError, () => calendar.call(Symbol()), "symbol"); -assert.throws(TypeError, () => calendar.call(1), "1"); -assert.throws(TypeError, () => calendar.call({}), "plain object"); -assert.throws(TypeError, () => calendar.call(Temporal.PlainMonthDay), "Temporal.PlainMonthDay"); -assert.throws(TypeError, () => calendar.call(Temporal.PlainMonthDay.prototype), "Temporal.PlainMonthDay.prototype"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/calendar/prop-desc.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/calendar/prop-desc.js deleted file mode 100644 index a428d164eaab..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/calendar/prop-desc.js +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-get-temporal.plainmonthday.prototype.calendar -description: The "calendar" property of Temporal.PlainMonthDay.prototype -features: [Temporal] ----*/ - -const descriptor = Object.getOwnPropertyDescriptor(Temporal.PlainMonthDay.prototype, "calendar"); -assert.sameValue(typeof descriptor.get, "function"); -assert.sameValue(descriptor.set, undefined); -assert.sameValue(descriptor.enumerable, false); -assert.sameValue(descriptor.configurable, true); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/calendarId/branding.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/calendarId/branding.js new file mode 100644 index 000000000000..85997673d962 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/calendarId/branding.js @@ -0,0 +1,22 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-get-temporal.plainmonthday.prototype.calendarid +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const calendarId = Object.getOwnPropertyDescriptor(Temporal.PlainMonthDay.prototype, "calendarId").get; + +assert.sameValue(typeof calendarId, "function"); + +assert.throws(TypeError, () => calendarId.call(undefined), "undefined"); +assert.throws(TypeError, () => calendarId.call(null), "null"); +assert.throws(TypeError, () => calendarId.call(true), "true"); +assert.throws(TypeError, () => calendarId.call(""), "empty string"); +assert.throws(TypeError, () => calendarId.call(Symbol()), "symbol"); +assert.throws(TypeError, () => calendarId.call(1), "1"); +assert.throws(TypeError, () => calendarId.call({}), "plain object"); +assert.throws(TypeError, () => calendarId.call(Temporal.PlainMonthDay), "Temporal.PlainMonthDay"); +assert.throws(TypeError, () => calendarId.call(Temporal.PlainMonthDay.prototype), "Temporal.PlainMonthDay.prototype"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/calendarId/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/calendarId/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..ebbc2bce1ad6 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/calendarId/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday.prototype.calendarid +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const idOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "id"); +Object.defineProperty(Temporal.Calendar.prototype, "id", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("id should not be looked up"); + }, +}); + +const instance = new Temporal.PlainMonthDay(5, 2, "iso8601", 1972); +instance.calendarId; + +Object.defineProperty(Temporal.Calendar.prototype, "id", idOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/calendarId/prop-desc.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/calendarId/prop-desc.js new file mode 100644 index 000000000000..9ca2b1a5ae41 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/calendarId/prop-desc.js @@ -0,0 +1,14 @@ +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-get-temporal.plainmonthday.prototype.calendarid +description: The "calendarId" property of Temporal.PlainMonthDay.prototype +features: [Temporal] +---*/ + +const descriptor = Object.getOwnPropertyDescriptor(Temporal.PlainMonthDay.prototype, "calendarId"); +assert.sameValue(typeof descriptor.get, "function"); +assert.sameValue(descriptor.set, undefined); +assert.sameValue(descriptor.enumerable, false); +assert.sameValue(descriptor.configurable, true); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/day/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/day/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..60556142b010 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/day/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday.prototype.day +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const dayOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "day"); +Object.defineProperty(Temporal.Calendar.prototype, "day", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("day should not be looked up"); + }, +}); + +const instance = new Temporal.PlainMonthDay(5, 2, "iso8601", 1972); +instance.day; + +Object.defineProperty(Temporal.Calendar.prototype, "day", dayOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-case-insensitive.js index 386f3da59a9b..bafa6df7645b 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-case-insensitive.js @@ -11,10 +11,6 @@ const instance = new Temporal.PlainMonthDay(11, 18); const calendar = "IsO8601"; -let arg = { monthCode: "M11", day: 18, calendar }; -const result1 = instance.equals(arg); -assert.sameValue(result1, true, "Calendar is case-insensitive"); - -arg = { monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.equals(arg); -assert.sameValue(result2, true, "Calendar is case-insensitive (nested property)"); +const arg = { monthCode: "M11", day: 18, calendar }; +const result = instance.equals(arg); +assert.sameValue(result, true, "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 83074bfcdc11..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,25 +0,0 @@ -// 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.equals -description: > - A Temporal.Calendar instance passed to equals() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.PlainMonthDay(11, 18); - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -let arg = { monthCode: "M11", day: 18, calendar }; -instance.equals(arg); - -arg = { monthCode: "M11", day: 18, calendar: { calendar } }; -instance.equals(arg); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-leap-second.js index 202f5f4318d3..a932e32fe86b 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-leap-second.js @@ -11,18 +11,10 @@ const instance = new Temporal.PlainMonthDay(11, 18); const calendar = "2016-12-31T23:59:60"; -let arg = { monthCode: "M11", day: 18, calendar }; -const result1 = instance.equals(arg); +const arg = { monthCode: "M11", day: 18, calendar }; +const result = instance.equals(arg); assert.sameValue( - result1, + result, true, "leap second is a valid ISO string for calendar" ); - -arg = { monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.equals(arg); -assert.sameValue( - result2, - true, - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-number.js index be40e79001a1..b558e4612ef9 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-number.js @@ -11,13 +11,9 @@ const instance = new Temporal.PlainMonthDay(11, 18); const calendar = 19970327; -let arg = { monthCode: "M11", day: 18, calendar }; -const result1 = instance.equals(arg); -assert.sameValue(result1, true, "19970327 is a valid ISO string for calendar"); - -arg = { monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.equals(arg); -assert.sameValue(result2, true, "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { monthCode: "M11", day: 18, calendar }; +const result = instance.equals(arg); +assert.sameValue(result, true, "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -26,16 +22,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { monthCode: "M11", day: 18, calendar }; + const arg = { monthCode: "M11", day: 18, calendar }; assert.throws( RangeError, () => instance.equals(arg), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { monthCode: "M11", day: 18, calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.equals(arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-wrong-type.js index b3b856b20b01..57b2933e85bf 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-wrong-type.js @@ -21,27 +21,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.equals(arg), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.equals(arg), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.equals(arg), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.equals(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.equals(arg), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-string-calendar-annotation.js index 1da1eb37d797..114589853697 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-string-calendar-annotation.js @@ -13,7 +13,6 @@ const tests = [ ["1976-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["1976-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["1976-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["1976-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const instance = new Temporal.PlainMonthDay(5, 2); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..af0173597d7b --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday.prototype.equals +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.PlainMonthDay(5, 2); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.equals(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/equals/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/equals/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..d39d410525f5 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/equals/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday.prototype.equals +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const idOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "id"); +Object.defineProperty(Temporal.Calendar.prototype, "id", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("id should not be looked up"); + }, +}); + +const instance = new Temporal.PlainMonthDay(5, 2, "iso8601", 1972); +instance.equals(new Temporal.PlainMonthDay(5, 2)); + +Object.defineProperty(Temporal.Calendar.prototype, "id", idOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/equals/calendar-monthdayfromfields-called-with-options-undefined.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/equals/calendar-monthdayfromfields-called-with-options-undefined.js index 649812219f9d..bb347480e549 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/equals/calendar-monthdayfromfields-called-with-options-undefined.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/equals/calendar-monthdayfromfields-called-with-options-undefined.js @@ -14,20 +14,3 @@ const calendar = TemporalHelpers.calendarFromFieldsUndefinedOptions(); const instance = new Temporal.PlainMonthDay(5, 2, calendar); instance.equals({ monthCode: "M05", day: 3, calendar }); assert.sameValue(calendar.monthDayFromFieldsCallCount, 1); - -// Test again, but overriding the global Temporal.Calendar.prototype method so -// we can observe the call to monthDayFromFields() on the ISO8601 calendar -// that occurs when we parse the string - -const realMonthDayFromFields = Temporal.Calendar.prototype.monthDayFromFields; -let monthDayFromFieldsCallCount = 0; -Temporal.Calendar.prototype.monthDayFromFields = function (fields, options) { - monthDayFromFieldsCallCount++; - assert.sameValue(options, undefined, "monthDayFromFields shouldn't be called with options"); - return realMonthDayFromFields.call(this, fields, options); -} - -instance.equals("2000-05-03"); -assert.sameValue(monthDayFromFieldsCallCount, 1); - -Temporal.Calendar.prototype.monthDayFromFields = realMonthDayFromFields; diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/equals/calendars.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/equals/calendars.js index 63b75cf1b17b..33ea11470697 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/equals/calendars.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/equals/calendars.js @@ -9,19 +9,41 @@ features: [Temporal] ---*/ const expected = [ - "get calendar a.toString", - "call calendar a.toString", - "get calendar b.toString", - "call calendar b.toString", + "get calendar a.id", + "get calendar b.id", ]; const actual = []; const calendar = (id) => { - return TemporalHelpers.toPrimitiveObserver(actual, id, `calendar ${id}`); + const c = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, + }; + TemporalHelpers.observeProperty(actual, c, "id", id, `calendar ${id}`); + return c; }; const mdA = new Temporal.PlainMonthDay(2, 7, calendar("a")); const mdB = new Temporal.PlainMonthDay(2, 7, calendar("b")); const mdC = new Temporal.PlainMonthDay(2, 7, calendar("c"), 1974); +actual.splice(0); // disregard the HasProperty checks done in the constructor assert.sameValue(mdA.equals(mdC), false, "different year"); assert.compareArray(actual, [], "Should not check calendar"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/getCalendar/branding.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/getCalendar/branding.js new file mode 100644 index 000000000000..91492e579c7b --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/getCalendar/branding.js @@ -0,0 +1,22 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday.prototype.getcalendar +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const getCalendar = Temporal.PlainMonthDay.prototype.getCalendar; + +assert.sameValue(typeof getCalendar, "function"); + +assert.throws(TypeError, () => getCalendar.call(undefined), "undefined"); +assert.throws(TypeError, () => getCalendar.call(null), "null"); +assert.throws(TypeError, () => getCalendar.call(true), "true"); +assert.throws(TypeError, () => getCalendar.call(""), "empty string"); +assert.throws(TypeError, () => getCalendar.call(Symbol()), "symbol"); +assert.throws(TypeError, () => getCalendar.call(1), "1"); +assert.throws(TypeError, () => getCalendar.call({}), "plain object"); +assert.throws(TypeError, () => getCalendar.call(Temporal.PlainMonthDay), "Temporal.PlainMonthDay"); +assert.throws(TypeError, () => getCalendar.call(Temporal.PlainMonthDay.prototype), "Temporal.PlainMonthDay.prototype"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/getCalendar/builtin.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/getCalendar/builtin.js new file mode 100644 index 000000000000..8a80d453524c --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/getCalendar/builtin.js @@ -0,0 +1,33 @@ +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday.prototype.getcalendar +description: > + Tests that Temporal.PlainMonthDay.prototype.getCalendar + meets the requirements for built-in objects defined by the + introduction of chapter 17 of the ECMAScript Language Specification. +info: | + Built-in functions that are not constructors do not have a "prototype" property unless + otherwise specified in the description of a particular function. + + Unless specified otherwise, a built-in object that is callable as a function is a built-in + function object with the characteristics described in 10.3. Unless specified otherwise, the + [[Extensible]] internal slot of a built-in object initially has the value true. + + Unless otherwise specified every built-in function and every built-in constructor has the + Function prototype object [...] as the value of its [[Prototype]] internal slot. +features: [Temporal] +---*/ + +assert.sameValue(Object.isExtensible(Temporal.PlainMonthDay.prototype.getCalendar), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.PlainMonthDay.prototype.getCalendar), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.PlainMonthDay.prototype.getCalendar), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.PlainMonthDay.prototype.getCalendar.hasOwnProperty("prototype"), + false, "prototype property"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/getCalendar/length.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/getCalendar/length.js new file mode 100644 index 000000000000..a79f3e8b60c7 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/getCalendar/length.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday.prototype.getcalendar +description: Temporal.PlainMonthDay.prototype.getCalendar.length is 0 +info: | + Every built-in function object, including constructors, has a "length" property whose value is + an integer. Unless otherwise specified, this value is equal to the largest number of named + arguments shown in the subclause headings for the function description. Optional parameters + (which are indicated with brackets: [ ]) or rest parameters (which are shown using the form + «...name») are not included in the default argument count. + + Unless otherwise specified, the "length" property of a built-in function object has the + attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +verifyProperty(Temporal.PlainMonthDay.prototype.getCalendar, "length", { + value: 0, + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/getCalendar/name.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/getCalendar/name.js new file mode 100644 index 000000000000..f02a73ddaf32 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/getCalendar/name.js @@ -0,0 +1,23 @@ +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday.prototype.getcalendar +description: Temporal.PlainMonthDay.prototype.getCalendar.name is "getCalendar". +info: | + Every built-in function object, including constructors, that is not identified as an anonymous + function has a "name" property whose value is a String. Unless otherwise specified, this value + is the name that is given to the function in this specification. + + Unless otherwise specified, the "name" property of a built-in function object, if it exists, + has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +verifyProperty(Temporal.PlainMonthDay.prototype.getCalendar, "name", { + value: "getCalendar", + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/getCalendar/not-a-constructor.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/getCalendar/not-a-constructor.js new file mode 100644 index 000000000000..54c34ebb5935 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/getCalendar/not-a-constructor.js @@ -0,0 +1,21 @@ +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday.prototype.getcalendar +description: > + Temporal.PlainMonthDay.prototype.getCalendar does not implement [[Construct]], is not new-able +info: | + Built-in function objects that are not identified as constructors do not implement the + [[Construct]] internal method unless otherwise specified in the description of a particular + function. +includes: [isConstructor.js] +features: [Reflect.construct, Temporal] +---*/ + +assert.throws(TypeError, () => { + new Temporal.PlainMonthDay.prototype.getCalendar(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.PlainMonthDay.prototype.getCalendar), false, + "isConstructor(Temporal.PlainMonthDay.prototype.getCalendar)"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/getCalendar/prop-desc.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/getCalendar/prop-desc.js new file mode 100644 index 000000000000..70da030514bc --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/getCalendar/prop-desc.js @@ -0,0 +1,21 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday.prototype.getcalendar +description: The "getCalendar" property of Temporal.PlainMonthDay.prototype +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.PlainMonthDay.prototype.getCalendar, + "function", + "`typeof PlainMonthDay.prototype.getCalendar` is `function`" +); + +verifyProperty(Temporal.PlainMonthDay.prototype, "getCalendar", { + writable: true, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/getISOFields/field-names.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/getISOFields/field-names.js index 87cedb2153aa..9b99f014e641 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/getISOFields/field-names.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/getISOFields/field-names.js @@ -13,4 +13,4 @@ const result = md.getISOFields(); assert.sameValue(result.isoYear, 1972, "isoYear result"); assert.sameValue(result.isoMonth, 5, "isoMonth result"); assert.sameValue(result.isoDay, 2, "isoDay result"); -assert.sameValue(result.calendar.id, "iso8601", "calendar result"); +assert.sameValue(result.calendar, "iso8601", "calendar result"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/monthCode/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/monthCode/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..2c94c80eaa6b --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/monthCode/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday.prototype.monthcode +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const monthCodeOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "monthCode"); +Object.defineProperty(Temporal.Calendar.prototype, "monthCode", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("monthCode should not be looked up"); + }, +}); + +const instance = new Temporal.PlainMonthDay(5, 2, "iso8601", 1972); +instance.monthCode; + +Object.defineProperty(Temporal.Calendar.prototype, "monthCode", monthCodeOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toJSON/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toJSON/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..7355f1c38859 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toJSON/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday.prototype.tojson +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const idOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "id"); +Object.defineProperty(Temporal.Calendar.prototype, "id", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("id should not be looked up"); + }, +}); + +const instance = new Temporal.PlainMonthDay(5, 2, "iso8601", 1972); +instance.toJSON(); + +Object.defineProperty(Temporal.Calendar.prototype, "id", idOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toJSON/calendarname.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toJSON/calendarname.js index a590710d694d..d5606782a70e 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toJSON/calendarname.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toJSON/calendarname.js @@ -7,12 +7,35 @@ description: toJSON doesn't take calendarName into account. features: [Temporal] ---*/ +const calendarMethods = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; + const tests = [ [[], "05-02"], - [[{ toString() { return "custom"; } }], "1972-05-02[u-ca=custom]"], - [[{ toString() { return "iso8601"; } }], "05-02"], - [[{ toString() { return "ISO8601"; } }], "1972-05-02[u-ca=ISO8601]"], - [[{ toString() { return "\u0131so8601"; } }], "1972-05-02[u-ca=\u0131so8601]"], // dotless i + [[{ id: "custom", ...calendarMethods }], "1972-05-02[u-ca=custom]"], + [[{ id: "iso8601", ...calendarMethods }], "05-02"], + [[{ id: "ISO8601", ...calendarMethods }], "1972-05-02[u-ca=ISO8601]"], + [[{ id: "\u0131so8601", ...calendarMethods }], "1972-05-02[u-ca=\u0131so8601]"], // dotless i ]; const options = { get calendarName() { diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toJSON/year-format.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toJSON/year-format.js index 90b633fb299f..ebe40ba17385 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toJSON/year-format.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toJSON/year-format.js @@ -11,7 +11,7 @@ features: [Temporal] // the calendar is not ISO 8601 class NotISO extends Temporal.Calendar { constructor() { super("iso8601"); } - toString() { return "not-iso"; } + get id() { return "not-iso"; } } const calendar = new NotISO(); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toLocaleString/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toLocaleString/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..7e5758ba462f --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toLocaleString/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday.prototype.tolocalestring +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const idOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "id"); +Object.defineProperty(Temporal.Calendar.prototype, "id", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("id should not be looked up"); + }, +}); + +const instance = new Temporal.PlainMonthDay(5, 2, "iso8601", 1972); +instance.toLocaleString(undefined, { calendar: "iso8601" }); + +Object.defineProperty(Temporal.Calendar.prototype, "id", idOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toPlainDate/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toPlainDate/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..ced798602436 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toPlainDate/builtin-calendar-no-observable-calls.js @@ -0,0 +1,43 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday.prototype.toplaindate +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const fieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "fields"); +Object.defineProperty(Temporal.Calendar.prototype, "fields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("fields should not be looked up"); + }, +}); +const mergeFieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "mergeFields"); +Object.defineProperty(Temporal.Calendar.prototype, "mergeFields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("mergeFields should not be looked up"); + }, +}); +const dateFromFieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dateFromFields"); +Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("dateFromFields should not be looked up"); + }, +}); + +const instance = new Temporal.PlainMonthDay(5, 2, "iso8601", 1972); +instance.toPlainDate({ year: 2002 }); + +Object.defineProperty(Temporal.Calendar.prototype, "fields", fieldsOriginal); +Object.defineProperty(Temporal.Calendar.prototype, "mergeFields", mergeFieldsOriginal); +Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", dateFromFieldsOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..1879aaeb1620 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 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: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const idOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "id"); +Object.defineProperty(Temporal.Calendar.prototype, "id", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("id should not be looked up"); + }, +}); + +const instance = new Temporal.PlainMonthDay(5, 2, "iso8601", 1972); +instance.toString(); + +Object.defineProperty(Temporal.Calendar.prototype, "id", idOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/calendar-tostring.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/calendar-tostring.js index 1df2ef8da2e3..f48201eb7d07 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/calendar-tostring.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/calendar-tostring.js @@ -4,15 +4,39 @@ /*--- esid: sec-temporal.plainmonthday.protoype.tostring description: Number of observable 'toString' calls on the calendar for each value of calendarName +includes: [temporalHelpers.js] features: [Temporal] ---*/ let calls; const customCalendar = { - toString() { + get id() { ++calls; return "custom"; - } + }, + toString() { + TemporalHelpers.assertUnreachable('toString should not be called'); + }, + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, }; const monthday = new Temporal.PlainMonthDay(5, 2, customCalendar); [ @@ -24,6 +48,6 @@ const monthday = new Temporal.PlainMonthDay(5, 2, customCalendar); ].forEach(([calendarName, expectedResult, expectedCalls]) => { calls = 0; const result = monthday.toString({ calendarName }); - assert.sameValue(result, expectedResult, `toString output for calendarName = ${calendarName}`); - assert.sameValue(calls, expectedCalls, `calls to toString for calendarName = ${calendarName}`); + assert.sameValue(result, expectedResult, `id for calendarName = ${calendarName}`); + assert.sameValue(calls, expectedCalls, `calls to id getter for calendarName = ${calendarName}`); }); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/calendarname-always.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/calendarname-always.js index df1d606fda29..c5a3fe2d169f 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/calendarname-always.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/calendarname-always.js @@ -7,12 +7,35 @@ description: If calendarName is "always", the calendar ID should be included. features: [Temporal] ---*/ +const calendarMethods = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; + const tests = [ [[], "1972-05-02[u-ca=iso8601]", "built-in ISO"], - [[{ toString() { return "custom"; } }], "1972-05-02[u-ca=custom]", "custom"], - [[{ toString() { return "iso8601"; } }], "1972-05-02[u-ca=iso8601]", "custom with iso8601 toString"], - [[{ toString() { return "ISO8601"; } }], "1972-05-02[u-ca=ISO8601]", "custom with caps toString"], - [[{ toString() { return "\u0131so8601"; } }], "1972-05-02[u-ca=\u0131so8601]", "custom with dotless i toString"], + [[{ id: "custom", ...calendarMethods }], "1972-05-02[u-ca=custom]", "custom"], + [[{ id: "iso8601", ...calendarMethods }], "1972-05-02[u-ca=iso8601]", "custom with iso8601 id"], + [[{ id: "ISO8601", ...calendarMethods }], "1972-05-02[u-ca=ISO8601]", "custom with caps id"], + [[{ id: "\u0131so8601", ...calendarMethods }], "1972-05-02[u-ca=\u0131so8601]", "custom with dotless i id"], ]; for (const [args, expected, description] of tests) { diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/calendarname-auto.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/calendarname-auto.js index 5abf0fa619de..7ab7659c840c 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/calendarname-auto.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/calendarname-auto.js @@ -7,12 +7,35 @@ description: If calendarName is "auto", "iso8601" should be omitted. features: [Temporal] ---*/ +const calendarMethods = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; + const tests = [ [[], "05-02", "built-in ISO"], - [[{ toString() { return "custom"; } }], "1972-05-02[u-ca=custom]", "custom"], - [[{ toString() { return "iso8601"; } }], "05-02", "custom with iso8601 toString"], - [[{ toString() { return "ISO8601"; } }], "1972-05-02[u-ca=ISO8601]", "custom with caps toString"], - [[{ toString() { return "\u0131so8601"; } }], "1972-05-02[u-ca=\u0131so8601]", "custom with dotless i toString"], + [[{ id: "custom", ...calendarMethods }], "1972-05-02[u-ca=custom]", "custom"], + [[{ id: "iso8601", ...calendarMethods }], "05-02", "custom with iso8601 id"], + [[{ id: "ISO8601", ...calendarMethods }], "1972-05-02[u-ca=ISO8601]", "custom with caps id"], + [[{ id: "\u0131so8601", ...calendarMethods }], "1972-05-02[u-ca=\u0131so8601]", "custom with dotless i id"], ]; for (const [args, expected, description] of tests) { diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/calendarname-critical.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/calendarname-critical.js index f49b6f89ffbd..60d26a57d018 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/calendarname-critical.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/calendarname-critical.js @@ -9,12 +9,35 @@ description: > features: [Temporal] ---*/ +const calendarMethods = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; + const tests = [ [[], "1972-05-02[!u-ca=iso8601]", "built-in ISO"], - [[{ toString() { return "custom"; } }], "1972-05-02[!u-ca=custom]", "custom"], - [[{ toString() { return "iso8601"; } }], "1972-05-02[!u-ca=iso8601]", "custom with iso8601 toString"], - [[{ toString() { return "ISO8601"; } }], "1972-05-02[!u-ca=ISO8601]", "custom with caps toString"], - [[{ toString() { return "\u0131so8601"; } }], "1972-05-02[!u-ca=\u0131so8601]", "custom with dotless i toString"], + [[{ id: "custom", ...calendarMethods }], "1972-05-02[!u-ca=custom]", "custom"], + [[{ id: "iso8601", ...calendarMethods }], "1972-05-02[!u-ca=iso8601]", "custom with iso8601 id"], + [[{ id: "ISO8601", ...calendarMethods }], "1972-05-02[!u-ca=ISO8601]", "custom with caps id"], + [[{ id: "\u0131so8601", ...calendarMethods }], "1972-05-02[!u-ca=\u0131so8601]", "custom with dotless i id"], ]; for (const [args, expected, description] of tests) { diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/calendarname-never.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/calendarname-never.js index 1fbb89abc758..50e04595763f 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/calendarname-never.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/calendarname-never.js @@ -7,12 +7,35 @@ description: If calendarName is "never", the calendar ID should be omitted. features: [Temporal] ---*/ +const calendarMethods = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; + const tests = [ [[], "05-02", "built-in ISO"], - [[{ toString() { return "custom"; } }], "1972-05-02", "custom"], - [[{ toString() { return "iso8601"; } }], "05-02", "custom with iso8601 toString"], - [[{ toString() { return "ISO8601"; } }], "1972-05-02", "custom with caps toString"], - [[{ toString() { return "\u0131so8601"; } }], "1972-05-02", "custom with dotless i toString"], + [[{ id: "custom", ...calendarMethods }], "1972-05-02", "custom"], + [[{ id: "iso8601", ...calendarMethods }], "05-02", "custom with iso8601 id"], + [[{ id: "ISO8601", ...calendarMethods }], "1972-05-02", "custom with caps id"], + [[{ id: "\u0131so8601", ...calendarMethods }], "1972-05-02", "custom with dotless i id"], ]; for (const [args, expected, description] of tests) { diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/calendarname-undefined.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/calendarname-undefined.js index 8fc2cde338d7..67c1d3a628da 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/calendarname-undefined.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/calendarname-undefined.js @@ -14,12 +14,35 @@ info: | features: [Temporal] ---*/ +const calendarMethods = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; + const tests = [ [[], "05-02", "built-in ISO"], - [[{ toString() { return "custom"; } }], "1972-05-02[u-ca=custom]", "custom"], - [[{ toString() { return "iso8601"; } }], "05-02", "custom with iso8601 toString"], - [[{ toString() { return "ISO8601"; } }], "1972-05-02[u-ca=ISO8601]", "custom with caps toString"], - [[{ toString() { return "\u0131so8601"; } }], "1972-05-02[u-ca=\u0131so8601]", "custom with dotless i toString"], + [[{ id: "custom", ...calendarMethods }], "1972-05-02[u-ca=custom]", "custom"], + [[{ id: "iso8601", ...calendarMethods }], "05-02", "custom with iso8601 id"], + [[{ id: "ISO8601", ...calendarMethods }], "1972-05-02[u-ca=ISO8601]", "custom with caps id"], + [[{ id: "\u0131so8601", ...calendarMethods }], "1972-05-02[u-ca=\u0131so8601]", "custom with dotless i id"], ]; for (const [args, expected, description] of tests) { diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/calendarname-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/calendarname-wrong-type.js index 39328d7e5745..efbc3a61386f 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/calendarname-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/calendarname-wrong-type.js @@ -16,7 +16,27 @@ features: [Temporal] ---*/ const calendar = { - toString() { return "custom"; } + id: "custom", + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, }; const monthday = new Temporal.PlainMonthDay(5, 2, calendar); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/options-undefined.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/options-undefined.js index da53b9a72c3e..73b5c8361b18 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/options-undefined.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/options-undefined.js @@ -7,12 +7,35 @@ description: Verify that undefined options are handled correctly. features: [Temporal] ---*/ +const calendarMethods = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; + const tests = [ [[], "05-02"], - [[{ toString() { return "custom"; } }], "1972-05-02[u-ca=custom]"], - [[{ toString() { return "iso8601"; } }], "05-02"], - [[{ toString() { return "ISO8601"; } }], "1972-05-02[u-ca=ISO8601]"], - [[{ toString() { return "\u0131so8601"; } }], "1972-05-02[u-ca=\u0131so8601]"], // dotless i + [[{ id: "custom", ...calendarMethods }], "1972-05-02[u-ca=custom]"], + [[{ id: "iso8601", ...calendarMethods }], "05-02"], + [[{ id: "ISO8601", ...calendarMethods }], "1972-05-02[u-ca=ISO8601]"], + [[{ id: "\u0131so8601", ...calendarMethods }], "1972-05-02[u-ca=\u0131so8601]"], // dotless i ]; for (const [args, expected] of tests) { diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/order-of-operations.js index be16b543ed39..6bd221d57d87 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/order-of-operations.js @@ -12,9 +12,7 @@ const expected = [ "get options.calendarName", "get options.calendarName.toString", "call options.calendarName.toString", - "get this.calendar[Symbol.toPrimitive]", - "get this.calendar.toString", - "call this.calendar.toString", + "get this.calendar.id", ]; const actual = []; diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/year-format.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/year-format.js index 3898ff66b655..da4aaeb7cb3d 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/year-format.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/toString/year-format.js @@ -11,7 +11,7 @@ features: [Temporal] // the calendar is not ISO 8601 class NotISO extends Temporal.Calendar { constructor() { super("iso8601"); } - toString() { return "not-iso"; } + get id() { return "not-iso"; } } const calendar = new NotISO(); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/with/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/with/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..8fa4dfe27d9d --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainMonthDay/prototype/with/builtin-calendar-no-observable-calls.js @@ -0,0 +1,43 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday.prototype.with +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const fieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "fields"); +Object.defineProperty(Temporal.Calendar.prototype, "fields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("fields should not be looked up"); + }, +}); +const mergeFieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "mergeFields"); +Object.defineProperty(Temporal.Calendar.prototype, "mergeFields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("mergeFields should not be looked up"); + }, +}); +const monthDayFromFieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "monthDayFromFields"); +Object.defineProperty(Temporal.Calendar.prototype, "monthDayFromFields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("monthDayFromFields should not be looked up"); + }, +}); + +const instance = new Temporal.PlainMonthDay(5, 2, "iso8601", 1972); +instance.with({ monthCode: "M06" }); + +Object.defineProperty(Temporal.Calendar.prototype, "fields", fieldsOriginal); +Object.defineProperty(Temporal.Calendar.prototype, "mergeFields", mergeFieldsOriginal); +Object.defineProperty(Temporal.Calendar.prototype, "monthDayFromFields", monthDayFromFieldsOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/basic.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/basic.js index 40ea36f208a4..ce41174fc104 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/basic.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/basic.js @@ -11,4 +11,3 @@ features: [Temporal] const args = [15, 23, 30, 123, 456, 789]; const plainTime = new Temporal.PlainTime(...args); TemporalHelpers.assertPlainTime(plainTime, ...args); -assert.sameValue(plainTime.calendar.id, "iso8601", "calendar"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/compare/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/compare/argument-string-calendar-annotation.js index ea387f7d8346..a24129cc3bff 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/compare/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/compare/argument-string-calendar-annotation.js @@ -21,7 +21,6 @@ const tests = [ ["1970-01-01T12:34:56.987654321[!u-ca=iso8601]", "with !, date, and no time zone"], ["1970-01-01T12:34:56.987654321[UTC][!u-ca=iso8601]", "with !, date, and time zone"], ["1970-01-01T12:34:56.987654321[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["1970-01-01T12:34:56.987654321[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; tests.forEach(([arg, description]) => { diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/compare/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/compare/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..be05ad6f4323 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/compare/argument-string-multiple-calendar.js @@ -0,0 +1,34 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.compare +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "00:00[u-ca=iso8601][!u-ca=iso8601]", + "00:00[!u-ca=iso8601][u-ca=iso8601]", + "00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; + +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => Temporal.PlainTime.compare(arg, new Temporal.PlainTime(12, 34, 56, 987, 654, 321)), + `reject more than one calendar annotation if any critical: ${arg} (first argument)` + ); + assert.throws( + RangeError, + () => Temporal.PlainTime.compare(new Temporal.PlainTime(12, 34, 56, 987, 654, 321), arg), + `reject more than one calendar annotation if any critical: ${arg} (first argument)` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/compare/calendar-temporal-object.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/compare/calendar-temporal-object.js deleted file mode 100644 index c1eb23e228fa..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/compare/calendar-temporal-object.js +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (C) 2020 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.plaintime.compare -description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots -info: | - sec-temporal.plaintime.compare steps 1–2: - 1. Set _one_ to ? ToTemporalTime(_one_). - 2. Set _two_ to ? ToTemporalTime(_two_). - sec-temporal-totemporaltime step 3.d: - d. If _calendar_ is not *undefined*, then - i. Set _calendar_ to ? ToTemporalCalendar(_calendar_). - ii. If ? ToString(_calendar_) is not *"iso8601"*, then - 1. Throw a *RangeError* exception. - sec-temporal-totemporalcalendar step 1.a: - a. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then - i. Return _temporalCalendarLike_.[[Calendar]]. -includes: [compareArray.js, temporalHelpers.js] -features: [Temporal] ----*/ - -TemporalHelpers.checkToTemporalCalendarFastPath((temporalObject) => { - const time = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); - assert.throws(RangeError, () => Temporal.PlainTime.compare({ hour: 12, minute: 30, calendar: temporalObject }, time)); - assert.throws(RangeError, () => Temporal.PlainTime.compare(time, { hour: 12, minute: 30, calendar: temporalObject })); -}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/from/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/from/argument-string-calendar-annotation.js index b15e34bf4de7..8375464ecc86 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/from/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/from/argument-string-calendar-annotation.js @@ -21,8 +21,10 @@ const tests = [ ["1970-01-01T12:34:56.987654321[UTC][u-ca=iso8601]", "with date and time zone"], ["1970-01-01T12:34:56.987654321[!u-ca=iso8601]", "with !, date, and no time zone"], ["1970-01-01T12:34:56.987654321[UTC][!u-ca=iso8601]", "with !, date, and time zone"], + ["12:34:56.987654321[u-ca=hebrew]", "calendar annotation ignored"], + ["12:34:56.987654321[u-ca=unknown]", "calendar annotation ignored even if unknown calendar"], + ["12:34:56.987654321[!u-ca=unknown]", "calendar annotation ignored even if unknown calendar with !"], ["1970-01-01T12:34:56.987654321[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["1970-01-01T12:34:56.987654321[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; tests.forEach(([arg, description]) => { diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/from/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/from/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..b6f2e20ceb07 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/from/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.from +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "00:00[u-ca=iso8601][!u-ca=iso8601]", + "00:00[!u-ca=iso8601][u-ca=iso8601]", + "00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; + +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => Temporal.PlainTime.from(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/from/argument-string-with-calendar.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/from/argument-string-with-calendar.js deleted file mode 100644 index 84bb8ee43bae..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/from/argument-string-with-calendar.js +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal-totemporaltime -description: Strings with non-ISO calendars are not supported. -info: | - b. Let result be ? ParseTemporalTimeString(string). - d. If result.[[Calendar]] is not one of undefined or "iso8601", then - i. Throw a RangeError exception. -features: [Temporal] ----*/ - -const isoString = "2004-03-21T10:00:00"; - -const valid = [ - "", - "[u-ca=iso8601]", -]; - -for (const s of valid) { - const input = isoString + s; - const plainTime = Temporal.PlainTime.from(input); - assert.sameValue(plainTime.calendar.id, "iso8601"); -} - -const invalid = [ - "[u-ca=indian]", - "[u-ca=hebrew]", -]; - -for (const s of invalid) { - const input = isoString + s; - assert.throws(RangeError, () => Temporal.PlainTime.from(input)); -} diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/from/calendar-temporal-object.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/from/calendar-temporal-object.js deleted file mode 100644 index 639a79426a91..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/from/calendar-temporal-object.js +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (C) 2020 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.plaintime.from -description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots -info: | - sec-temporal.plaintime.from step 4: - 4. Return ? ToTemporalTime(_temporalTime_, _overflow_). - sec-temporal-totemporaltime step 3.d: - d. If _calendar_ is not *undefined*, then - i. Set _calendar_ to ? ToTemporalCalendar(_calendar_). - ii. If ? ToString(_calendar_) is not *"iso8601"*, then - 1. Throw a *RangeError* exception. - sec-temporal-totemporalcalendar step 1.a: - a. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then - i. Return _temporalCalendarLike_.[[Calendar]]. -includes: [compareArray.js, temporalHelpers.js] -features: [Temporal] ----*/ - -TemporalHelpers.checkToTemporalCalendarFastPath((temporalObject) => { - assert.throws(RangeError, () => Temporal.PlainTime.from({ hour: 12, minute: 34, second: 56, calendar: temporalObject })); -}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/from/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/from/order-of-operations.js index 8c4548e9208c..96d1e896285f 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/from/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/from/order-of-operations.js @@ -12,9 +12,6 @@ const expected = [ "get options.overflow", "get options.overflow.toString", "call options.overflow.toString", - "get fields.calendar", - "get fields.calendar.toString", - "call fields.calendar.toString", // ToTemporalTimeRecord "get fields.hour", "get fields.hour.valueOf", diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/add/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/add/order-of-operations.js index c67fdba319ca..92409826ccf5 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/add/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/add/order-of-operations.js @@ -56,5 +56,4 @@ const fields = TemporalHelpers.propertyBagObserver(actual, { }, "fields"); const result = instance.add(fields); TemporalHelpers.assertPlainTime(result, 13, 35, 57, 988, 655, 322); -assert.sameValue(result.calendar.id, "iso8601", "calendar result"); assert.compareArray(actual, expected, "order of operations"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/calendar/basic.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/calendar/basic.js deleted file mode 100644 index 83bd0e3f1920..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/calendar/basic.js +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (C) 2022 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-get-temporal.plaintime.prototype.calendar -description: calendar returns the iso8601 calendar. -features: [Temporal] ----*/ - -const pt = new Temporal.PlainTime(); -assert(pt.calendar instanceof Temporal.Calendar, "getter returns Calendar object"); -assert.sameValue(pt.calendar.toString(), "iso8601", "getter returns iso8601 calendar"); -assert.sameValue(pt.calendar, pt.calendar, "getter returns the same object"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/calendar/branding.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/calendar/branding.js deleted file mode 100644 index ccf2de2a6c4d..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/calendar/branding.js +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-get-temporal.plaintime.prototype.calendar -description: Throw a TypeError if the receiver is invalid -features: [Symbol, Temporal] ----*/ - -const calendar = Object.getOwnPropertyDescriptor(Temporal.PlainTime.prototype, "calendar").get; - -assert.sameValue(typeof calendar, "function"); - -assert.throws(TypeError, () => calendar.call(undefined), "undefined"); -assert.throws(TypeError, () => calendar.call(null), "null"); -assert.throws(TypeError, () => calendar.call(true), "true"); -assert.throws(TypeError, () => calendar.call(""), "empty string"); -assert.throws(TypeError, () => calendar.call(Symbol()), "symbol"); -assert.throws(TypeError, () => calendar.call(1), "1"); -assert.throws(TypeError, () => calendar.call({}), "plain object"); -assert.throws(TypeError, () => calendar.call(Temporal.PlainTime), "Temporal.PlainTime"); -assert.throws(TypeError, () => calendar.call(Temporal.PlainTime.prototype), "Temporal.PlainTime.prototype"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/calendar/prop-desc.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/calendar/prop-desc.js deleted file mode 100644 index d4ffd5312eb9..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/calendar/prop-desc.js +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-get-temporal.plaintime.prototype.calendar -description: The "calendar" property of Temporal.PlainTime.prototype -features: [Temporal] ----*/ - -const descriptor = Object.getOwnPropertyDescriptor(Temporal.PlainTime.prototype, "calendar"); -assert.sameValue(typeof descriptor.get, "function"); -assert.sameValue(descriptor.set, undefined); -assert.sameValue(descriptor.enumerable, false); -assert.sameValue(descriptor.configurable, true); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/equals/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/equals/argument-string-calendar-annotation.js index 1803cce00ef9..597aa0c7fe89 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/equals/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/equals/argument-string-calendar-annotation.js @@ -20,8 +20,10 @@ const tests = [ ["1970-01-01T12:34:56.987654321[UTC][u-ca=iso8601]", "with date and time zone"], ["1970-01-01T12:34:56.987654321[!u-ca=iso8601]", "with !, date, and no time zone"], ["1970-01-01T12:34:56.987654321[UTC][!u-ca=iso8601]", "with !, date, and time zone"], + ["12:34:56.987654321[u-ca=hebrew]", "calendar annotation ignored"], + ["12:34:56.987654321[u-ca=unknown]", "calendar annotation ignored even if unknown calendar"], + ["12:34:56.987654321[!u-ca=unknown]", "calendar annotation ignored even if unknown calendar with !"], ["1970-01-01T12:34:56.987654321[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["1970-01-01T12:34:56.987654321[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/equals/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/equals/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..f4801ffffb18 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/equals/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.equals +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "00:00[u-ca=iso8601][!u-ca=iso8601]", + "00:00[!u-ca=iso8601][u-ca=iso8601]", + "00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.equals(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/equals/calendar-temporal-object.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/equals/calendar-temporal-object.js deleted file mode 100644 index 0234fb5444f5..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/equals/calendar-temporal-object.js +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (C) 2020 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.plaintime.prototype.equals -description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots -info: | - sec-temporal.plaintime.prototype.equals step 3: - 3. Set _other_ to ? ToTemporalTime(_other_). - sec-temporal-totemporaltime step 3.d: - d. If _calendar_ is not *undefined*, then - i. Set _calendar_ to ? ToTemporalCalendar(_calendar_). - ii. If ? ToString(_calendar_) is not *"iso8601"*, then - 1. Throw a *RangeError* exception. - sec-temporal-totemporalcalendar step 1.a: - a. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then - i. Return _temporalCalendarLike_.[[Calendar]]. -includes: [compareArray.js, temporalHelpers.js] -features: [Temporal] ----*/ - -TemporalHelpers.checkToTemporalCalendarFastPath((temporalObject) => { - const time = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); - assert.throws(RangeError, () => time.equals({ hour: 12, minute: 30, calendar: temporalObject })); -}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/getISOFields/custom.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/getISOFields/custom.js deleted file mode 100644 index cf6d41ceab15..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/getISOFields/custom.js +++ /dev/null @@ -1,21 +0,0 @@ -// 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.getisofields -description: getISOFields does not call into user code. -includes: [temporalHelpers.js] -features: [Temporal] ----*/ - -const calendar = TemporalHelpers.calendarThrowEverything(); -const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321, calendar); -const result = instance.getISOFields(); - -assert.sameValue(result.isoHour, 12, "isoHour result"); -assert.sameValue(result.isoMinute, 34, "isoMinute result"); -assert.sameValue(result.isoSecond, 56, "isoSecond result"); -assert.sameValue(result.isoMillisecond, 987, "isoMillisecond result"); -assert.sameValue(result.isoMicrosecond, 654, "isoMicrosecond result"); -assert.sameValue(result.isoNanosecond, 321, "isoNanosecond result"); -assert.sameValue(result.calendar.id, "iso8601", "calendar result"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/getISOFields/field-names.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/getISOFields/field-names.js index df16645aa973..4ea80a535fac 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/getISOFields/field-names.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/getISOFields/field-names.js @@ -16,4 +16,3 @@ assert.sameValue(result.isoSecond, 56, "isoSecond result"); assert.sameValue(result.isoMillisecond, 987, "isoMillisecond result"); assert.sameValue(result.isoMicrosecond, 654, "isoMicrosecond result"); assert.sameValue(result.isoNanosecond, 321, "isoNanosecond result"); -assert.sameValue(result.calendar.id, "iso8601", "calendar result"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/getISOFields/field-prop-desc.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/getISOFields/field-prop-desc.js index 3d4c7a6cb5cf..4b81951bf45a 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/getISOFields/field-prop-desc.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/getISOFields/field-prop-desc.js @@ -9,7 +9,6 @@ features: [Temporal] ---*/ const expected = [ - "calendar", "isoHour", "isoMicrosecond", "isoMillisecond", diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/getISOFields/field-traversal-order.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/getISOFields/field-traversal-order.js index 882bfda76ea8..55afd2c4d85d 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/getISOFields/field-traversal-order.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/getISOFields/field-traversal-order.js @@ -9,7 +9,6 @@ features: [Temporal] ---*/ const expected = [ - "calendar", "isoHour", "isoMicrosecond", "isoMillisecond", diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/since/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/since/argument-string-calendar-annotation.js index eac24b18f901..8b1912724658 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/since/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/since/argument-string-calendar-annotation.js @@ -21,8 +21,10 @@ const tests = [ ["1970-01-01T12:34:56.987654321[UTC][u-ca=iso8601]", "with date and time zone"], ["1970-01-01T12:34:56.987654321[!u-ca=iso8601]", "with !, date, and no time zone"], ["1970-01-01T12:34:56.987654321[UTC][!u-ca=iso8601]", "with !, date, and time zone"], + ["12:34:56.987654321[u-ca=hebrew]", "calendar annotation ignored"], + ["12:34:56.987654321[u-ca=unknown]", "calendar annotation ignored even if unknown calendar"], + ["12:34:56.987654321[!u-ca=unknown]", "calendar annotation ignored even if unknown calendar with !"], ["1970-01-01T12:34:56.987654321[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["1970-01-01T12:34:56.987654321[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/since/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/since/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..9b7c4ac82cbf --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/since/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 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: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "00:00[u-ca=iso8601][!u-ca=iso8601]", + "00:00[!u-ca=iso8601][u-ca=iso8601]", + "00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.since(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/since/calendar-temporal-object.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/since/calendar-temporal-object.js deleted file mode 100644 index 04bf4d7492db..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/since/calendar-temporal-object.js +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (C) 2020 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: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots -info: | - sec-temporal.plaintime.prototype.since step 3: - 3. Set _other_ to ? ToTemporalTime(_other_). - sec-temporal-totemporaltime step 3.d: - d. If _calendar_ is not *undefined*, then - i. Set _calendar_ to ? ToTemporalCalendar(_calendar_). - ii. If ? ToString(_calendar_) is not *"iso8601"*, then - 1. Throw a *RangeError* exception. - sec-temporal-totemporalcalendar step 1.a: - a. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then - i. Return _temporalCalendarLike_.[[Calendar]]. -includes: [compareArray.js, temporalHelpers.js] -features: [Temporal] ----*/ - -TemporalHelpers.checkToTemporalCalendarFastPath((temporalObject) => { - const time = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); - assert.throws(RangeError, () => time.since({ hour: 12, minute: 30, calendar: temporalObject })); -}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/since/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/since/order-of-operations.js index 3505a4166019..1809cd3575d8 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/since/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/since/order-of-operations.js @@ -10,9 +10,6 @@ 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", diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/subtract/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/subtract/order-of-operations.js index c11a4b025838..b6727a99f355 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/subtract/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/subtract/order-of-operations.js @@ -56,5 +56,4 @@ const fields = TemporalHelpers.propertyBagObserver(actual, { }, "fields"); const result = instance.subtract(fields); TemporalHelpers.assertPlainTime(result, 11, 33, 55, 986, 653, 320); -assert.sameValue(result.calendar.id, "iso8601", "calendar result"); assert.compareArray(actual, expected, "order of operations"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-propertybag-calendar-case-insensitive.js index 710e28d45805..8c759f73db7f 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-propertybag-calendar-case-insensitive.js @@ -12,10 +12,6 @@ const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); const calendar = "IsO8601"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.toPlainDateTime(arg); -TemporalHelpers.assertPlainDateTime(result1, 1976, 11, "M11", 18, 12, 34, 56, 987, 654, 321, "Calendar is case-insensitive"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.toPlainDateTime(arg); -TemporalHelpers.assertPlainDateTime(result2, 1976, 11, "M11", 18, 12, 34, 56, 987, 654, 321, "Calendar is case-insensitive (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.toPlainDateTime(arg); +TemporalHelpers.assertPlainDateTime(result, 1976, 11, "M11", 18, 12, 34, 56, 987, 654, 321, "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index ccb3efa81c1b..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,25 +0,0 @@ -// 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.toplaindatetime -description: > - A Temporal.Calendar instance passed to toPlainDateTime() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -instance.toPlainDateTime(arg); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -instance.toPlainDateTime(arg); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-propertybag-calendar-leap-second.js index 6e38a9300382..21a0901132c7 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-propertybag-calendar-leap-second.js @@ -12,18 +12,10 @@ const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); const calendar = "2016-12-31T23:59:60"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.toPlainDateTime(arg); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.toPlainDateTime(arg); TemporalHelpers.assertPlainDateTime( - result1, + result, 1976, 11, "M11", 18, 12, 34, 56, 987, 654, 321, "leap second is a valid ISO string for calendar" ); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.toPlainDateTime(arg); -TemporalHelpers.assertPlainDateTime( - result2, - 1976, 11, "M11", 18, 12, 34, 56, 987, 654, 321, - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-propertybag-calendar-number.js index 1353b30b9917..2d642c11ce67 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-propertybag-calendar-number.js @@ -12,13 +12,9 @@ const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); const calendar = 19970327; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.toPlainDateTime(arg); -TemporalHelpers.assertPlainDateTime(result1, 1976, 11, "M11", 18, 12, 34, 56, 987, 654, 321, "19970327 is a valid ISO string for calendar"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.toPlainDateTime(arg); -TemporalHelpers.assertPlainDateTime(result2, 1976, 11, "M11", 18, 12, 34, 56, 987, 654, 321, "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.toPlainDateTime(arg); +TemporalHelpers.assertPlainDateTime(result, 1976, 11, "M11", 18, 12, 34, 56, 987, 654, 321, "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -27,16 +23,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; assert.throws( RangeError, () => instance.toPlainDateTime(arg), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.toPlainDateTime(arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-propertybag-calendar-wrong-type.js index b74193686c08..14aaad26d485 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-propertybag-calendar-wrong-type.js @@ -21,27 +21,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.toPlainDateTime(arg), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.toPlainDateTime(arg), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.toPlainDateTime(arg), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.toPlainDateTime(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.toPlainDateTime(arg), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-string-calendar-annotation.js index 40950a0b99b1..a0d745c9ae9f 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-string-calendar-annotation.js @@ -16,7 +16,6 @@ const tests = [ ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..ee035cef28d8 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.toplaindatetime +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.toPlainDateTime(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/calendar-temporal-object.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/calendar-temporal-object.js index c165f41d6df9..97146e9264f8 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/calendar-temporal-object.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/calendar-temporal-object.js @@ -23,5 +23,5 @@ features: [Temporal] TemporalHelpers.checkToTemporalCalendarFastPath((temporalObject, calendar) => { const time = new Temporal.PlainTime(13, 3); const result = time.toPlainDateTime({ year: 2000, month: 5, day: 3, calendar: temporalObject }); - assert.sameValue(result.calendar, calendar, "Temporal object coerced to calendar"); + assert.sameValue(result.getCalendar(), calendar, "Temporal object coerced to calendar"); }); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-propertybag-calendar-case-insensitive.js index 39d3572beac2..d9565e0d5960 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-propertybag-calendar-case-insensitive.js @@ -11,10 +11,6 @@ const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); const calendar = "IsO8601"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }); -assert.sameValue(result1.epochNanoseconds, 217_168_496_987_654_321n, "Calendar is case-insensitive"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }); -assert.sameValue(result2.epochNanoseconds, 217_168_496_987_654_321n, "Calendar is case-insensitive (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }); +assert.sameValue(result.epochNanoseconds, 217_168_496_987_654_321n, "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 8a04d725977c..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,25 +0,0 @@ -// 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.tozoneddatetime -description: > - A Temporal.Calendar instance passed to toZonedDateTime() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-propertybag-calendar-leap-second.js index 975d536ff80d..ad0bda9c1910 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-propertybag-calendar-leap-second.js @@ -11,18 +11,10 @@ const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); const calendar = "2016-12-31T23:59:60"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }); assert.sameValue( - result1.epochNanoseconds, + result.epochNanoseconds, 217_168_496_987_654_321n, "leap second is a valid ISO string for calendar" ); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }); -assert.sameValue( - result2.epochNanoseconds, - 217_168_496_987_654_321n, - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-propertybag-calendar-number.js index 1f40ffa0dcf2..0dab910df75a 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-propertybag-calendar-number.js @@ -11,13 +11,9 @@ const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); const calendar = 19970327; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }); -assert.sameValue(result1.epochNanoseconds, 217_168_496_987_654_321n, "19970327 is a valid ISO string for calendar"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }); -assert.sameValue(result2.epochNanoseconds, 217_168_496_987_654_321n, "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }); +assert.sameValue(result.epochNanoseconds, 217_168_496_987_654_321n, "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -26,16 +22,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; assert.throws( RangeError, () => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-propertybag-calendar-wrong-type.js index 22a1101801c6..6b05bed91d73 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-propertybag-calendar-wrong-type.js @@ -21,27 +21,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-string-calendar-annotation.js index c32a12c35ae5..028035f12230 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-string-calendar-annotation.js @@ -15,7 +15,6 @@ const tests = [ ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..42894d32854c --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.tozoneddatetime +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/basic.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/basic.js index 55b11b45d28e..3b1afd5c8e2b 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/basic.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/basic.js @@ -13,12 +13,12 @@ const timeZone = Temporal.TimeZone.from('-07:00'); const objects = plainTime.toZonedDateTime({ timeZone, plainDate }); assert.sameValue(objects.epochNanoseconds, 1594234800000000000n, "objects: epochNanoseconds"); -assert.sameValue(objects.timeZone, timeZone, "objects: timeZone"); +assert.sameValue(objects.getTimeZone(), timeZone, "objects: timeZone"); const timeZoneString = plainTime.toZonedDateTime({ timeZone: "-07:00", plainDate }); assert.sameValue(timeZoneString.epochNanoseconds, 1594234800000000000n, "timeZone string: epochNanoseconds"); -assert.sameValue(timeZoneString.timeZone.id, "-07:00", "timeZone string: timeZone"); +assert.sameValue(timeZoneString.timeZoneId, "-07:00", "timeZone string: timeZone"); const plainDateString = plainTime.toZonedDateTime({ timeZone, plainDate: "2020-07-08" }); assert.sameValue(plainDateString.epochNanoseconds, 1594234800000000000n, "plainDate string: epochNanoseconds"); -assert.sameValue(plainDateString.timeZone.id, "-07:00", "plainDate string: timeZone"); +assert.sameValue(plainDateString.getTimeZone(), timeZone, "plainDate string: timeZone"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/calendar-temporal-object.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/calendar-temporal-object.js index 400e9cbacb29..23372a953aa0 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/calendar-temporal-object.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/calendar-temporal-object.js @@ -23,5 +23,5 @@ features: [Temporal] TemporalHelpers.checkToTemporalCalendarFastPath((temporalObject, calendar) => { const time = new Temporal.PlainTime(13, 3); const result = time.toZonedDateTime({ timeZone: "UTC", plainDate: { year: 2000, month: 5, day: 3, calendar: temporalObject } }); - assert.sameValue(result.calendar, calendar, "Temporal object coerced to calendar"); + assert.sameValue(result.getCalendar(), calendar, "Temporal object coerced to calendar"); }); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-case-insensitive.js index 9fa6c6a4354d..7b71990b4e5d 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-case-insensitive.js @@ -7,8 +7,8 @@ description: Time zone names are case insensitive features: [Temporal] ---*/ -const instance = new Temporal.PlainTime(); +const instance = new Temporal.PlainTime(); const timeZone = 'uTc'; const result = instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone }); -assert.sameValue(result.timeZone.id, 'UTC', `Time zone created from string "${timeZone}"`); +assert.sameValue(result.timeZoneId, 'UTC', `Time zone created from string "${timeZone}"`); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-instance-does-not-get-timeZone-property.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-instance-does-not-get-timeZone-property.js deleted file mode 100644 index 75ecf010fd4c..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-instance-does-not-get-timeZone-property.js +++ /dev/null @@ -1,22 +0,0 @@ -// 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.tozoneddatetime -description: > - A Temporal.TimeZone instance passed to toZonedDateTime() does not have its - 'timeZone' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.PlainTime(); - -const timeZone = new Temporal.TimeZone("UTC"); -Object.defineProperty(timeZone, "timeZone", { - get() { - throw new Test262Error("timeZone.timeZone should not be accessed"); - }, -}); - -instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone }); -instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone: { timeZone } }); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-string-datetime.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-string-datetime.js index b0537ee43162..a475b9870d3b 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-string-datetime.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-string-datetime.js @@ -11,34 +11,23 @@ const instance = new Temporal.PlainTime(); let timeZone = "2021-08-19T17:30"; assert.throws(RangeError, () => instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone }), "bare date-time string is not a time zone"); -assert.throws(RangeError, () => instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone: { timeZone } }), "bare date-time string is not a time zone"); timeZone = "2021-08-19T17:30Z"; const result1 = instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone }); -assert.sameValue(result1.timeZone.id, "UTC", "date-time + Z is UTC time zone"); -const result2 = instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone: { timeZone } }); -assert.sameValue(result2.timeZone.id, "UTC", "date-time + Z is UTC time zone (string in property bag)"); +assert.sameValue(result1.timeZoneId, "UTC", "date-time + Z is UTC time zone"); timeZone = "2021-08-19T17:30-07:00"; -const result3 = instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone }); -assert.sameValue(result3.timeZone.id, "-07:00", "date-time + offset is the offset time zone"); -const result4 = instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone: { timeZone } }); -assert.sameValue(result4.timeZone.id, "-07:00", "date-time + offset is the offset time zone (string in property bag)"); +const result2 = instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone }); +assert.sameValue(result2.timeZoneId, "-07:00", "date-time + offset is the offset time zone"); timeZone = "2021-08-19T17:30[UTC]"; -const result5 = instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone }); -assert.sameValue(result5.timeZone.id, "UTC", "date-time + IANA annotation is the IANA time zone"); -const result6 = instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone: { timeZone } }); -assert.sameValue(result6.timeZone.id, "UTC", "date-time + IANA annotation is the IANA time zone (string in property bag)"); +const result3 = instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone }); +assert.sameValue(result3.timeZoneId, "UTC", "date-time + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30Z[UTC]"; -const result7 = instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone }); -assert.sameValue(result7.timeZone.id, "UTC", "date-time + Z + IANA annotation is the IANA time zone"); -const result8 = instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone: { timeZone } }); -assert.sameValue(result8.timeZone.id, "UTC", "date-time + Z + IANA annotation is the IANA time zone (string in property bag)"); +const result4 = instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone }); +assert.sameValue(result4.timeZoneId, "UTC", "date-time + Z + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30-07:00[UTC]"; -const result9 = instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone }); -assert.sameValue(result9.timeZone.id, "UTC", "date-time + offset + IANA annotation is the IANA time zone"); -const result10 = instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone: { timeZone } }); -assert.sameValue(result10.timeZone.id, "UTC", "date-time + offset + IANA annotation is the IANA time zone (string in property bag)"); +const result5 = instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone }); +assert.sameValue(result5.timeZoneId, "UTC", "date-time + offset + IANA annotation is the IANA time zone"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-string-leap-second.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-string-leap-second.js index 78dffeb2c9b2..bb994f9ef544 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-string-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-string-leap-second.js @@ -10,11 +10,8 @@ features: [Temporal] const instance = new Temporal.PlainTime(); let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; -const result1 = instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone }); -assert.sameValue(result1.timeZone.id, "UTC", "leap second is a valid ISO string for TimeZone"); -const result2 = instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone: { timeZone } }); -assert.sameValue(result2.timeZone.id, "UTC", "leap second is a valid ISO string for TimeZone (nested property)"); +const result = instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone }); +assert.sameValue(result.timeZoneId, "UTC", "leap second is a valid ISO string for TimeZone"); timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; assert.throws(RangeError, () => instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone }), "leap second in time zone name not valid"); -assert.throws(RangeError, () => instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone: { timeZone } }), "leap second in time zone name not valid (nested property)"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-string-multiple-offsets.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-string-multiple-offsets.js index fbbad9045378..e70db04f473a 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-string-multiple-offsets.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-string-multiple-offsets.js @@ -10,7 +10,5 @@ features: [Temporal] const instance = new Temporal.PlainTime(); const timeZone = "2021-08-19T17:30:45.123456789+01:46[+01:45:30.987654321]"; -const result1 = instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone }); -assert.sameValue(result1.timeZone.id, "+01:45:30.987654321", "Time zone string determined from bracket name"); -const result2 = instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone: { timeZone } }); -assert.sameValue(result2.timeZone.id, "+01:45:30.987654321", "Time zone string determined from bracket name"); +const result = instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone }); +assert.sameValue(result.timeZoneId, "+01:45:30.987654321", "Time zone string determined from bracket name"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-string-year-zero.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-string-year-zero.js index 80a06780bc79..50ca173af49c 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-string-year-zero.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-string-year-zero.js @@ -18,9 +18,4 @@ invalidStrings.forEach((timeZone) => { () => instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone }), "reject minus zero as extended year" ); - assert.throws( - RangeError, - () => instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone: { timeZone } }), - "reject minus zero as extended year (nested property)" - ); }); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-string.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-string.js index 0798d74080bd..6e3de214a873 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-string.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-string.js @@ -4,12 +4,33 @@ /*--- esid: sec-temporal.plaintime.prototype.tozoneddatetime description: Time zone IDs are valid input for a time zone +includes: [temporalHelpers.js] features: [Temporal] ---*/ +const getPossibleInstantsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getPossibleInstantsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getPossibleInstantsFor should not be looked up"); + }, +}); +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + const instance = new Temporal.PlainTime(); ["UTC", "+01:30"].forEach((timeZone) => { const result = instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone }); - assert.sameValue(result.timeZone.id, timeZone, `Time zone created from string "${timeZone}"`); + assert.sameValue(result.getISOFields().timeZone, timeZone, `time zone slot should store string "${timeZone}"`); }); + +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", getPossibleInstantsForOriginal); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-wrong-type.js index 304f4990b67e..7aa204395e25 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-wrong-type.js @@ -18,22 +18,18 @@ const rangeErrorTests = [ [1, "number that doesn't convert to a valid ISO string"], [19761118, "number that would convert to a valid ISO string in other contexts"], [1n, "bigint"], - [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of rangeErrorTests) { assert.throws(RangeError, () => instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone }), `${description} does not convert to a valid ISO string`); - assert.throws(RangeError, () => instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone: { timeZone } }), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], + [{}, "object not implementing time zone protocol"], + [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of typeErrorTests) { assert.throws(TypeError, () => instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone }), `${description} is not a valid object and does not convert to a string`); - assert.throws(TypeError, () => instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone: { timeZone } }), `${description} is not a valid object and does not convert to a string (nested property)`); } - -const timeZone = undefined; -assert.throws(RangeError, () => instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone: { timeZone } }), `undefined is always a RangeError as nested property`); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/until/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/until/argument-string-calendar-annotation.js index 4d2f6c0c4c0a..b29530178023 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/until/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/until/argument-string-calendar-annotation.js @@ -21,8 +21,10 @@ const tests = [ ["1970-01-01T12:34:56.987654321[UTC][u-ca=iso8601]", "with date and time zone"], ["1970-01-01T12:34:56.987654321[!u-ca=iso8601]", "with !, date, and no time zone"], ["1970-01-01T12:34:56.987654321[UTC][!u-ca=iso8601]", "with !, date, and time zone"], + ["12:34:56.987654321[u-ca=hebrew]", "calendar annotation ignored"], + ["12:34:56.987654321[u-ca=unknown]", "calendar annotation ignored even if unknown calendar"], + ["12:34:56.987654321[!u-ca=unknown]", "calendar annotation ignored even if unknown calendar with !"], ["1970-01-01T12:34:56.987654321[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["1970-01-01T12:34:56.987654321[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/until/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/until/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..c69a68ba4910 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/until/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 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: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "00:00[u-ca=iso8601][!u-ca=iso8601]", + "00:00[!u-ca=iso8601][u-ca=iso8601]", + "00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.until(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/until/calendar-temporal-object.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/until/calendar-temporal-object.js deleted file mode 100644 index 983c110723a0..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/until/calendar-temporal-object.js +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (C) 2020 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: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots -info: | - sec-temporal.plaintime.prototype.until step 3: - 3. Set _other_ to ? ToTemporalTime(_other_). - sec-temporal-totemporaltime step 3.d: - d. If _calendar_ is not *undefined*, then - i. Set _calendar_ to ? ToTemporalCalendar(_calendar_). - ii. If ? ToString(_calendar_) is not *"iso8601"*, then - 1. Throw a *RangeError* exception. - sec-temporal-totemporalcalendar step 1.a: - a. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then - i. Return _temporalCalendarLike_.[[Calendar]]. -includes: [compareArray.js, temporalHelpers.js] -features: [Temporal] ----*/ - -TemporalHelpers.checkToTemporalCalendarFastPath((temporalObject) => { - const time = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); - assert.throws(RangeError, () => time.until({ hour: 12, minute: 30, calendar: temporalObject })); -}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/until/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/until/order-of-operations.js index 41263769a4fc..4c401ef2881b 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/until/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainTime/prototype/until/order-of-operations.js @@ -10,9 +10,6 @@ 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", diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/calendar-case-insensitive.js index 9160f5648759..7c6d96efcec4 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/calendar-case-insensitive.js @@ -10,4 +10,4 @@ features: [Temporal] const arg = "iSo8601"; const result = new Temporal.PlainYearMonth(2000, 5, arg, 1); -assert.sameValue(result.calendar.id, "iso8601", "Calendar is case-insensitive"); +assert.sameValue(result.calendarId, "iso8601", "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 87011f26e9f8..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,20 +0,0 @@ -// 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 -description: > - A Temporal.Calendar instance passed to new PlainYearMonth() does not have - its 'calendar' property observably checked -features: [Temporal] ----*/ - -const arg = new Temporal.Calendar("iso8601"); -Object.defineProperty(arg, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -new Temporal.PlainYearMonth(2000, 5, arg, 1); -new Temporal.PlainYearMonth(2000, 5, { calendar: arg }, 1); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/calendar-number.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/calendar-number.js index cf7d4142a517..4b22e59ebfe0 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/calendar-number.js @@ -10,7 +10,7 @@ features: [Temporal] const arg = 19761118; const result = new Temporal.PlainYearMonth(2000, 5, arg, 1); -assert.sameValue(result.calendar.id, "iso8601", "19761118 is a valid ISO string for Calendar"); +assert.sameValue(result.calendarId, "iso8601", "19761118 is a valid ISO string for Calendar"); const numbers = [ 1, diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/calendar-string.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/calendar-string.js index 1c2be402aed2..d9f558955c06 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/calendar-string.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/calendar-string.js @@ -10,4 +10,4 @@ features: [Temporal] const arg = "iso8601"; const result = new Temporal.PlainYearMonth(2000, 5, arg, 1); -assert.sameValue(result.calendar.id, "iso8601", `Calendar created from string "${arg}"`); +assert.sameValue(result.getISOFields().calendar, "iso8601", `Calendar created from string "${arg}"`); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/calendar-temporal-object.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/calendar-temporal-object.js index 65ad8ab6e631..e9fb1c9c0ab6 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/calendar-temporal-object.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/calendar-temporal-object.js @@ -6,7 +6,7 @@ esid: sec-temporal.plainyearmonth description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots info: | sec-temporal-totemporalcalendar step 1.b: - b. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then + b. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then i. Return _temporalCalendarLike_.[[Calendar]]. includes: [compareArray.js] features: [Temporal] @@ -14,12 +14,11 @@ features: [Temporal] const plainDate = new Temporal.PlainDate(2000, 5, 2); const plainDateTime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); -const plainTime = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); const plainMonthDay = new Temporal.PlainMonthDay(5, 2); const plainYearMonth = new Temporal.PlainYearMonth(2000, 5); const zonedDateTime = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); -[plainDate, plainDateTime, plainTime, plainMonthDay, plainYearMonth, zonedDateTime].forEach((arg) => { +[plainDate, plainDateTime, plainMonthDay, plainYearMonth, zonedDateTime].forEach((arg) => { const actual = []; const expected = []; @@ -33,7 +32,7 @@ const zonedDateTime = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UT }); const result = new Temporal.PlainYearMonth(2000, 5, arg, 1); - assert.sameValue(result.calendar, calendar, "Temporal object coerced to calendar"); + assert.sameValue(result.getISOFields().calendar, calendar, "Temporal object coerced to calendar"); assert.compareArray(actual, expected, "calendar getter not called"); }); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/calendar-undefined.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/calendar-undefined.js index 457e63241824..d08947cec880 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/calendar-undefined.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/calendar-undefined.js @@ -16,7 +16,7 @@ Object.defineProperty(Temporal.Calendar, "from", { }); const dateExplicit = new Temporal.PlainYearMonth(...args, undefined); -assert.sameValue(dateExplicit.calendar.toString(), "iso8601"); +assert.sameValue(dateExplicit.calendarId, "iso8601"); const dateImplicit = new Temporal.PlainYearMonth(...args); -assert.sameValue(dateImplicit.calendar.toString(), "iso8601"); +assert.sameValue(dateImplicit.calendarId, "iso8601"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/calendar-wrong-type.js index 3ca821d0b5c6..0df4de7aeec0 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/calendar-wrong-type.js @@ -23,6 +23,9 @@ for (const [arg, description] of rangeErrorTests) { const typeErrorTests = [ [Symbol(), "symbol"], + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], ]; for (const [arg, description] of typeErrorTests) { diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/compare/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/compare/argument-propertybag-calendar-case-insensitive.js index 0fe7e6675e7d..b6390fa434c9 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/compare/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/compare/argument-propertybag-calendar-case-insensitive.js @@ -9,14 +9,8 @@ features: [Temporal] const calendar = "IsO8601"; -let arg = { year: 2019, monthCode: "M06", calendar }; +const arg = { year: 2019, monthCode: "M06", calendar }; const result1 = Temporal.PlainYearMonth.compare(arg, new Temporal.PlainYearMonth(2019, 6)); assert.sameValue(result1, 0, "Calendar is case-insensitive (first argument)"); const result2 = Temporal.PlainYearMonth.compare(new Temporal.PlainYearMonth(2019, 6), arg); assert.sameValue(result2, 0, "Calendar is case-insensitive (second argument)"); - -arg = { year: 2019, monthCode: "M06", calendar: { calendar } }; -const result3 = Temporal.PlainYearMonth.compare(arg, new Temporal.PlainYearMonth(2019, 6)); -assert.sameValue(result3, 0, "Calendar is case-insensitive (nested property, first argument)"); -const result4 = Temporal.PlainYearMonth.compare(new Temporal.PlainYearMonth(2019, 6), arg); -assert.sameValue(result4, 0, "Calendar is case-insensitive (nested property, second argument)"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/compare/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/compare/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 2fd2387b2edd..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/compare/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,20 +0,0 @@ -// 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.compare -description: > - A Temporal.Calendar instance passed to compare() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -const arg = { year: 2019, monthCode: "M06", calendar }; -Temporal.PlainYearMonth.compare(arg, arg); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/compare/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/compare/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..63ac224db2cb --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/compare/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,24 @@ +// 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.compare +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const calendar = "2016-12-31T23:59:60"; + +const arg = { year: 2019, monthCode: "M06", calendar }; +const result1 = Temporal.PlainYearMonth.compare(arg, new Temporal.PlainYearMonth(2019, 6)); +assert.sameValue( + result1, + 0, + "leap second is a valid ISO string for calendar (first argument)" +); +const result2 = Temporal.PlainYearMonth.compare(new Temporal.PlainYearMonth(2019, 6), arg); +assert.sameValue( + result2, + 0, + "leap second is a valid ISO string for calendar (second argument)" +); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/compare/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/compare/argument-propertybag-calendar-number.js index e153ce98fc50..cfa815ea4811 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/compare/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/compare/argument-propertybag-calendar-number.js @@ -9,18 +9,12 @@ features: [Temporal] const calendar = 19970327; -let arg = { year: 2019, monthCode: "M06", calendar }; +const arg = { year: 2019, monthCode: "M06", calendar }; const result1 = Temporal.PlainYearMonth.compare(arg, new Temporal.PlainYearMonth(2019, 6)); assert.sameValue(result1, 0, "19970327 is a valid ISO string for calendar (first argument)"); const result2 = Temporal.PlainYearMonth.compare(new Temporal.PlainYearMonth(2019, 6), arg); assert.sameValue(result2, 0, "19970327 is a valid ISO string for calendar (second argument)"); -arg = { year: 2019, monthCode: "M06", calendar: { calendar } }; -const result3 = Temporal.PlainYearMonth.compare(arg, new Temporal.PlainYearMonth(2019, 6)); -assert.sameValue(result3, 0, "19970327 is a valid ISO string for calendar (nested property, first argument)"); -const result4 = Temporal.PlainYearMonth.compare(new Temporal.PlainYearMonth(2019, 6), arg); -assert.sameValue(result4, 0, "19970327 is a valid ISO string for calendar (nested property, second argument)"); - const numbers = [ 1, -19970327, @@ -28,7 +22,7 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 2019, monthCode: "M06", calendar }; + const arg = { year: 2019, monthCode: "M06", calendar }; assert.throws( RangeError, () => Temporal.PlainYearMonth.compare(arg, new Temporal.PlainYearMonth(2019, 6)), @@ -39,15 +33,4 @@ for (const calendar of numbers) { () => Temporal.PlainYearMonth.compare(new Temporal.PlainYearMonth(2019, 6), arg), `Number ${calendar} does not convert to a valid ISO string for calendar (second argument)` ); - arg = { year: 2019, monthCode: "M06", calendar: { calendar } }; - assert.throws( - RangeError, - () => Temporal.PlainYearMonth.compare(arg, new Temporal.PlainYearMonth(2019, 6)), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property, first argument)` - ); - assert.throws( - RangeError, - () => Temporal.PlainYearMonth.compare(new Temporal.PlainYearMonth(2019, 6), arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property, second argument)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/compare/argument-propertybag-calendar-string.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/compare/argument-propertybag-calendar-string.js index c6c04f6c6e1c..cabd39954829 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/compare/argument-propertybag-calendar-string.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/compare/argument-propertybag-calendar-string.js @@ -4,9 +4,19 @@ /*--- esid: sec-temporal.plainyearmonth.compare description: A calendar ID is valid input for Calendar +includes: [temporalHelpers.js] features: [Temporal] ---*/ +const dateFromFieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dateFromFields"); +Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("dateFromFields should not be looked up"); + }, +}); + const calendar = "iso8601"; const arg = { year: 2019, monthCode: "M06", calendar }; @@ -16,3 +26,5 @@ assert.sameValue(result1, 0, `Calendar created from string "${arg}" (first argum const result2 = Temporal.PlainYearMonth.compare(new Temporal.PlainYearMonth(2019, 6), arg); assert.sameValue(result2, 0, `Calendar created from string "${arg}" (second argument)`); + +Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", dateFromFieldsOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/compare/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/compare/argument-propertybag-calendar-wrong-type.js index 778fd527425d..5d405acc5020 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/compare/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/compare/argument-propertybag-calendar-wrong-type.js @@ -15,36 +15,24 @@ const rangeErrorTests = [ ["", "empty string"], [1, "number that doesn't convert to a valid ISO string"], [1n, "bigint"], - [new Temporal.TimeZone("UTC"), "time zone instance"], ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => Temporal.PlainYearMonth.compare(arg, new Temporal.PlainYearMonth(2019, 6)), `${description} does not convert to a valid ISO string (first argument)`); assert.throws(RangeError, () => Temporal.PlainYearMonth.compare(new Temporal.PlainYearMonth(2019, 6), arg), `${description} does not convert to a valid ISO string (second argument)`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => Temporal.PlainYearMonth.compare(arg, new Temporal.PlainYearMonth(2019, 6)), `${description} does not convert to a valid ISO string (nested property, first argument)`); - assert.throws(RangeError, () => Temporal.PlainYearMonth.compare(new Temporal.PlainYearMonth(2019, 6), arg), `${description} does not convert to a valid ISO string (nested property, second argument)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => Temporal.PlainYearMonth.compare(arg, new Temporal.PlainYearMonth(2019, 6)), `${description} is not a valid property bag and does not convert to a string (first argument)`); assert.throws(TypeError, () => Temporal.PlainYearMonth.compare(new Temporal.PlainYearMonth(2019, 6), arg), `${description} is not a valid property bag and does not convert to a string (second argument)`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => Temporal.PlainYearMonth.compare(arg, new Temporal.PlainYearMonth(2019, 6)), `${description} is not a valid property bag and does not convert to a string (nested property, first argument)`); - assert.throws(TypeError, () => Temporal.PlainYearMonth.compare(new Temporal.PlainYearMonth(2019, 6), arg), `${description} is not a valid property bag and does not convert to a string (nested property, second argument)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => Temporal.PlainYearMonth.compare(arg, new Temporal.PlainYearMonth(2019, 6)), `nested undefined calendar property is always a RangeError (first argument)`); -assert.throws(RangeError, () => Temporal.PlainYearMonth.compare(new Temporal.PlainYearMonth(2019, 6), arg), `nested undefined calendar property is always a RangeError (second argument)`); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/compare/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/compare/argument-string-calendar-annotation.js index ca15d7067df5..4e0d4b9eddc8 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/compare/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/compare/argument-string-calendar-annotation.js @@ -13,7 +13,6 @@ const tests = [ ["2019-12-15T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["2019-12-15T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["2019-12-15T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["2019-12-15T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; tests.forEach(([arg, description]) => { diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/compare/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/compare/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..be8ea1019ab7 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/compare/argument-string-multiple-calendar.js @@ -0,0 +1,34 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.compare +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; + +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => Temporal.PlainYearMonth.compare(arg, new Temporal.PlainYearMonth(2019, 6)), + `reject more than one calendar annotation if any critical: ${arg} (first argument)` + ); + assert.throws( + RangeError, + () => Temporal.PlainYearMonth.compare(new Temporal.PlainYearMonth(2019, 6), arg), + `reject more than one calendar annotation if any critical: ${arg} (second argument)` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/compare/calendar-yearmonthfromfields-called-with-options-undefined.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/compare/calendar-yearmonthfromfields-called-with-options-undefined.js index 999e5afa760a..6696ad2a8685 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/compare/calendar-yearmonthfromfields-called-with-options-undefined.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/compare/calendar-yearmonthfromfields-called-with-options-undefined.js @@ -13,20 +13,3 @@ features: [Temporal] const calendar = TemporalHelpers.calendarFromFieldsUndefinedOptions(); Temporal.PlainYearMonth.compare({ year: 2000, month: 5, calendar }, { year: 2000, month: 6, calendar }); assert.sameValue(calendar.yearMonthFromFieldsCallCount, 2); - -// Test again, but overriding the global Temporal.Calendar.prototype method so -// we can observe the call to yearMonthFromFields() on the ISO8601 calendar -// that occurs when we parse the string - -const realYearMonthFromFields = Temporal.Calendar.prototype.yearMonthFromFields; -let yearMonthFromFieldsCallCount = 0; -Temporal.Calendar.prototype.yearMonthFromFields = function (fields, options) { - yearMonthFromFieldsCallCount++; - assert.sameValue(options, undefined, "yearMonthFromFields shouldn't be called with options"); - return realYearMonthFromFields.call(this, fields, options); -} - -Temporal.PlainYearMonth.compare("2000-05-01", "2000-06-01"); -assert.sameValue(yearMonthFromFieldsCallCount, 2); - -Temporal.Calendar.prototype.yearMonthFromFields = realYearMonthFromFields; diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-plaindate.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-plaindate.js index e423a148e854..9923c808ebc1 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-plaindate.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-plaindate.js @@ -12,7 +12,7 @@ const plainDate = Temporal.PlainDate.from("1976-11-18"); const plainYearMonth = Temporal.PlainYearMonth.from(plainDate); TemporalHelpers.assertPlainYearMonth(plainYearMonth, 1976, 11, "M11"); const fields = plainYearMonth.getISOFields(); -assert.sameValue(fields.calendar.id, "iso8601"); +assert.sameValue(fields.calendar, "iso8601", "calendar slot should store a string"); assert.sameValue(fields.isoDay, 1, "isoDay"); assert.sameValue(fields.isoMonth, 11, "isoMonth"); assert.sameValue(fields.isoYear, 1976, "isoYear"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-plainyearmonth.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-plainyearmonth.js index b8196919b534..9dd8f55b377a 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-plainyearmonth.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-plainyearmonth.js @@ -18,7 +18,7 @@ TemporalHelpers.assertPlainYearMonth( /* era = */ undefined, /* eraYear = */ undefined, /* isoDay = */ 7 ); -assert.sameValue(result.calendar, orig.calendar, "Calendar is copied"); +assert.sameValue(result.getISOFields().calendar, orig.getISOFields().calendar, "Calendar is copied"); assert.notSameValue( result, diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-case-insensitive.js index 24dbb023aa8f..addc6aeef485 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-case-insensitive.js @@ -10,10 +10,6 @@ features: [Temporal] const calendar = "IsO8601"; -let arg = { year: 2019, monthCode: "M06", calendar }; -const result1 = Temporal.PlainYearMonth.from(arg); -TemporalHelpers.assertPlainYearMonth(result1, 2019, 6, "M06", "Calendar is case-insensitive"); - -arg = { year: 2019, monthCode: "M06", calendar: { calendar } }; -const result2 = Temporal.PlainYearMonth.from(arg); -TemporalHelpers.assertPlainYearMonth(result2, 2019, 6, "M06", "Calendar is case-insensitive (nested property)"); +const arg = { year: 2019, monthCode: "M06", calendar }; +const result = Temporal.PlainYearMonth.from(arg); +TemporalHelpers.assertPlainYearMonth(result, 2019, 6, "M06", "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 764b31665c43..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,23 +0,0 @@ -// 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.from -description: > - A Temporal.Calendar instance passed to from() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -let arg = { year: 2019, monthCode: "M06", calendar }; -Temporal.PlainYearMonth.from(arg); - -arg = { year: 2019, monthCode: "M06", calendar: { calendar } }; -Temporal.PlainYearMonth.from(arg); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-leap-second.js index 34160a40db06..105422ee94a6 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-leap-second.js @@ -10,18 +10,10 @@ features: [Temporal] const calendar = "2016-12-31T23:59:60"; -let arg = { year: 2019, monthCode: "M06", calendar }; -const result1 = Temporal.PlainYearMonth.from(arg); +const arg = { year: 2019, monthCode: "M06", calendar }; +const result = Temporal.PlainYearMonth.from(arg); TemporalHelpers.assertPlainYearMonth( - result1, + result, 2019, 6, "M06", "leap second is a valid ISO string for calendar" ); - -arg = { year: 2019, monthCode: "M06", calendar: { calendar } }; -const result2 = Temporal.PlainYearMonth.from(arg); -TemporalHelpers.assertPlainYearMonth( - result2, - 2019, 6, "M06", - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-number.js index ecead4225c1e..be415abf44eb 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-number.js @@ -10,13 +10,9 @@ features: [Temporal] const calendar = 19970327; -let arg = { year: 2019, monthCode: "M06", calendar }; -const result1 = Temporal.PlainYearMonth.from(arg); -TemporalHelpers.assertPlainYearMonth(result1, 2019, 6, "M06", "19970327 is a valid ISO string for calendar"); - -arg = { year: 2019, monthCode: "M06", calendar: { calendar } }; -const result2 = Temporal.PlainYearMonth.from(arg); -TemporalHelpers.assertPlainYearMonth(result2, 2019, 6, "M06", "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { year: 2019, monthCode: "M06", calendar }; +const result = Temporal.PlainYearMonth.from(arg); +TemporalHelpers.assertPlainYearMonth(result, 2019, 6, "M06", "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -25,16 +21,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 2019, monthCode: "M06", calendar }; + const arg = { year: 2019, monthCode: "M06", calendar }; assert.throws( RangeError, () => Temporal.PlainYearMonth.from(arg), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { year: 2019, monthCode: "M06", calendar: { calendar } }; - assert.throws( - RangeError, - () => Temporal.PlainYearMonth.from(arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-string.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-string.js index 4b84505e6a4a..a98c2b5567ff 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-string.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-string.js @@ -13,3 +13,4 @@ const calendar = "iso8601"; const arg = { year: 2019, monthCode: "M06", calendar }; const result = Temporal.PlainYearMonth.from(arg); TemporalHelpers.assertPlainYearMonth(result, 2019, 6, "M06", `Calendar created from string "${calendar}"`); +assert.sameValue(result.getISOFields().calendar, "iso8601", "calendar slot stores a string"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-wrong-type.js index 0419e3c42133..551c97e3ac03 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-wrong-type.js @@ -18,27 +18,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => Temporal.PlainYearMonth.from(arg), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => Temporal.PlainYearMonth.from(arg), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => Temporal.PlainYearMonth.from(arg), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => Temporal.PlainYearMonth.from(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => Temporal.PlainYearMonth.from(arg), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-string-calendar-annotation.js index c0a5c4dc2a9b..6eac644aa0e3 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-string-calendar-annotation.js @@ -14,7 +14,6 @@ const tests = [ ["2019-12-15T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["2019-12-15T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["2019-12-15T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["2019-12-15T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; tests.forEach(([arg, description]) => { diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..778e3480ca6e --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.from +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; + +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => Temporal.PlainYearMonth.from(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-string.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-string.js index 4d90936bcf0e..dc897c34ddd6 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-string.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/argument-string.js @@ -12,7 +12,7 @@ for (const input of TemporalHelpers.ISO.plainYearMonthStringsValid()) { const plainYearMonth = Temporal.PlainYearMonth.from(input); TemporalHelpers.assertPlainYearMonth(plainYearMonth, 1976, 11, "M11"); const fields = plainYearMonth.getISOFields(); - assert.sameValue(fields.calendar.id, "iso8601"); + assert.sameValue(fields.calendar, "iso8601", "calendar slot should store a string"); assert.sameValue(fields.isoDay, 1, "isoDay"); assert.sameValue(fields.isoMonth, 11, "isoMonth"); assert.sameValue(fields.isoYear, 1976, "isoYear"); @@ -22,7 +22,7 @@ for (const input of TemporalHelpers.ISO.plainYearMonthStringsValidNegativeYear() const plainYearMonth = Temporal.PlainYearMonth.from(input); TemporalHelpers.assertPlainYearMonth(plainYearMonth, -9999, 11, "M11"); const fields = plainYearMonth.getISOFields(); - assert.sameValue(fields.calendar.id, "iso8601"); + assert.sameValue(fields.calendar, "iso8601", "calendar slot should store a string"); assert.sameValue(fields.isoDay, 1, "isoDay"); assert.sameValue(fields.isoMonth, 11, "isoMonth"); assert.sameValue(fields.isoYear, -9999, "isoYear"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/calendar-temporal-object.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/calendar-temporal-object.js index f2d3897f4658..050e990a0ff8 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/calendar-temporal-object.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/calendar-temporal-object.js @@ -22,5 +22,5 @@ features: [Temporal] TemporalHelpers.checkToTemporalCalendarFastPath((temporalObject, calendar) => { const result = Temporal.PlainYearMonth.from({ year: 2000, month: 5, calendar: temporalObject }); - assert.sameValue(result.calendar, calendar, "Temporal object coerced to calendar"); + assert.sameValue(result.getCalendar(), calendar, "Temporal object coerced to calendar"); }); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/calendar-yearmonthfromfields-called-with-options-undefined.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/calendar-yearmonthfromfields-called-with-options-undefined.js deleted file mode 100644 index f3f33f1ba0f8..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/calendar-yearmonthfromfields-called-with-options-undefined.js +++ /dev/null @@ -1,23 +0,0 @@ -// 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.from -description: > - Calendar.yearMonthFromFields method is called with undefined as the options - value when call originates internally -features: [Temporal] ----*/ - -const realYearMonthFromFields = Temporal.Calendar.prototype.yearMonthFromFields; -let yearMonthFromFieldsCallCount = 0; -Temporal.Calendar.prototype.yearMonthFromFields = function (fields, options) { - yearMonthFromFieldsCallCount++; - assert.sameValue(options, undefined, "yearMonthFromFields shouldn't be called with options"); - return realYearMonthFromFields.call(this, fields, options); -} - -Temporal.PlainYearMonth.from("2000-05-01"); -assert.sameValue(yearMonthFromFieldsCallCount, 1); - -Temporal.Calendar.prototype.yearMonthFromFields = realYearMonthFromFields; diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/order-of-operations.js index 2ae9926967b8..a641a5786cf6 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/from/order-of-operations.js @@ -9,9 +9,29 @@ features: [Temporal] ---*/ const expected = [ - // GetTemporalCalendarWithISODefault + // GetTemporalCalendarSlotValueWithISODefault "get fields.calendar", - "has fields.calendar.calendar", + "has fields.calendar.dateAdd", + "has fields.calendar.dateFromFields", + "has fields.calendar.dateUntil", + "has fields.calendar.day", + "has fields.calendar.dayOfWeek", + "has fields.calendar.dayOfYear", + "has fields.calendar.daysInMonth", + "has fields.calendar.daysInWeek", + "has fields.calendar.daysInYear", + "has fields.calendar.fields", + "has fields.calendar.id", + "has fields.calendar.inLeapYear", + "has fields.calendar.mergeFields", + "has fields.calendar.month", + "has fields.calendar.monthCode", + "has fields.calendar.monthDayFromFields", + "has fields.calendar.monthsInYear", + "has fields.calendar.weekOfYear", + "has fields.calendar.year", + "has fields.calendar.yearMonthFromFields", + "has fields.calendar.yearOfWeek", // CalendarFields "get fields.calendar.fields", "call fields.calendar.fields", diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/add/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/add/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..b6058315ed6f --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/add/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.add +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const dateAddOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dateAdd"); +Object.defineProperty(Temporal.Calendar.prototype, "dateAdd", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("dateAdd should not be looked up"); + }, +}); + +const instance = new Temporal.PlainYearMonth(2000, 5, "iso8601", 1); +instance.add(new Temporal.Duration(1)); + +Object.defineProperty(Temporal.Calendar.prototype, "dateAdd", dateAddOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/add/calendar-dateadd-called-with-plaindate-instance.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/add/calendar-dateadd-called-with-plaindate-instance.js new file mode 100644 index 000000000000..a8dd88ce0717 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/add/calendar-dateadd-called-with-plaindate-instance.js @@ -0,0 +1,18 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.add +description: Duration addition to PlainYearMonth calls Calendar.dateAdd the right number of times +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = TemporalHelpers.calendarDateAddPlainDateInstance(); +const instance = new Temporal.PlainYearMonth(1983, 3, calendar); +TemporalHelpers.assertPlainYearMonth(instance.add({days: 31}), 1983, 4, 'M04', "Adding 31 days to march in is8601 calendar") +assert.sameValue(calendar.dateAddCallCount, 1, "dateAdd called once with positive add"); + +calendar.dateAddCallCount = 0; +TemporalHelpers.assertPlainYearMonth(instance.add({days: -31}), 1983, 2, 'M02', "Adding -31 days to march in is8601 calendar") +assert.sameValue(calendar.dateAddCallCount, 3, "dateAdd called 3 times with negative add"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/add/calendar-datefromfields-called.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/add/calendar-datefromfields-called.js index 356c59a60d62..07b5c6b115bc 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/add/calendar-datefromfields-called.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/add/calendar-datefromfields-called.js @@ -77,8 +77,13 @@ class CustomCalendar extends Temporal.Calendar { return new Temporal.PlainMonthDay(isoMonth, isoDay, this, isoYear); } dateAdd(date, duration, options) { - if (duration.months) throw new Error("adding months not implemented in this test"); - return super.dateAdd(date, duration, options); + const {isoYear, isoMonth, isoDay} = date.getISOFields(); + let {years, months, weeks, days} = duration; + let iter = new Temporal.PlainDate(isoYear + years, isoMonth, isoDay, "iso8601"); + const monthsDays = months * 36; + if (iter.dayOfYear + monthsDays > iter.daysInYear || iter.dayOfYear + monthsDays < 1) + throw new Error("complicated addition not implemented in this test"); + return iter.add({ weeks, days: monthsDays + days }).withCalendar(this); } toString() { return "thirty-six"; @@ -132,9 +137,9 @@ TemporalHelpers.assertPlainYearMonth( "adding negative less than one month's worth of days yields the same month", /* era = */ undefined, /* eraYear = */ undefined, /* referenceISODay = */ 6 ); -assert.sameValue(calendar.dateFromFieldsCalls.length, 1, "dateFromFields was called"); +assert.sameValue(calendar.dateFromFieldsCalls.length, 2, "dateFromFields was called twice"); assert.deepEqual( - calendar.dateFromFieldsCalls[0][0], + calendar.dateFromFieldsCalls[1][0], { year: 2022, monthCode: "M02", day: 36 }, "last day of month 2 passed to dateFromFields when adding negative duration" ); @@ -147,9 +152,9 @@ TemporalHelpers.assertPlainYearMonth( "adding negative one month's worth of days yields the previous month", /* era = */ undefined, /* eraYear = */ undefined, /* referenceISODay = */ 1 ); -assert.sameValue(calendar.dateFromFieldsCalls.length, 1, "dateFromFields was called"); +assert.sameValue(calendar.dateFromFieldsCalls.length, 2, "dateFromFields was called twice"); assert.deepEqual( - calendar.dateFromFieldsCalls[0][0], + calendar.dateFromFieldsCalls[1][0], { year: 2022, monthCode: "M02", day: 36 }, "last day of month 2 passed to dateFromFields when adding negative duration" ); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/add/calendar-daysinmonth-wrong-value.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/add/calendar-daysinmonth-wrong-value.js deleted file mode 100644 index d44cd9105be9..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/add/calendar-daysinmonth-wrong-value.js +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.plainyearmonth.prototype.add -description: > - The appropriate error is thrown if the calendar's daysInMonth method returns a - value that cannot be converted to a positive integer -includes: [compareArray.js] -features: [BigInt, Symbol, Temporal] ----*/ - -const actual = []; -class CalendarDaysInMonthWrongValue extends Temporal.Calendar { - constructor(badValue) { - super("iso8601"); - this._badValue = badValue; - } - dateFromFields(fields, options) { - actual.push("call dateFromFields"); - return super.dateFromFields(fields, options); - } - daysInMonth() { - return this._badValue; - } -} -// daysInMonth is only called if we are adding a negative duration -const duration = new Temporal.Duration(-1, -1); - -[Infinity, -Infinity, -42].forEach((badValue) => { - const calendar = new CalendarDaysInMonthWrongValue(badValue); - const yearMonth = new Temporal.PlainYearMonth(2000, 5, calendar); - assert.throws(RangeError, () => yearMonth.add(duration), `daysInMonth ${badValue}`); - assert.compareArray(actual, [], "dateFromFields not called"); -}); - -[Symbol('foo'), 31n].forEach((badValue) => { - const calendar = new CalendarDaysInMonthWrongValue(badValue); - const yearMonth = new Temporal.PlainYearMonth(2000, 5, calendar); - assert.throws(TypeError, () => yearMonth.add(duration), `daysInMonth ${typeof badValue}`); - assert.compareArray(actual, [], "dateFromFields not called"); -}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/add/custom-daysInMonth-irrelevant.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/add/custom-daysInMonth-irrelevant.js new file mode 100644 index 000000000000..e1834e58b5cd --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/add/custom-daysInMonth-irrelevant.js @@ -0,0 +1,23 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.add +description: Addition of a negative duration to a PlainYearMonth is not influenced by the implementation of daysInMonth() +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +class CustomCalendar extends Temporal.Calendar { + constructor() { + super("iso8601"); + } + daysInMonth(ym, ...args) { + return 15; + } +} + +const customCalendar = new CustomCalendar(); +const instance = new Temporal.PlainYearMonth(2023, 3, customCalendar); + +TemporalHelpers.assertPlainYearMonth(instance.add({days: -30}), 2023, 3, 'M03', "Adding -30 days from calendar reimplementing daysinMonth()") diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/add/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/add/order-of-operations.js index 97b5206a5426..cdb987195846 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/add/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/add/order-of-operations.js @@ -51,12 +51,12 @@ const expected = [ // CalendarDateFromFields "get this.calendar.dateFromFields", "call this.calendar.dateFromFields", + "get this.calendar.dateAdd", // CopyDataProperties "ownKeys options", "getOwnPropertyDescriptor options.overflow", "get options.overflow", // CalendarDateAdd - "get this.calendar.dateAdd", "call this.calendar.dateAdd", // inside Calendar.p.dateAdd "get options.overflow", diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/calendar/branding.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/calendar/branding.js deleted file mode 100644 index 4235571465ac..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/calendar/branding.js +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-get-temporal.plainyearmonth.prototype.calendar -description: Throw a TypeError if the receiver is invalid -features: [Symbol, Temporal] ----*/ - -const calendar = Object.getOwnPropertyDescriptor(Temporal.PlainYearMonth.prototype, "calendar").get; - -assert.sameValue(typeof calendar, "function"); - -assert.throws(TypeError, () => calendar.call(undefined), "undefined"); -assert.throws(TypeError, () => calendar.call(null), "null"); -assert.throws(TypeError, () => calendar.call(true), "true"); -assert.throws(TypeError, () => calendar.call(""), "empty string"); -assert.throws(TypeError, () => calendar.call(Symbol()), "symbol"); -assert.throws(TypeError, () => calendar.call(1), "1"); -assert.throws(TypeError, () => calendar.call({}), "plain object"); -assert.throws(TypeError, () => calendar.call(Temporal.PlainYearMonth), "Temporal.PlainYearMonth"); -assert.throws(TypeError, () => calendar.call(Temporal.PlainYearMonth.prototype), "Temporal.PlainYearMonth.prototype"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/calendar/prop-desc.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/calendar/prop-desc.js deleted file mode 100644 index 2a0eacf082eb..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/calendar/prop-desc.js +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-get-temporal.plainyearmonth.prototype.calendar -description: The "calendar" property of Temporal.PlainYearMonth.prototype -features: [Temporal] ----*/ - -const descriptor = Object.getOwnPropertyDescriptor(Temporal.PlainYearMonth.prototype, "calendar"); -assert.sameValue(typeof descriptor.get, "function"); -assert.sameValue(descriptor.set, undefined); -assert.sameValue(descriptor.enumerable, false); -assert.sameValue(descriptor.configurable, true); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/calendarId/branding.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/calendarId/branding.js new file mode 100644 index 000000000000..5bad236cb316 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/calendarId/branding.js @@ -0,0 +1,22 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-get-temporal.plainyearmonth.prototype.calendarid +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const calendarId = Object.getOwnPropertyDescriptor(Temporal.PlainYearMonth.prototype, "calendarId").get; + +assert.sameValue(typeof calendarId, "function"); + +assert.throws(TypeError, () => calendarId.call(undefined), "undefined"); +assert.throws(TypeError, () => calendarId.call(null), "null"); +assert.throws(TypeError, () => calendarId.call(true), "true"); +assert.throws(TypeError, () => calendarId.call(""), "empty string"); +assert.throws(TypeError, () => calendarId.call(Symbol()), "symbol"); +assert.throws(TypeError, () => calendarId.call(1), "1"); +assert.throws(TypeError, () => calendarId.call({}), "plain object"); +assert.throws(TypeError, () => calendarId.call(Temporal.PlainYearMonth), "Temporal.PlainYearMonth"); +assert.throws(TypeError, () => calendarId.call(Temporal.PlainYearMonth.prototype), "Temporal.PlainYearMonth.prototype"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/calendarId/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/calendarId/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..ab0323f1befa --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/calendarId/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.calendarid +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const idOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "id"); +Object.defineProperty(Temporal.Calendar.prototype, "id", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("id should not be looked up"); + }, +}); + +const instance = new Temporal.PlainYearMonth(2000, 5, "iso8601", 1); +instance.calendarId; + +Object.defineProperty(Temporal.Calendar.prototype, "id", idOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/calendarId/prop-desc.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/calendarId/prop-desc.js new file mode 100644 index 000000000000..b0ef8d7b0852 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/calendarId/prop-desc.js @@ -0,0 +1,14 @@ +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-get-temporal.plainyearmonth.prototype.calendarid +description: The "calendarId" property of Temporal.PlainYearMonth.prototype +features: [Temporal] +---*/ + +const descriptor = Object.getOwnPropertyDescriptor(Temporal.PlainYearMonth.prototype, "calendarId"); +assert.sameValue(typeof descriptor.get, "function"); +assert.sameValue(descriptor.set, undefined); +assert.sameValue(descriptor.enumerable, false); +assert.sameValue(descriptor.configurable, true); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/daysInMonth/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/daysInMonth/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..516cffbb41ca --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/daysInMonth/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.daysinmonth +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const daysInMonthOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "daysInMonth"); +Object.defineProperty(Temporal.Calendar.prototype, "daysInMonth", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("daysInMonth should not be looked up"); + }, +}); + +const instance = new Temporal.PlainYearMonth(2000, 5, "iso8601", 1); +instance.daysInMonth; + +Object.defineProperty(Temporal.Calendar.prototype, "daysInMonth", daysInMonthOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/daysInYear/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/daysInYear/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..87c59cd9a018 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/daysInYear/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.daysinyear +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const daysInYearOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "daysInYear"); +Object.defineProperty(Temporal.Calendar.prototype, "daysInYear", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("daysInYear should not be looked up"); + }, +}); + +const instance = new Temporal.PlainYearMonth(2000, 5, "iso8601", 1); +instance.daysInYear; + +Object.defineProperty(Temporal.Calendar.prototype, "daysInYear", daysInYearOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-case-insensitive.js index ccfa48c26003..2d7bedf2f3be 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-case-insensitive.js @@ -11,10 +11,6 @@ const instance = new Temporal.PlainYearMonth(2019, 6); const calendar = "IsO8601"; -let arg = { year: 2019, monthCode: "M06", calendar }; -const result1 = instance.equals(arg); -assert.sameValue(result1, true, "Calendar is case-insensitive"); - -arg = { year: 2019, monthCode: "M06", calendar: { calendar } }; -const result2 = instance.equals(arg); -assert.sameValue(result2, true, "Calendar is case-insensitive (nested property)"); +const arg = { year: 2019, monthCode: "M06", calendar }; +const result = instance.equals(arg); +assert.sameValue(result, true, "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index e8c4790ca556..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,25 +0,0 @@ -// 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.equals -description: > - A Temporal.Calendar instance passed to equals() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.PlainYearMonth(2019, 6); - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -let arg = { year: 2019, monthCode: "M06", calendar }; -instance.equals(arg); - -arg = { year: 2019, monthCode: "M06", calendar: { calendar } }; -instance.equals(arg); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-leap-second.js index 3d446c778980..9ede1f97a8e5 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-leap-second.js @@ -11,18 +11,10 @@ const instance = new Temporal.PlainYearMonth(2019, 6); const calendar = "2016-12-31T23:59:60"; -let arg = { year: 2019, monthCode: "M06", calendar }; -const result1 = instance.equals(arg); +const arg = { year: 2019, monthCode: "M06", calendar }; +const result = instance.equals(arg); assert.sameValue( - result1, + result, true, "leap second is a valid ISO string for calendar" ); - -arg = { year: 2019, monthCode: "M06", calendar: { calendar } }; -const result2 = instance.equals(arg); -assert.sameValue( - result2, - true, - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-number.js index cd1ea7b30d31..4e979abcd26f 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-number.js @@ -11,13 +11,9 @@ const instance = new Temporal.PlainYearMonth(2019, 6); const calendar = 19970327; -let arg = { year: 2019, monthCode: "M06", calendar }; -const result1 = instance.equals(arg); -assert.sameValue(result1, true, "19970327 is a valid ISO string for calendar"); - -arg = { year: 2019, monthCode: "M06", calendar: { calendar } }; -const result2 = instance.equals(arg); -assert.sameValue(result2, true, "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { year: 2019, monthCode: "M06", calendar }; +const result = instance.equals(arg); +assert.sameValue(result, true, "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -26,16 +22,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 2019, monthCode: "M06", calendar }; + const arg = { year: 2019, monthCode: "M06", calendar }; assert.throws( RangeError, () => instance.equals(arg), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { year: 2019, monthCode: "M06", calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.equals(arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-wrong-type.js index 137b9ffdbeb4..4448cd36f839 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-wrong-type.js @@ -21,27 +21,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.equals(arg), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.equals(arg), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.equals(arg), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.equals(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.equals(arg), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-string-calendar-annotation.js index e94d368392d6..09ee7e189a63 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-string-calendar-annotation.js @@ -13,7 +13,6 @@ const tests = [ ["2019-12-15T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["2019-12-15T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["2019-12-15T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["2019-12-15T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const instance = new Temporal.PlainYearMonth(2019, 12); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..f645286cf6aa --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.equals +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.PlainYearMonth(2000, 5); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.equals(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/equals/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/equals/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..2bd1798fd436 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/equals/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.equals +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const idOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "id"); +Object.defineProperty(Temporal.Calendar.prototype, "id", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("id should not be looked up"); + }, +}); + +const instance = new Temporal.PlainYearMonth(2000, 5, "iso8601", 1); +instance.equals(new Temporal.PlainYearMonth(2000, 5)); + +Object.defineProperty(Temporal.Calendar.prototype, "id", idOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/equals/calendar-yearmonthfromfields-called-with-options-undefined.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/equals/calendar-yearmonthfromfields-called-with-options-undefined.js index 490c35f49390..b69dc74fe575 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/equals/calendar-yearmonthfromfields-called-with-options-undefined.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/equals/calendar-yearmonthfromfields-called-with-options-undefined.js @@ -14,22 +14,3 @@ let calendar = TemporalHelpers.calendarFromFieldsUndefinedOptions(); let instance = new Temporal.PlainYearMonth(2000, 5, calendar); instance.equals({ year: 2000, month: 6, calendar }); assert.sameValue(calendar.yearMonthFromFieldsCallCount, 1); - -// Test again, but overriding the global Temporal.Calendar.prototype method so -// we can observe the call to yearMonthFromFields() on the ISO8601 calendar -// that occurs when we parse the string - -const realYearMonthFromFields = Temporal.Calendar.prototype.yearMonthFromFields; -let yearMonthFromFieldsCallCount = 0; -Temporal.Calendar.prototype.yearMonthFromFields = function (fields, options) { - yearMonthFromFieldsCallCount++; - assert.sameValue(options, undefined, "yearMonthFromFields shouldn't be called with options"); - return realYearMonthFromFields.call(this, fields, options); -} - -calendar = new Temporal.Calendar("iso8601"); -instance = new Temporal.PlainYearMonth(2000, 5, calendar); -instance.equals("2000-06-01"); -assert.sameValue(yearMonthFromFieldsCallCount, 1); - -Temporal.Calendar.prototype.yearMonthFromFields = realYearMonthFromFields; diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/equals/compare-calendar.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/equals/compare-calendar.js index b7bf5dc96824..90244edacac7 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/equals/compare-calendar.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/equals/compare-calendar.js @@ -4,7 +4,7 @@ /*--- esid: sec-temporal.plainyearmonth.prototype.equals description: equals() takes the calendar into account -includes: [compareArray.js] +includes: [compareArray.js, temporalHelpers.js] features: [Temporal] ---*/ @@ -14,10 +14,13 @@ class CustomCalendar extends Temporal.Calendar { super("iso8601"); this._id = id; } - toString() { + get id() { actual.push(this._id); return this._id; } + toString() { + TemporalHelpers.assertUnreachable("should not call toString"); + } } const sharedCalendar = new CustomCalendar("a"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/getCalendar/branding.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/getCalendar/branding.js new file mode 100644 index 000000000000..86293ae25009 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/getCalendar/branding.js @@ -0,0 +1,22 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.getcalendar +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const getCalendar = Temporal.PlainYearMonth.prototype.getCalendar; + +assert.sameValue(typeof getCalendar, "function"); + +assert.throws(TypeError, () => getCalendar.call(undefined), "undefined"); +assert.throws(TypeError, () => getCalendar.call(null), "null"); +assert.throws(TypeError, () => getCalendar.call(true), "true"); +assert.throws(TypeError, () => getCalendar.call(""), "empty string"); +assert.throws(TypeError, () => getCalendar.call(Symbol()), "symbol"); +assert.throws(TypeError, () => getCalendar.call(1), "1"); +assert.throws(TypeError, () => getCalendar.call({}), "plain object"); +assert.throws(TypeError, () => getCalendar.call(Temporal.PlainYearMonth), "Temporal.PlainYearMonth"); +assert.throws(TypeError, () => getCalendar.call(Temporal.PlainYearMonth.prototype), "Temporal.PlainYearMonth.prototype"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/getCalendar/builtin.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/getCalendar/builtin.js new file mode 100644 index 000000000000..a83fbdabe30c --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/getCalendar/builtin.js @@ -0,0 +1,33 @@ +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.getcalendar +description: > + Tests that Temporal.PlainYearMonth.prototype.getCalendar + meets the requirements for built-in objects defined by the + introduction of chapter 17 of the ECMAScript Language Specification. +info: | + Built-in functions that are not constructors do not have a "prototype" property unless + otherwise specified in the description of a particular function. + + Unless specified otherwise, a built-in object that is callable as a function is a built-in + function object with the characteristics described in 10.3. Unless specified otherwise, the + [[Extensible]] internal slot of a built-in object initially has the value true. + + Unless otherwise specified every built-in function and every built-in constructor has the + Function prototype object [...] as the value of its [[Prototype]] internal slot. +features: [Temporal] +---*/ + +assert.sameValue(Object.isExtensible(Temporal.PlainYearMonth.prototype.getCalendar), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.PlainYearMonth.prototype.getCalendar), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.PlainYearMonth.prototype.getCalendar), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.PlainYearMonth.prototype.getCalendar.hasOwnProperty("prototype"), + false, "prototype property"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/getCalendar/length.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/getCalendar/length.js new file mode 100644 index 000000000000..3105dd5b7e76 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/getCalendar/length.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.getcalendar +description: Temporal.PlainYearMonth.prototype.getCalendar.length is 0 +info: | + Every built-in function object, including constructors, has a "length" property whose value is + an integer. Unless otherwise specified, this value is equal to the largest number of named + arguments shown in the subclause headings for the function description. Optional parameters + (which are indicated with brackets: [ ]) or rest parameters (which are shown using the form + «...name») are not included in the default argument count. + + Unless otherwise specified, the "length" property of a built-in function object has the + attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +verifyProperty(Temporal.PlainYearMonth.prototype.getCalendar, "length", { + value: 0, + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/getCalendar/name.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/getCalendar/name.js new file mode 100644 index 000000000000..f12a2525d752 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/getCalendar/name.js @@ -0,0 +1,23 @@ +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.getcalendar +description: Temporal.PlainYearMonth.prototype.getCalendar.name is "getCalendar". +info: | + Every built-in function object, including constructors, that is not identified as an anonymous + function has a "name" property whose value is a String. Unless otherwise specified, this value + is the name that is given to the function in this specification. + + Unless otherwise specified, the "name" property of a built-in function object, if it exists, + has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +verifyProperty(Temporal.PlainYearMonth.prototype.getCalendar, "name", { + value: "getCalendar", + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/getCalendar/not-a-constructor.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/getCalendar/not-a-constructor.js new file mode 100644 index 000000000000..a5fd3b5306a2 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/getCalendar/not-a-constructor.js @@ -0,0 +1,21 @@ +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.getcalendar +description: > + Temporal.PlainYearMonth.prototype.getCalendar does not implement [[Construct]], is not new-able +info: | + Built-in function objects that are not identified as constructors do not implement the + [[Construct]] internal method unless otherwise specified in the description of a particular + function. +includes: [isConstructor.js] +features: [Reflect.construct, Temporal] +---*/ + +assert.throws(TypeError, () => { + new Temporal.PlainYearMonth.prototype.getCalendar(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.PlainYearMonth.prototype.getCalendar), false, + "isConstructor(Temporal.PlainYearMonth.prototype.getCalendar)"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/getCalendar/prop-desc.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/getCalendar/prop-desc.js new file mode 100644 index 000000000000..7a2db16e2cfd --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/getCalendar/prop-desc.js @@ -0,0 +1,21 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.getcalendar +description: The "getCalendar" property of Temporal.PlainYearMonth.prototype +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.PlainYearMonth.prototype.getCalendar, + "function", + "`typeof PlainYearMonth.prototype.getCalendar` is `function`" +); + +verifyProperty(Temporal.PlainYearMonth.prototype, "getCalendar", { + writable: true, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/getISOFields/field-names.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/getISOFields/field-names.js index 631c02891d69..9684bb591e26 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/getISOFields/field-names.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/getISOFields/field-names.js @@ -13,4 +13,4 @@ const result = ym.getISOFields(); assert.sameValue(result.isoYear, 2000, "isoYear result"); assert.sameValue(result.isoMonth, 5, "isoMonth result"); assert.sameValue(result.isoDay, 1, "isoDay result"); -assert.sameValue(result.calendar.id, "iso8601", "calendar result"); +assert.sameValue(result.calendar, "iso8601", "calendar result"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/inLeapYear/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/inLeapYear/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..a7e7f1444103 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/inLeapYear/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.inleapyear +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const inLeapYearOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "inLeapYear"); +Object.defineProperty(Temporal.Calendar.prototype, "inLeapYear", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("inLeapYear should not be looked up"); + }, +}); + +const instance = new Temporal.PlainYearMonth(2000, 5, "iso8601", 1); +instance.inLeapYear; + +Object.defineProperty(Temporal.Calendar.prototype, "inLeapYear", inLeapYearOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/month/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/month/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..d89b08518272 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/month/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.month +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const monthOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "month"); +Object.defineProperty(Temporal.Calendar.prototype, "month", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("month should not be looked up"); + }, +}); + +const instance = new Temporal.PlainYearMonth(2000, 5, "iso8601", 1); +instance.month; + +Object.defineProperty(Temporal.Calendar.prototype, "month", monthOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/monthCode/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/monthCode/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..0961724c40c4 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/monthCode/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.monthcode +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const monthCodeOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "monthCode"); +Object.defineProperty(Temporal.Calendar.prototype, "monthCode", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("monthCode should not be looked up"); + }, +}); + +const instance = new Temporal.PlainYearMonth(2000, 5, "iso8601", 1); +instance.monthCode; + +Object.defineProperty(Temporal.Calendar.prototype, "monthCode", monthCodeOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/monthsInYear/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/monthsInYear/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..afbc4769079f --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/monthsInYear/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.monthsinyear +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const monthsInYearOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "monthsInYear"); +Object.defineProperty(Temporal.Calendar.prototype, "monthsInYear", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("monthsInYear should not be looked up"); + }, +}); + +const instance = new Temporal.PlainYearMonth(2000, 5, "iso8601", 1); +instance.monthsInYear; + +Object.defineProperty(Temporal.Calendar.prototype, "monthsInYear", monthsInYearOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-case-insensitive.js index 0c0d6dbcf4b1..b290e51b504d 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-case-insensitive.js @@ -12,10 +12,6 @@ const instance = new Temporal.PlainYearMonth(2019, 6); const calendar = "IsO8601"; -let arg = { year: 2019, monthCode: "M06", calendar }; -const result1 = instance.since(arg); -TemporalHelpers.assertDuration(result1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Calendar is case-insensitive"); - -arg = { year: 2019, monthCode: "M06", calendar: { calendar } }; -const result2 = instance.since(arg); -TemporalHelpers.assertDuration(result2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Calendar is case-insensitive (nested property)"); +const arg = { year: 2019, monthCode: "M06", calendar }; +const result = instance.since(arg); +TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 629dd814b7c6..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,25 +0,0 @@ -// 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.since -description: > - A Temporal.Calendar instance passed to since() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.PlainYearMonth(2019, 6); - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -let arg = { year: 2019, monthCode: "M06", calendar }; -instance.since(arg); - -arg = { year: 2019, monthCode: "M06", calendar: { calendar } }; -instance.since(arg); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-leap-second.js index 9a276a1a4c5f..523035719bd1 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-leap-second.js @@ -12,18 +12,10 @@ const instance = new Temporal.PlainYearMonth(2019, 6); const calendar = "2016-12-31T23:59:60"; -let arg = { year: 2019, monthCode: "M06", calendar }; -const result1 = instance.since(arg); +const arg = { year: 2019, monthCode: "M06", calendar }; +const result = instance.since(arg); TemporalHelpers.assertDuration( - result1, + result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "leap second is a valid ISO string for calendar" ); - -arg = { year: 2019, monthCode: "M06", calendar: { calendar } }; -const result2 = instance.since(arg); -TemporalHelpers.assertDuration( - result2, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-number.js index ab573e785ab4..97c87fc7e23d 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-number.js @@ -12,13 +12,9 @@ const instance = new Temporal.PlainYearMonth(2019, 6); const calendar = 19970327; -let arg = { year: 2019, monthCode: "M06", calendar }; -const result1 = instance.since(arg); -TemporalHelpers.assertDuration(result1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar"); - -arg = { year: 2019, monthCode: "M06", calendar: { calendar } }; -const result2 = instance.since(arg); -TemporalHelpers.assertDuration(result2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { year: 2019, monthCode: "M06", calendar }; +const result = instance.since(arg); +TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -27,16 +23,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 2019, monthCode: "M06", calendar }; + const arg = { year: 2019, monthCode: "M06", calendar }; assert.throws( RangeError, () => instance.since(arg), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { year: 2019, monthCode: "M06", calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.since(arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-wrong-type.js index da4a19a8bfc8..364753a8404d 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-wrong-type.js @@ -21,27 +21,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.since(arg), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.since(arg), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.since(arg), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.since(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.since(arg), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/argument-string-calendar-annotation.js index be7dc5dcd09c..5e40a87534ad 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/argument-string-calendar-annotation.js @@ -14,7 +14,6 @@ const tests = [ ["2019-12-15T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["2019-12-15T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["2019-12-15T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["2019-12-15T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const instance = new Temporal.PlainYearMonth(2019, 12); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..29b0e33a638b --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.since +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.PlainYearMonth(2000, 5); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.since(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..3e8120ac1173 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.since +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const dateUntilOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dateUntil"); +Object.defineProperty(Temporal.Calendar.prototype, "dateUntil", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("dateUntil should not be looked up"); + }, +}); + +const instance = new Temporal.PlainYearMonth(2000, 5, "iso8601", 1); +instance.since(new Temporal.PlainYearMonth(1999, 4)); + +Object.defineProperty(Temporal.Calendar.prototype, "dateUntil", dateUntilOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/calendar-yearmonthfromfields-called-with-options-undefined.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/calendar-yearmonthfromfields-called-with-options-undefined.js index db48db0cfaae..17a7687b4fa9 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/calendar-yearmonthfromfields-called-with-options-undefined.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/calendar-yearmonthfromfields-called-with-options-undefined.js @@ -14,22 +14,3 @@ let calendar = TemporalHelpers.calendarFromFieldsUndefinedOptions(); let instance = new Temporal.PlainYearMonth(2000, 5, calendar); instance.since({ year: 2000, month: 6, calendar }); assert.sameValue(calendar.yearMonthFromFieldsCallCount, 1); - -// Test again, but overriding the global Temporal.Calendar.prototype method so -// we can observe the call to yearMonthFromFields() on the ISO8601 calendar -// that occurs when we parse the string - -const realYearMonthFromFields = Temporal.Calendar.prototype.yearMonthFromFields; -let yearMonthFromFieldsCallCount = 0; -Temporal.Calendar.prototype.yearMonthFromFields = function (fields, options) { - yearMonthFromFieldsCallCount++; - assert.sameValue(options, undefined, "yearMonthFromFields shouldn't be called with options"); - return realYearMonthFromFields.call(this, fields, options); -} - -calendar = new Temporal.Calendar("iso8601"); -instance = new Temporal.PlainYearMonth(2000, 5, calendar); -instance.since("2000-06-01"); -assert.sameValue(yearMonthFromFieldsCallCount, 1); - -Temporal.Calendar.prototype.yearMonthFromFields = realYearMonthFromFields; diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/mixed-calendar-invalid.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/mixed-calendar-invalid.js index de9ffb8d925e..8dfa5fb13927 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/mixed-calendar-invalid.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/mixed-calendar-invalid.js @@ -11,8 +11,8 @@ class customCal extends Temporal.Calendar { constructor () { super('iso8601'); } - - toString() { + + get id() { return "I am a secret cal."; } } diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/order-of-operations.js index 44e5c304a34b..5cc60b85e0b1 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/since/order-of-operations.js @@ -11,7 +11,27 @@ features: [Temporal] const expected = [ // ToTemporalYearMonth "get other.calendar", - "has other.calendar.calendar", + "has other.calendar.dateAdd", + "has other.calendar.dateFromFields", + "has other.calendar.dateUntil", + "has other.calendar.day", + "has other.calendar.dayOfWeek", + "has other.calendar.dayOfYear", + "has other.calendar.daysInMonth", + "has other.calendar.daysInWeek", + "has other.calendar.daysInYear", + "has other.calendar.fields", + "has other.calendar.id", + "has other.calendar.inLeapYear", + "has other.calendar.mergeFields", + "has other.calendar.month", + "has other.calendar.monthCode", + "has other.calendar.monthDayFromFields", + "has other.calendar.monthsInYear", + "has other.calendar.weekOfYear", + "has other.calendar.year", + "has other.calendar.yearMonthFromFields", + "has other.calendar.yearOfWeek", "get other.calendar.fields", "call other.calendar.fields", "get other.month", @@ -26,12 +46,8 @@ const expected = [ "get other.calendar.yearMonthFromFields", "call other.calendar.yearMonthFromFields", // CalendarEquals - "get this.calendar[Symbol.toPrimitive]", - "get this.calendar.toString", - "call this.calendar.toString", - "get other.calendar[Symbol.toPrimitive]", - "get other.calendar.toString", - "call other.calendar.toString", + "get this.calendar.id", + "get other.calendar.id", // CopyDataProperties "ownKeys options", "getOwnPropertyDescriptor options.roundingIncrement", diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..18fb32df5d9b --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.subtract +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const dateAddOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dateAdd"); +Object.defineProperty(Temporal.Calendar.prototype, "dateAdd", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("dateAdd should not be looked up"); + }, +}); + +const instance = new Temporal.PlainYearMonth(2000, 5, "iso8601", 1); +instance.subtract(new Temporal.Duration(1)); + +Object.defineProperty(Temporal.Calendar.prototype, "dateAdd", dateAddOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-arguments-extra-options.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-arguments-extra-options.js index fed109d70a57..46384397d7fe 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-arguments-extra-options.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-arguments-extra-options.js @@ -25,13 +25,16 @@ const expected = [ ]; const options = TemporalHelpers.propertyBagObserver(actual, { extra: 5 }, "options"); +let dateAddCalls = 0; class CustomCalendar extends Temporal.Calendar { constructor() { super("iso8601"); } dateAdd(date, duration, options) { const result = super.dateAdd(date, duration, options); - options.overflow = 'meatloaf'; + dateAddCalls++; + if (dateAddCalls == 3) + options.overflow = 'meatloaf'; return result; } yearMonthFromFields(...args) { diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-arguments.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-arguments.js index 5c196c0e89e1..122e29ae28a0 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-arguments.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-arguments.js @@ -30,13 +30,16 @@ const expected = [ ]; const options = TemporalHelpers.propertyBagObserver(actual, { overflow: "constrain" }, "options"); +let dateAddCalls = 0; class CustomCalendar extends Temporal.Calendar { constructor() { super("iso8601"); } dateAdd(date, duration, options) { const result = super.dateAdd(date, duration, options); - options.overflow = 'meatloaf'; + dateAddCalls++; + if (dateAddCalls == 3) + options.overflow = 'meatloaf'; return result; } yearMonthFromFields(...args) { diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-dateadd-called-with-plaindate-instance.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-dateadd-called-with-plaindate-instance.js new file mode 100644 index 000000000000..037d83a78aa9 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-dateadd-called-with-plaindate-instance.js @@ -0,0 +1,18 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.subtract +description: Duration subtraction from PlainYearMonth calls Calendar.dateAdd the right number of times +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = TemporalHelpers.calendarDateAddPlainDateInstance(); +const instance = new Temporal.PlainYearMonth(1983, 3, calendar); +TemporalHelpers.assertPlainYearMonth(instance.subtract({days: 31}), 1983, 2, 'M02', "Removing 31 days to march in is8601 calendar") +assert.sameValue(calendar.dateAddCallCount, 3, "dateAdd called 3 times with positive subtract"); + +calendar.dateAddCallCount = 0; +TemporalHelpers.assertPlainYearMonth(instance.subtract({days: -31}), 1983, 4, 'M04', "Removing -31 days to march in is8601 calendar") +assert.sameValue(calendar.dateAddCallCount, 1, "dateAdd called once with negative subtract"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-dateadd.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-dateadd.js index 5622d8779429..0e39c359ffe1 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-dateadd.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-dateadd.js @@ -15,10 +15,12 @@ class CustomCalendar extends Temporal.Calendar { } dateAdd(plainDate, duration, options) { ++calls; - TemporalHelpers.assertPlainDate(plainDate, 2000, 3, "M03", 31, "plainDate argument"); - TemporalHelpers.assertDuration(duration, 0, -10, 0, 0, 0, 0, 0, 0, 0, 0, "duration argument"); - assert.sameValue(typeof options, "object", "options argument: type"); - assert.sameValue(Object.getPrototypeOf(options), null, "options argument: prototype"); + if (calls == 3) { + TemporalHelpers.assertPlainDate(plainDate, 2000, 3, "M03", 31, "plainDate argument"); + TemporalHelpers.assertDuration(duration, 0, -10, 0, 0, 0, 0, 0, 0, 0, 0, "duration argument"); + assert.sameValue(typeof options, "object", "options argument: type"); + assert.sameValue(Object.getPrototypeOf(options), null, "options argument: prototype"); + } return super.dateAdd(plainDate, duration, options); } } @@ -26,4 +28,4 @@ class CustomCalendar extends Temporal.Calendar { const plainYearMonth = new Temporal.PlainYearMonth(2000, 3, new CustomCalendar()); const result = plainYearMonth.subtract({ months: 10 }); TemporalHelpers.assertPlainYearMonth(result, 1999, 5, "M05"); -assert.sameValue(calls, 1, "should have called dateAdd"); +assert.sameValue(calls, 3, "should have called dateAdd 3 times"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-datefromfields-called.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-datefromfields-called.js index 91ed2c46daf5..080c12eba8da 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-datefromfields-called.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-datefromfields-called.js @@ -77,8 +77,13 @@ class CustomCalendar extends Temporal.Calendar { return new Temporal.PlainMonthDay(isoMonth, isoDay, this, isoYear); } dateAdd(date, duration, options) { - if (duration.months) throw new Error("adding months not implemented in this test"); - return super.dateAdd(date, duration, options); + const {isoYear, isoMonth, isoDay} = date.getISOFields(); + let {years, months, weeks, days} = duration; + let iter = new Temporal.PlainDate(isoYear + years, isoMonth, isoDay, "iso8601"); + const monthsDays = months * 36; + if (iter.dayOfYear + monthsDays > iter.daysInYear || iter.dayOfYear + monthsDays < 1) + throw new Error("complicated addition not implemented in this test"); + return iter.add({ weeks, days: monthsDays + days }).withCalendar(this); } toString() { return "thirty-six"; @@ -102,9 +107,9 @@ TemporalHelpers.assertPlainYearMonth( "subtracting positive less than one month's worth of days yields the same month", /* era = */ undefined, /* eraYear = */ undefined, /* referenceISODay = */ 6 ); -assert.sameValue(calendar.dateFromFieldsCalls.length, 1, "dateFromFields was called"); +assert.sameValue(calendar.dateFromFieldsCalls.length, 2, "dateFromFields was called twice"); assert.deepEqual( - calendar.dateFromFieldsCalls[0][0], + calendar.dateFromFieldsCalls[1][0], { year: 2022, monthCode: "M02", day: 36 }, "last day of month 2 passed to dateFromFields when subtracting positive duration" ); @@ -117,9 +122,9 @@ TemporalHelpers.assertPlainYearMonth( "subtracting positive one month's worth of days yields the previous month", /* era = */ undefined, /* eraYear = */ undefined, /* referenceISODay = */ 1 ); -assert.sameValue(calendar.dateFromFieldsCalls.length, 1, "dateFromFields was called"); +assert.sameValue(calendar.dateFromFieldsCalls.length, 2, "dateFromFields was called twice"); assert.deepEqual( - calendar.dateFromFieldsCalls[0][0], + calendar.dateFromFieldsCalls[1][0], { year: 2022, monthCode: "M02", day: 36 }, "last day of month 2 passed to dateFromFields when subtracting positive duration" ); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-daysinmonth-wrong-value.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-daysinmonth-wrong-value.js deleted file mode 100644 index 50d7feeab7a8..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-daysinmonth-wrong-value.js +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.plainyearmonth.prototype.subtract -description: > - The appropriate error is thrown if the calendar's daysInMonth method returns a - value that cannot be converted to a positive integer -includes: [compareArray.js] -features: [BigInt, Symbol, Temporal] ----*/ - -const actual = []; -class CalendarDaysInMonthWrongValue extends Temporal.Calendar { - constructor(badValue) { - super("iso8601"); - this._badValue = badValue; - } - dateFromFields(fields, options) { - actual.push("call dateFromFields"); - return super.dateFromFields(fields, options); - } - daysInMonth() { - return this._badValue; - } -} -// daysInMonth is only called if we are subtracting a positive duration -const duration = new Temporal.Duration(1, 1); - -[Infinity, -Infinity, -42].forEach((badValue) => { - const calendar = new CalendarDaysInMonthWrongValue(badValue); - const yearMonth = new Temporal.PlainYearMonth(2000, 5, calendar); - assert.throws(RangeError, () => yearMonth.subtract(duration), `daysInMonth ${badValue}`); - assert.compareArray(actual, [], "dateFromFields not called"); -}); - -[Symbol('foo'), 31n].forEach((badValue) => { - const calendar = new CalendarDaysInMonthWrongValue(badValue); - const yearMonth = new Temporal.PlainYearMonth(2000, 5, calendar); - assert.throws(TypeError, () => yearMonth.subtract(duration), `daysInMonth ${typeof badValue}`); - assert.compareArray(actual, [], "dateFromFields not called"); -}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-fromfields-called-with-null-prototype-fields.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-fromfields-called-with-null-prototype-fields.js index adfcb9819606..885716b52a0a 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-fromfields-called-with-null-prototype-fields.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-fromfields-called-with-null-prototype-fields.js @@ -12,5 +12,5 @@ features: [Temporal] const calendar = TemporalHelpers.calendarCheckFieldsPrototypePollution(); const instance = new Temporal.PlainYearMonth(2000, 5, calendar); instance.subtract(new Temporal.Duration(1)); -assert.sameValue(calendar.dateFromFieldsCallCount, 1, "dateFromFields should have been called on the calendar"); +assert.sameValue(calendar.dateFromFieldsCallCount, 2, "dateFromFields should have been called twice on the calendar"); assert.sameValue(calendar.yearMonthFromFieldsCallCount, 1, "yearMonthFromFields should have been called on the calendar"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/custom-daysInMonth-irrelevant.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/custom-daysInMonth-irrelevant.js new file mode 100644 index 000000000000..147fa5fa384d --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/custom-daysInMonth-irrelevant.js @@ -0,0 +1,23 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.subtract +description: Subtraction of positive duration to a PlainYearMonth is not influenced by the implementation of daysInMonth() +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +class CustomCalendar extends Temporal.Calendar { + constructor() { + super("iso8601"); + } + daysInMonth(ym, ...args) { + return 15; + } +} + +const customCalendar = new CustomCalendar(); +const instance = new Temporal.PlainYearMonth(2023, 3, customCalendar); + +TemporalHelpers.assertPlainYearMonth(instance.subtract({days: 30}), 2023, 3, 'M03', "Subtracting 30 days from calendar reimplementing daysinMonth()") diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/options-undefined.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/options-undefined.js index 3588779fe8b2..c1e7fc7f1ce8 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/options-undefined.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/options-undefined.js @@ -12,10 +12,12 @@ features: [Temporal] class CheckedAdd extends Temporal.Calendar { constructor() { super("iso8601"); + this.called = 0; } dateAdd(date, duration, options, constructor) { - this.called = true; - assert.notSameValue(options, undefined, "options not undefined"); + this.called += 1; + if (this.called == 3) + assert.notSameValue(options, undefined, "options not undefined"); return super.dateAdd(date, duration, options, constructor); } } @@ -25,6 +27,8 @@ const yearmonth = new Temporal.PlainYearMonth(2000, 3, calendar); const duration = { months: 1 }; yearmonth.subtract(duration, undefined); -yearmonth.subtract(duration); +assert(calendar.called == 3); -assert(calendar.called); +calendar.called = 0; +yearmonth.subtract(duration); +assert(calendar.called == 3); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/order-of-operations.js index d0743024ef38..d92ed783eb78 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/order-of-operations.js @@ -49,9 +49,13 @@ const expected = [ "get this.calendar.year", "call this.calendar.year", // CalendarDaysInMonth - "get this.calendar.daysInMonth", - "call this.calendar.daysInMonth", - // CalendarDateFromFields + "get this.calendar.dateFromFields", + "call this.calendar.dateFromFields", + "get this.calendar.dateAdd", + "call this.calendar.dateAdd", + "call this.calendar.dateAdd", + "get this.calendar.day", + "call this.calendar.day", "get this.calendar.dateFromFields", "call this.calendar.dateFromFields", // CopyDataProperties @@ -59,7 +63,6 @@ const expected = [ "getOwnPropertyDescriptor options.overflow", "get options.overflow", // CalendarDateAdd - "get this.calendar.dateAdd", "call this.calendar.dateAdd", // inside Calendar.p.dateAdd "get options.overflow", diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toJSON/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toJSON/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..88557a40b878 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toJSON/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.tojson +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const idOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "id"); +Object.defineProperty(Temporal.Calendar.prototype, "id", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("id should not be looked up"); + }, +}); + +const instance = new Temporal.PlainYearMonth(2000, 5, "iso8601", 1); +instance.toJSON(); + +Object.defineProperty(Temporal.Calendar.prototype, "id", idOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toLocaleString/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toLocaleString/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..474e4ce5bd71 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toLocaleString/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.tolocalestring +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const idOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "id"); +Object.defineProperty(Temporal.Calendar.prototype, "id", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("id should not be looked up"); + }, +}); + +const instance = new Temporal.PlainYearMonth(2000, 5, "iso8601", 1); +instance.toLocaleString(undefined, { calendar: "iso8601" }); + +Object.defineProperty(Temporal.Calendar.prototype, "id", idOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toPlainDate/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toPlainDate/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..027fe0baf973 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toPlainDate/builtin-calendar-no-observable-calls.js @@ -0,0 +1,43 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.toplaindate +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const fieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "fields"); +Object.defineProperty(Temporal.Calendar.prototype, "fields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("fields should not be looked up"); + }, +}); +const mergeFieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "mergeFields"); +Object.defineProperty(Temporal.Calendar.prototype, "mergeFields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("mergeFields should not be looked up"); + }, +}); +const dateFromFieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dateFromFields"); +Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("dateFromFields should not be looked up"); + }, +}); + +const instance = new Temporal.PlainYearMonth(2000, 5, "iso8601", 1); +instance.toPlainDate({ day: 12 }); + +Object.defineProperty(Temporal.Calendar.prototype, "fields", fieldsOriginal); +Object.defineProperty(Temporal.Calendar.prototype, "mergeFields", mergeFieldsOriginal); +Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", dateFromFieldsOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toString/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toString/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..e4b908dea574 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toString/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 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: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const idOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "id"); +Object.defineProperty(Temporal.Calendar.prototype, "id", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("id should not be looked up"); + }, +}); + +const instance = new Temporal.PlainYearMonth(2000, 5, "iso8601", 1); +instance.toString(); + +Object.defineProperty(Temporal.Calendar.prototype, "id", idOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toString/calendar-tostring.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toString/calendar-tostring.js index 3eec13d7791f..da23c65c5eb3 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toString/calendar-tostring.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toString/calendar-tostring.js @@ -4,15 +4,39 @@ /*--- esid: sec-temporal.plainyearmonth.protoype.tostring description: Number of observable 'toString' calls on the calendar for each value of calendarName +includes: [temporalHelpers.js] features: [Temporal] ---*/ let calls; const customCalendar = { - toString() { + get id() { ++calls; return "custom"; - } + }, + toString() { + TemporalHelpers.assertUnreachable('toString should not be called'); + }, + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, }; const yearmonth = new Temporal.PlainYearMonth(2000, 5, customCalendar); [ @@ -24,6 +48,6 @@ const yearmonth = new Temporal.PlainYearMonth(2000, 5, customCalendar); ].forEach(([calendarName, expectedResult, expectedCalls]) => { calls = 0; const result = yearmonth.toString({ calendarName }); - assert.sameValue(result, expectedResult, `toString output for calendarName = ${calendarName}`); - assert.sameValue(calls, expectedCalls, `calls to toString for calendarName = ${calendarName}`); + assert.sameValue(result, expectedResult, `id for calendarName = ${calendarName}`); + assert.sameValue(calls, expectedCalls, `calls to id getter for calendarName = ${calendarName}`); }); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toString/calendarname-always.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toString/calendarname-always.js index 378a056bec6d..9aaf7f0d76ff 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toString/calendarname-always.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toString/calendarname-always.js @@ -7,12 +7,35 @@ description: If calendarName is "always", the calendar ID should be included. features: [Temporal] ---*/ +const calendarMethods = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; + const tests = [ [[], "2000-05-01[u-ca=iso8601]", "built-in ISO"], - [[{ toString() { return "custom"; } }], "2000-05-01[u-ca=custom]", "custom"], - [[{ toString() { return "iso8601"; } }], "2000-05-01[u-ca=iso8601]", "custom with iso8601 toString"], - [[{ toString() { return "ISO8601"; } }], "2000-05-01[u-ca=ISO8601]", "custom with caps toString"], - [[{ toString() { return "\u0131so8601"; } }], "2000-05-01[u-ca=\u0131so8601]", "custom with dotless i toString"], + [[{ id: "custom", ...calendarMethods }], "2000-05-01[u-ca=custom]", "custom"], + [[{ id: "iso8601", ...calendarMethods }], "2000-05-01[u-ca=iso8601]", "custom with iso8601 id"], + [[{ id: "ISO8601", ...calendarMethods }], "2000-05-01[u-ca=ISO8601]", "custom with caps id"], + [[{ id: "\u0131so8601", ...calendarMethods }], "2000-05-01[u-ca=\u0131so8601]", "custom with dotless i id"], ]; for (const [args, expected, description] of tests) { diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toString/calendarname-auto.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toString/calendarname-auto.js index d4e547d2151a..c940f67815e3 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toString/calendarname-auto.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toString/calendarname-auto.js @@ -7,12 +7,35 @@ description: If calendarName is "auto", "iso8601" should be omitted. features: [Temporal] ---*/ +const calendarMethods = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; + const tests = [ [[], "2000-05", "built-in ISO"], - [[{ toString() { return "custom"; } }], "2000-05-01[u-ca=custom]", "custom"], - [[{ toString() { return "iso8601"; } }], "2000-05", "custom with iso8601 toString"], - [[{ toString() { return "ISO8601"; } }], "2000-05-01[u-ca=ISO8601]", "custom with caps toString"], - [[{ toString() { return "\u0131so8601"; } }], "2000-05-01[u-ca=\u0131so8601]", "custom with dotless i toString"], + [[{ id: "custom", ...calendarMethods }], "2000-05-01[u-ca=custom]", "custom"], + [[{ id: "iso8601", ...calendarMethods }], "2000-05", "custom with iso8601 id"], + [[{ id: "ISO8601", ...calendarMethods }], "2000-05-01[u-ca=ISO8601]", "custom with caps id"], + [[{ id: "\u0131so8601", ...calendarMethods }], "2000-05-01[u-ca=\u0131so8601]", "custom with dotless i id"], ]; for (const [args, expected, description] of tests) { diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toString/calendarname-critical.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toString/calendarname-critical.js index 85e50d262c68..cc4aeaea3a07 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toString/calendarname-critical.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toString/calendarname-critical.js @@ -9,12 +9,35 @@ description: > features: [Temporal] ---*/ +const calendarMethods = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; + const tests = [ [[], "2000-05-01[!u-ca=iso8601]", "built-in ISO"], - [[{ toString() { return "custom"; } }], "2000-05-01[!u-ca=custom]", "custom"], - [[{ toString() { return "iso8601"; } }], "2000-05-01[!u-ca=iso8601]", "custom with iso8601 toString"], - [[{ toString() { return "ISO8601"; } }], "2000-05-01[!u-ca=ISO8601]", "custom with caps toString"], - [[{ toString() { return "\u0131so8601"; } }], "2000-05-01[!u-ca=\u0131so8601]", "custom with dotless i toString"], + [[{ id: "custom", ...calendarMethods }], "2000-05-01[!u-ca=custom]", "custom"], + [[{ id: "iso8601", ...calendarMethods }], "2000-05-01[!u-ca=iso8601]", "custom with iso8601 id"], + [[{ id: "ISO8601", ...calendarMethods }], "2000-05-01[!u-ca=ISO8601]", "custom with caps id"], + [[{ id: "\u0131so8601", ...calendarMethods }], "2000-05-01[!u-ca=\u0131so8601]", "custom with dotless i id"], ]; for (const [args, expected, description] of tests) { diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toString/calendarname-never.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toString/calendarname-never.js index 670c0019a7cd..9bfe45ec12ac 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toString/calendarname-never.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toString/calendarname-never.js @@ -7,12 +7,35 @@ description: If calendarName is "never", the calendar ID should be omitted. features: [Temporal] ---*/ +const calendarMethods = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; + const tests = [ [[], "2000-05", "built-in ISO"], - [[{ toString() { return "custom"; } }], "2000-05-01", "custom"], - [[{ toString() { return "iso8601"; } }], "2000-05", "custom with iso8601 toString"], - [[{ toString() { return "ISO8601"; } }], "2000-05-01", "custom with caps toString"], - [[{ toString() { return "\u0131so8601"; } }], "2000-05-01", "custom with dotless i toString"], + [[{ id: "custom", ...calendarMethods }], "2000-05-01", "custom"], + [[{ id: "iso8601", ...calendarMethods }], "2000-05", "custom with iso8601 id"], + [[{ id: "ISO8601", ...calendarMethods }], "2000-05-01", "custom with caps id"], + [[{ id: "\u0131so8601", ...calendarMethods }], "2000-05-01", "custom with dotless i id"], ]; for (const [args, expected, description] of tests) { diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toString/calendarname-undefined.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toString/calendarname-undefined.js index 23592c7d5486..a8d9717eadfe 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toString/calendarname-undefined.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toString/calendarname-undefined.js @@ -14,12 +14,35 @@ info: | features: [Temporal] ---*/ +const calendarMethods = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; + const tests = [ [[], "2000-05", "built-in ISO"], - [[{ toString() { return "custom"; } }], "2000-05-01[u-ca=custom]", "custom"], - [[{ toString() { return "iso8601"; } }], "2000-05", "custom with iso8601 toString"], - [[{ toString() { return "ISO8601"; } }], "2000-05-01[u-ca=ISO8601]", "custom with caps toString"], - [[{ toString() { return "\u0131so8601"; } }], "2000-05-01[u-ca=\u0131so8601]", "custom with dotless i toString"], + [[{ id: "custom", ...calendarMethods }], "2000-05-01[u-ca=custom]", "custom"], + [[{ id: "iso8601", ...calendarMethods }], "2000-05", "custom with iso8601 id"], + [[{ id: "ISO8601", ...calendarMethods }], "2000-05-01[u-ca=ISO8601]", "custom with caps id"], + [[{ id: "\u0131so8601", ...calendarMethods }], "2000-05-01[u-ca=\u0131so8601]", "custom with dotless i id"], ]; for (const [args, expected, description] of tests) { diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toString/calendarname-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toString/calendarname-wrong-type.js index 4ad85fe1df50..df91dd657cac 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toString/calendarname-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toString/calendarname-wrong-type.js @@ -16,7 +16,27 @@ features: [Temporal] ---*/ const calendar = { - toString() { return "custom"; } + id: "custom", + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, }; const yearmonth = new Temporal.PlainYearMonth(2000, 5, calendar); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toString/options-undefined.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toString/options-undefined.js index 19b6e8e7b329..c84712f2e6c4 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toString/options-undefined.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toString/options-undefined.js @@ -8,7 +8,27 @@ features: [Temporal] ---*/ const calendar = { - toString() { return "custom"; } + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "custom", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, }; const yearmonth1 = new Temporal.PlainYearMonth(2000, 5); const yearmonth2 = new Temporal.PlainYearMonth(2000, 5, calendar); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toString/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toString/order-of-operations.js index 902d57fd5bff..95bcf3ff942a 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toString/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/toString/order-of-operations.js @@ -12,9 +12,7 @@ const expected = [ "get options.calendarName", "get options.calendarName.toString", "call options.calendarName.toString", - "get this.calendar[Symbol.toPrimitive]", - "get this.calendar.toString", - "call this.calendar.toString", + "get this.calendar.id", ]; const actual = []; diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-case-insensitive.js index bb9636441556..a708ef9313ba 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-case-insensitive.js @@ -12,10 +12,6 @@ const instance = new Temporal.PlainYearMonth(2019, 6); const calendar = "IsO8601"; -let arg = { year: 2019, monthCode: "M06", calendar }; -const result1 = instance.until(arg); -TemporalHelpers.assertDuration(result1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Calendar is case-insensitive"); - -arg = { year: 2019, monthCode: "M06", calendar: { calendar } }; -const result2 = instance.until(arg); -TemporalHelpers.assertDuration(result2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Calendar is case-insensitive (nested property)"); +const arg = { year: 2019, monthCode: "M06", calendar }; +const result = instance.until(arg); +TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index b87a98c3f6d7..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,25 +0,0 @@ -// 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.until -description: > - A Temporal.Calendar instance passed to until() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.PlainYearMonth(2019, 6); - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -let arg = { year: 2019, monthCode: "M06", calendar }; -instance.until(arg); - -arg = { year: 2019, monthCode: "M06", calendar: { calendar } }; -instance.until(arg); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-leap-second.js index 883d319460ec..91ec88efc6ab 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-leap-second.js @@ -12,18 +12,10 @@ const instance = new Temporal.PlainYearMonth(2019, 6); const calendar = "2016-12-31T23:59:60"; -let arg = { year: 2019, monthCode: "M06", calendar }; -const result1 = instance.until(arg); +const arg = { year: 2019, monthCode: "M06", calendar }; +const result = instance.until(arg); TemporalHelpers.assertDuration( - result1, + result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "leap second is a valid ISO string for calendar" ); - -arg = { year: 2019, monthCode: "M06", calendar: { calendar } }; -const result2 = instance.until(arg); -TemporalHelpers.assertDuration( - result2, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-number.js index 2dedd8fe55fa..2ee4920af05d 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-number.js @@ -12,13 +12,9 @@ const instance = new Temporal.PlainYearMonth(2019, 6); const calendar = 19970327; -let arg = { year: 2019, monthCode: "M06", calendar }; -const result1 = instance.until(arg); -TemporalHelpers.assertDuration(result1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar"); - -arg = { year: 2019, monthCode: "M06", calendar: { calendar } }; -const result2 = instance.until(arg); -TemporalHelpers.assertDuration(result2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { year: 2019, monthCode: "M06", calendar }; +const result = instance.until(arg); +TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -27,16 +23,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 2019, monthCode: "M06", calendar }; + const arg = { year: 2019, monthCode: "M06", calendar }; assert.throws( RangeError, () => instance.until(arg), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { year: 2019, monthCode: "M06", calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.until(arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-wrong-type.js index 18a4d80265ef..760a559d6b03 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-wrong-type.js @@ -21,27 +21,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.until(arg), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.until(arg), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.until(arg), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.until(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.until(arg), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/argument-string-calendar-annotation.js index f764083c5900..37e2e3fa84b7 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/argument-string-calendar-annotation.js @@ -14,7 +14,6 @@ const tests = [ ["2019-12-15T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["2019-12-15T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["2019-12-15T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["2019-12-15T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const instance = new Temporal.PlainYearMonth(2019, 12); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..7a5603e125ac --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.until +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.PlainYearMonth(2000, 5); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.until(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..8fd95fd45625 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.until +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const dateUntilOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dateUntil"); +Object.defineProperty(Temporal.Calendar.prototype, "dateUntil", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("dateUntil should not be looked up"); + }, +}); + +const instance = new Temporal.PlainYearMonth(2000, 5, "iso8601", 1); +instance.until(new Temporal.PlainYearMonth(2001, 6)); + +Object.defineProperty(Temporal.Calendar.prototype, "dateUntil", dateUntilOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/calendar-yearmonthfromfields-called-with-options-undefined.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/calendar-yearmonthfromfields-called-with-options-undefined.js index d9b946e2795a..5b2ac6578ad4 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/calendar-yearmonthfromfields-called-with-options-undefined.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/calendar-yearmonthfromfields-called-with-options-undefined.js @@ -14,22 +14,3 @@ let calendar = TemporalHelpers.calendarFromFieldsUndefinedOptions(); let instance = new Temporal.PlainYearMonth(2000, 5, calendar); instance.until({ year: 2000, month: 6, calendar }); assert.sameValue(calendar.yearMonthFromFieldsCallCount, 1); - -// Test again, but overriding the global Temporal.Calendar.prototype method so -// we can observe the call to yearMonthFromFields() on the ISO8601 calendar -// that occurs when we parse the string - -const realYearMonthFromFields = Temporal.Calendar.prototype.yearMonthFromFields; -let yearMonthFromFieldsCallCount = 0; -Temporal.Calendar.prototype.yearMonthFromFields = function (fields, options) { - yearMonthFromFieldsCallCount++; - assert.sameValue(options, undefined, "yearMonthFromFields shouldn't be called with options"); - return realYearMonthFromFields.call(this, fields, options); -} - -calendar = new Temporal.Calendar("iso8601"); -instance = new Temporal.PlainYearMonth(2000, 5, calendar); -instance.until("2000-06-01"); -assert.sameValue(yearMonthFromFieldsCallCount, 1); - -Temporal.Calendar.prototype.yearMonthFromFields = realYearMonthFromFields; diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/mixed-calendar-invalid.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/mixed-calendar-invalid.js index d971f9faf747..653542e78157 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/mixed-calendar-invalid.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/mixed-calendar-invalid.js @@ -11,8 +11,8 @@ class customCal extends Temporal.Calendar { constructor () { super('iso8601'); } - - toString() { + + get id() { return "I am a secret cal."; } } diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/order-of-operations.js index e9c93ad41d28..3eb4a0f3bfbb 100644 --- a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/until/order-of-operations.js @@ -11,7 +11,27 @@ features: [Temporal] const expected = [ // ToTemporalYearMonth "get other.calendar", - "has other.calendar.calendar", + "has other.calendar.dateAdd", + "has other.calendar.dateFromFields", + "has other.calendar.dateUntil", + "has other.calendar.day", + "has other.calendar.dayOfWeek", + "has other.calendar.dayOfYear", + "has other.calendar.daysInMonth", + "has other.calendar.daysInWeek", + "has other.calendar.daysInYear", + "has other.calendar.fields", + "has other.calendar.id", + "has other.calendar.inLeapYear", + "has other.calendar.mergeFields", + "has other.calendar.month", + "has other.calendar.monthCode", + "has other.calendar.monthDayFromFields", + "has other.calendar.monthsInYear", + "has other.calendar.weekOfYear", + "has other.calendar.year", + "has other.calendar.yearMonthFromFields", + "has other.calendar.yearOfWeek", "get other.calendar.fields", "call other.calendar.fields", "get other.month", @@ -26,12 +46,8 @@ const expected = [ "get other.calendar.yearMonthFromFields", "call other.calendar.yearMonthFromFields", // CalendarEquals - "get this.calendar[Symbol.toPrimitive]", - "get this.calendar.toString", - "call this.calendar.toString", - "get other.calendar[Symbol.toPrimitive]", - "get other.calendar.toString", - "call other.calendar.toString", + "get this.calendar.id", + "get other.calendar.id", // CopyDataProperties "ownKeys options", "getOwnPropertyDescriptor options.roundingIncrement", diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/with/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/with/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..98da4da7c95a --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/with/builtin-calendar-no-observable-calls.js @@ -0,0 +1,43 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.with +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const fieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "fields"); +Object.defineProperty(Temporal.Calendar.prototype, "fields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("fields should not be looked up"); + }, +}); +const mergeFieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "mergeFields"); +Object.defineProperty(Temporal.Calendar.prototype, "mergeFields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("mergeFields should not be looked up"); + }, +}); +const yearMonthFromFieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "yearMonthFromFields"); +Object.defineProperty(Temporal.Calendar.prototype, "yearMonthFromFields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("yearMonthFromFields should not be looked up"); + }, +}); + +const instance = new Temporal.PlainYearMonth(2000, 5, "iso8601", 1); +instance.with({ year: 2001 }); + +Object.defineProperty(Temporal.Calendar.prototype, "fields", fieldsOriginal); +Object.defineProperty(Temporal.Calendar.prototype, "mergeFields", mergeFieldsOriginal); +Object.defineProperty(Temporal.Calendar.prototype, "yearMonthFromFields", yearMonthFromFieldsOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/year/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/year/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..78ac7725c4c6 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/PlainYearMonth/prototype/year/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.year +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const yearOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "year"); +Object.defineProperty(Temporal.Calendar.prototype, "year", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("year should not be looked up"); + }, +}); + +const instance = new Temporal.PlainYearMonth(2000, 5, "iso8601", 1); +instance.year; + +Object.defineProperty(Temporal.Calendar.prototype, "year", yearOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/from/argument-object-invalid.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/from/argument-object-invalid.js deleted file mode 100644 index 1c49e98dedaa..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/TimeZone/from/argument-object-invalid.js +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (C) 2020 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.timezone.from -description: TimeZone.from() with invalid objects. -features: [Temporal] ----*/ - -assert.throws(RangeError, () => Temporal.TimeZone.from({ timeZone: "local" })); -assert.throws(RangeError, () => Temporal.TimeZone.from({ timeZone: { timeZone: "UTC" } })); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/from/argument-object.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/from/argument-object.js index 499e9cc67d70..31d443ba3a99 100644 --- a/JSTests/test262/test/built-ins/Temporal/TimeZone/from/argument-object.js +++ b/JSTests/test262/test/built-ins/Temporal/TimeZone/from/argument-object.js @@ -12,9 +12,7 @@ class CustomTimeZone extends Temporal.TimeZone {} const objects = [ new Temporal.TimeZone("UTC"), new CustomTimeZone("UTC"), - {}, - { getPlainDateTimeFor: null }, - { id: "Etc/Custom" }, + { id: "Etc/Custom", getPossibleInstantsFor: null, getOffsetNanosecondsFor: null }, ]; const thisValues = [ @@ -34,15 +32,6 @@ for (const thisValue of thisValues) { const zdt = new Temporal.ZonedDateTime(0n, "UTC"); const fromZdt = Temporal.TimeZone.from.call(thisValue, zdt); - assert.sameValue(fromZdt, zdt.timeZone); + assert.notSameValue(fromZdt, zdt.getTimeZone(), "from() creates a new object from a string slot value"); assert.sameValue(fromZdt.id, "UTC"); - - const tz = new Temporal.TimeZone("UTC"); - const fromPropertyBagObject = Temporal.TimeZone.from.call(thisValue, { timeZone: tz }); - assert.sameValue(fromPropertyBagObject, tz); - assert.sameValue(fromPropertyBagObject.id, "UTC"); - - const fromPropertyBagString = Temporal.TimeZone.from.call(thisValue, { timeZone: "UTC" }); - assert(fromPropertyBagString instanceof Temporal.TimeZone); - assert.sameValue(fromPropertyBagString.id, "UTC"); } diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/from/timezone-instance-does-not-get-timeZone-property.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/from/timezone-instance-does-not-get-timeZone-property.js deleted file mode 100644 index 38f519b518b3..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/TimeZone/from/timezone-instance-does-not-get-timeZone-property.js +++ /dev/null @@ -1,20 +0,0 @@ -// 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.from -description: > - A Temporal.TimeZone instance passed to from() does not have its - 'timeZone' property observably checked -features: [Temporal] ----*/ - -const timeZone = new Temporal.TimeZone("UTC"); -Object.defineProperty(timeZone, "timeZone", { - get() { - throw new Test262Error("timeZone.timeZone should not be accessed"); - }, -}); - -Temporal.TimeZone.from(timeZone); -Temporal.TimeZone.from({ timeZone }); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/from/timezone-string-datetime.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/from/timezone-string-datetime.js index 7535023ae2d4..b37e7a47e5c4 100644 --- a/JSTests/test262/test/built-ins/Temporal/TimeZone/from/timezone-string-datetime.js +++ b/JSTests/test262/test/built-ins/Temporal/TimeZone/from/timezone-string-datetime.js @@ -9,34 +9,23 @@ features: [Temporal] let timeZone = "2021-08-19T17:30"; assert.throws(RangeError, () => Temporal.TimeZone.from(timeZone), "bare date-time string is not a time zone"); -assert.throws(RangeError, () => Temporal.TimeZone.from({ timeZone }), "bare date-time string is not a time zone"); timeZone = "2021-08-19T17:30Z"; const result1 = Temporal.TimeZone.from(timeZone); assert.sameValue(result1.id, "UTC", "date-time + Z is UTC time zone"); -const result2 = Temporal.TimeZone.from({ timeZone }); -assert.sameValue(result2.id, "UTC", "date-time + Z is UTC time zone (string in property bag)"); timeZone = "2021-08-19T17:30-07:00"; -const result3 = Temporal.TimeZone.from(timeZone); -assert.sameValue(result3.id, "-07:00", "date-time + offset is the offset time zone"); -const result4 = Temporal.TimeZone.from({ timeZone }); -assert.sameValue(result4.id, "-07:00", "date-time + offset is the offset time zone (string in property bag)"); +const result2 = Temporal.TimeZone.from(timeZone); +assert.sameValue(result2.id, "-07:00", "date-time + offset is the offset time zone"); timeZone = "2021-08-19T17:30[UTC]"; -const result5 = Temporal.TimeZone.from(timeZone); -assert.sameValue(result5.id, "UTC", "date-time + IANA annotation is the IANA time zone"); -const result6 = Temporal.TimeZone.from({ timeZone }); -assert.sameValue(result6.id, "UTC", "date-time + IANA annotation is the IANA time zone (string in property bag)"); +const result3 = Temporal.TimeZone.from(timeZone); +assert.sameValue(result3.id, "UTC", "date-time + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30Z[UTC]"; -const result7 = Temporal.TimeZone.from(timeZone); -assert.sameValue(result7.id, "UTC", "date-time + Z + IANA annotation is the IANA time zone"); -const result8 = Temporal.TimeZone.from({ timeZone }); -assert.sameValue(result8.id, "UTC", "date-time + Z + IANA annotation is the IANA time zone (string in property bag)"); +const result4 = Temporal.TimeZone.from(timeZone); +assert.sameValue(result4.id, "UTC", "date-time + Z + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30-07:00[UTC]"; -const result9 = Temporal.TimeZone.from(timeZone); -assert.sameValue(result9.id, "UTC", "date-time + offset + IANA annotation is the IANA time zone"); -const result10 = Temporal.TimeZone.from({ timeZone }); -assert.sameValue(result10.id, "UTC", "date-time + offset + IANA annotation is the IANA time zone (string in property bag)"); +const result5 = Temporal.TimeZone.from(timeZone); +assert.sameValue(result5.id, "UTC", "date-time + offset + IANA annotation is the IANA time zone"); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/from/timezone-string-leap-second.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/from/timezone-string-leap-second.js index 6629f5aeb84f..6433f9f10002 100644 --- a/JSTests/test262/test/built-ins/Temporal/TimeZone/from/timezone-string-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/TimeZone/from/timezone-string-leap-second.js @@ -9,11 +9,8 @@ features: [Temporal] let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; -const result1 = Temporal.TimeZone.from(timeZone); -assert.sameValue(result1.id, "UTC", "leap second is a valid ISO string for TimeZone"); -const result2 = Temporal.TimeZone.from({ timeZone }); -assert.sameValue(result2.id, "UTC", "leap second is a valid ISO string for TimeZone (nested property)"); +const result = Temporal.TimeZone.from(timeZone); +assert.sameValue(result.id, "UTC", "leap second is a valid ISO string for TimeZone"); timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; assert.throws(RangeError, () => Temporal.TimeZone.from(timeZone), "leap second in time zone name not valid"); -assert.throws(RangeError, () => Temporal.TimeZone.from({ timeZone }), "leap second in time zone name not valid (nested property)"); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/from/timezone-string-multiple-offsets.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/from/timezone-string-multiple-offsets.js index 85693acae994..e8b686fe038a 100644 --- a/JSTests/test262/test/built-ins/Temporal/TimeZone/from/timezone-string-multiple-offsets.js +++ b/JSTests/test262/test/built-ins/Temporal/TimeZone/from/timezone-string-multiple-offsets.js @@ -9,7 +9,5 @@ features: [Temporal] const timeZone = "2021-08-19T17:30:45.123456789+01:46[+01:45:30.987654321]"; -const result1 = Temporal.TimeZone.from(timeZone); -assert.sameValue(result1.id, "+01:45:30.987654321", "Time zone string determined from bracket name"); -const result2 = Temporal.TimeZone.from({ timeZone }); -assert.sameValue(result2.id, "+01:45:30.987654321", "Time zone string determined from bracket name"); +const result = Temporal.TimeZone.from(timeZone); +assert.sameValue(result.id, "+01:45:30.987654321", "Time zone string determined from bracket name"); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/from/timezone-string-year-zero.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/from/timezone-string-year-zero.js index 59940a4faa06..9e3720be18da 100644 --- a/JSTests/test262/test/built-ins/Temporal/TimeZone/from/timezone-string-year-zero.js +++ b/JSTests/test262/test/built-ins/Temporal/TimeZone/from/timezone-string-year-zero.js @@ -17,9 +17,4 @@ invalidStrings.forEach((timeZone) => { () => Temporal.TimeZone.from(timeZone), "reject minus zero as extended year" ); - assert.throws( - RangeError, - () => Temporal.TimeZone.from({ timeZone }), - "reject minus zero as extended year (nested property)" - ); }); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/from/timezone-string.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/from/timezone-string.js index 8be5cee0026b..38189494e549 100644 --- a/JSTests/test262/test/built-ins/Temporal/TimeZone/from/timezone-string.js +++ b/JSTests/test262/test/built-ins/Temporal/TimeZone/from/timezone-string.js @@ -4,10 +4,31 @@ /*--- esid: sec-temporal.timezone.from description: Time zone IDs are valid input for a time zone +includes: [temporalHelpers.js] features: [Temporal] ---*/ +const getPossibleInstantsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getPossibleInstantsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getPossibleInstantsFor should not be looked up"); + }, +}); +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + ["UTC", "+01:30"].forEach((timeZone) => { const result = Temporal.TimeZone.from(timeZone); assert.sameValue(result.id, timeZone, `Time zone created from string "${timeZone}"`); }); + +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", getPossibleInstantsForOriginal); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/from/timezone-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/from/timezone-wrong-type.js index e834410c785f..ac74b54f7fd6 100644 --- a/JSTests/test262/test/built-ins/Temporal/TimeZone/from/timezone-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/TimeZone/from/timezone-wrong-type.js @@ -16,22 +16,18 @@ const rangeErrorTests = [ [1, "number that doesn't convert to a valid ISO string"], [19761118, "number that would convert to a valid ISO string in other contexts"], [1n, "bigint"], - [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of rangeErrorTests) { assert.throws(RangeError, () => Temporal.TimeZone.from(timeZone), `${description} does not convert to a valid ISO string`); - assert.throws(RangeError, () => Temporal.TimeZone.from({ timeZone }), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], + [{}, "object not implementing time zone protocol"], + [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of typeErrorTests) { assert.throws(TypeError, () => Temporal.TimeZone.from(timeZone), `${description} is not a valid object and does not convert to a string`); - assert.throws(TypeError, () => Temporal.TimeZone.from({ timeZone }), `${description} is not a valid object and does not convert to a string (nested property)`); } - -const timeZone = undefined; -assert.throws(RangeError, () => Temporal.TimeZone.from({ timeZone }), `undefined is always a RangeError as nested property`); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-case-insensitive.js index 40aa37fe517d..ec10e723198f 100644 --- a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-case-insensitive.js @@ -11,10 +11,6 @@ const instance = new Temporal.TimeZone("UTC"); const calendar = "IsO8601"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.getInstantFor(arg); -assert.sameValue(result1.epochNanoseconds, 217_123_200_000_000_000n, "Calendar is case-insensitive"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.getInstantFor(arg); -assert.sameValue(result2.epochNanoseconds, 217_123_200_000_000_000n, "Calendar is case-insensitive (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.getInstantFor(arg); +assert.sameValue(result.epochNanoseconds, 217_123_200_000_000_000n, "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 8df2107ee8bd..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,25 +0,0 @@ -// 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: > - A Temporal.Calendar instance passed to getInstantFor() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.TimeZone("UTC"); - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -instance.getInstantFor(arg); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -instance.getInstantFor(arg); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-leap-second.js index 0e9d07bfb791..5701e251955b 100644 --- a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-leap-second.js @@ -11,18 +11,10 @@ const instance = new Temporal.TimeZone("UTC"); const calendar = "2016-12-31T23:59:60"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.getInstantFor(arg); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.getInstantFor(arg); assert.sameValue( - result1.epochNanoseconds, + result.epochNanoseconds, 217_123_200_000_000_000n, "leap second is a valid ISO string for calendar" ); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.getInstantFor(arg); -assert.sameValue( - result2.epochNanoseconds, - 217_123_200_000_000_000n, - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-number.js index 2d14c50ee38a..1de1dca472cf 100644 --- a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-number.js @@ -11,13 +11,9 @@ const instance = new Temporal.TimeZone("UTC"); const calendar = 19970327; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.getInstantFor(arg); -assert.sameValue(result1.epochNanoseconds, 217_123_200_000_000_000n, "19970327 is a valid ISO string for calendar"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.getInstantFor(arg); -assert.sameValue(result2.epochNanoseconds, 217_123_200_000_000_000n, "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.getInstantFor(arg); +assert.sameValue(result.epochNanoseconds, 217_123_200_000_000_000n, "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -26,16 +22,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; assert.throws( RangeError, () => instance.getInstantFor(arg), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.getInstantFor(arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-wrong-type.js index 576a7ff93cf2..6604b51fe76d 100644 --- a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-wrong-type.js @@ -21,27 +21,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.getInstantFor(arg), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.getInstantFor(arg), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.getInstantFor(arg), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.getInstantFor(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.getInstantFor(arg), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-string-calendar-annotation.js index 1ae9e99b8bfc..118f11679e7b 100644 --- a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-string-calendar-annotation.js @@ -13,7 +13,6 @@ const tests = [ ["1976-11-18T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["1976-11-18T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["1976-11-18T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["1976-11-18T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const instance = new Temporal.TimeZone("UTC"); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..1d1e6ef70f40 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 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: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.TimeZone("UTC"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.getInstantFor(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getInstantFor/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getInstantFor/order-of-operations.js index a4318a880f14..02f53ffbba34 100644 --- a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getInstantFor/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getInstantFor/order-of-operations.js @@ -9,9 +9,29 @@ features: [Temporal] ---*/ const expected = [ - // GetTemporalCalendarWithISODefault + // GetTemporalCalendarSlotValueWithISODefault "get fields.calendar", - "has fields.calendar.calendar", + "has fields.calendar.dateAdd", + "has fields.calendar.dateFromFields", + "has fields.calendar.dateUntil", + "has fields.calendar.day", + "has fields.calendar.dayOfWeek", + "has fields.calendar.dayOfYear", + "has fields.calendar.daysInMonth", + "has fields.calendar.daysInWeek", + "has fields.calendar.daysInYear", + "has fields.calendar.fields", + "has fields.calendar.id", + "has fields.calendar.inLeapYear", + "has fields.calendar.mergeFields", + "has fields.calendar.month", + "has fields.calendar.monthCode", + "has fields.calendar.monthDayFromFields", + "has fields.calendar.monthsInYear", + "has fields.calendar.weekOfYear", + "has fields.calendar.year", + "has fields.calendar.yearMonthFromFields", + "has fields.calendar.yearOfWeek", // CalendarFields "get fields.calendar.fields", "call fields.calendar.fields", diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getNextTransition/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getNextTransition/argument-string-calendar-annotation.js index e655390e68f0..db98cdb83d84 100644 --- a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getNextTransition/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getNextTransition/argument-string-calendar-annotation.js @@ -15,7 +15,6 @@ const tests = [ ["1970-01-01T00:00Z[u-ca=discord]", "annotation is ignored"], ["1970-01-01T00:00Z[!u-ca=discord]", "annotation with ! is ignored"], ["1970-01-01T00:00Z[u-ca=iso8601][u-ca=discord]", "two annotations are ignored"], - ["1970-01-01T00:00Z[u-ca=iso8601][!u-ca=discord]", "two annotations are ignored even with !"], ]; const instance = new Temporal.TimeZone("UTC"); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getNextTransition/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getNextTransition/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..5adbdb1fa981 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getNextTransition/argument-string-multiple-calendar.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getnexttransition +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01T00:00Z[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00Z[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00Z[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00Z[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.TimeZone("UTC"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.getNextTransition(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/argument-string-calendar-annotation.js index 8bb055bb2b7a..684f02a4788d 100644 --- a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/argument-string-calendar-annotation.js @@ -15,7 +15,6 @@ const tests = [ ["1970-01-01T00:00Z[u-ca=discord]", "annotation is ignored"], ["1970-01-01T00:00Z[!u-ca=discord]", "annotation with ! is ignored"], ["1970-01-01T00:00Z[u-ca=iso8601][u-ca=discord]", "two annotations are ignored"], - ["1970-01-01T00:00Z[u-ca=iso8601][!u-ca=discord]", "two annotations are ignored even with !"], ]; const instance = new Temporal.TimeZone("UTC"); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..4301e8e77b99 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/argument-string-multiple-calendar.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetnanosecondsfor +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01T00:00Z[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00Z[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00Z[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00Z[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.TimeZone("UTC"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.getOffsetNanosecondsFor(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-string-calendar-annotation.js index 17b5c0076e73..dfd5bc0d039c 100644 --- a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-string-calendar-annotation.js @@ -15,7 +15,6 @@ const tests = [ ["1970-01-01T00:00Z[u-ca=discord]", "annotation is ignored"], ["1970-01-01T00:00Z[!u-ca=discord]", "annotation with ! is ignored"], ["1970-01-01T00:00Z[u-ca=iso8601][u-ca=discord]", "two annotations are ignored"], - ["1970-01-01T00:00Z[u-ca=iso8601][!u-ca=discord]", "two annotations are ignored even with !"], ]; const instance = new Temporal.TimeZone("UTC"); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..d190bbdcdb9c --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/argument-string-multiple-calendar.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetstringfor +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01T00:00Z[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00Z[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00Z[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00Z[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.TimeZone("UTC"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.getOffsetStringFor(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-string-calendar-annotation.js index 4a7191a1464d..c5a032b40486 100644 --- a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-string-calendar-annotation.js @@ -16,7 +16,6 @@ const tests = [ ["1970-01-01T00:00Z[u-ca=discord]", "annotation is ignored"], ["1970-01-01T00:00Z[!u-ca=discord]", "annotation with ! is ignored"], ["1970-01-01T00:00Z[u-ca=iso8601][u-ca=discord]", "two annotations are ignored"], - ["1970-01-01T00:00Z[u-ca=iso8601][!u-ca=discord]", "two annotations are ignored even with !"], ]; const instance = new Temporal.TimeZone("UTC"); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..eeb2ce24b42b --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-string-multiple-calendar.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01T00:00Z[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00Z[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00Z[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00Z[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.TimeZone("UTC"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.getPlainDateTimeFor(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-case-insensitive.js index c7ae3d6e5fb9..0cc75d0e91a4 100644 --- a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-case-insensitive.js @@ -11,4 +11,4 @@ const instance = new Temporal.TimeZone("UTC"); const arg = "iSo8601"; const result = instance.getPlainDateTimeFor(new Temporal.Instant(0n), arg); -assert.sameValue(result.calendar.id, "iso8601", "Calendar is case-insensitive"); +assert.sameValue(result.calendarId, "iso8601", "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 6d6341a29ef6..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,22 +0,0 @@ -// 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.getplaindatetimefor -description: > - A Temporal.Calendar instance passed to getPlainDateTimeFor() does not have its - 'calendar' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.TimeZone("UTC"); - -const arg = new Temporal.Calendar("iso8601"); -Object.defineProperty(arg, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -instance.getPlainDateTimeFor(new Temporal.Instant(0n), arg); -instance.getPlainDateTimeFor(new Temporal.Instant(0n), { calendar: arg }); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-number.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-number.js index 97a6429cd5a2..f48725772e26 100644 --- a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-number.js @@ -12,7 +12,7 @@ const instance = new Temporal.TimeZone("UTC"); const arg = 19761118; const result = instance.getPlainDateTimeFor(new Temporal.Instant(0n), arg); -assert.sameValue(result.calendar.id, "iso8601", "19761118 is a valid ISO string for Calendar"); +assert.sameValue(result.calendarId, "iso8601", "19761118 is a valid ISO string for Calendar"); const numbers = [ 1, diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-string-leap-second.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-string-leap-second.js index 927df4900102..efd79853de26 100644 --- a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-string-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-string-leap-second.js @@ -9,18 +9,10 @@ features: [Temporal] const instance = new Temporal.TimeZone("UTC"); -let arg = "2016-12-31T23:59:60"; -const result1 = instance.getPlainDateTimeFor(new Temporal.Instant(0n), arg); +const arg = "2016-12-31T23:59:60"; +const result = instance.getPlainDateTimeFor(new Temporal.Instant(0n), arg); assert.sameValue( - result1.calendar.id, + result.calendarId, "iso8601", "leap second is a valid ISO string for Calendar" ); - -arg = { calendar: "2016-12-31T23:59:60" }; -const result2 = instance.getPlainDateTimeFor(new Temporal.Instant(0n), arg); -assert.sameValue( - result2.calendar.id, - "iso8601", - "leap second is a valid ISO string for Calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-string.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-string.js index f97f14a433ff..fe3d4932a2c9 100644 --- a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-string.js +++ b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-string.js @@ -12,4 +12,4 @@ const instance = new Temporal.TimeZone("UTC"); const arg = "iso8601"; const result = instance.getPlainDateTimeFor(new Temporal.Instant(0n), arg); -assert.sameValue(result.calendar.id, "iso8601", `Calendar created from string "${arg}"`); +assert.sameValue(result.getISOFields().calendar, "iso8601", `Calendar created from string "${arg}"`); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-temporal-object.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-temporal-object.js index 574bad04a378..345d50f60b3c 100644 --- a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-temporal-object.js +++ b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-temporal-object.js @@ -6,7 +6,7 @@ esid: sec-temporal.timezone.prototype.getplaindatetimefor description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots info: | sec-temporal-totemporalcalendar step 1.b: - b. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then + b. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then i. Return _temporalCalendarLike_.[[Calendar]]. includes: [compareArray.js] features: [Temporal] @@ -14,12 +14,11 @@ features: [Temporal] const plainDate = new Temporal.PlainDate(2000, 5, 2); const plainDateTime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); -const plainTime = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); const plainMonthDay = new Temporal.PlainMonthDay(5, 2); const plainYearMonth = new Temporal.PlainYearMonth(2000, 5); const zonedDateTime = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); -[plainDate, plainDateTime, plainTime, plainMonthDay, plainYearMonth, zonedDateTime].forEach((arg) => { +[plainDate, plainDateTime, plainMonthDay, plainYearMonth, zonedDateTime].forEach((arg) => { const actual = []; const expected = []; @@ -34,7 +33,7 @@ const zonedDateTime = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UT const instance = new Temporal.TimeZone("UTC"); const result = instance.getPlainDateTimeFor(new Temporal.Instant(0n), arg); - assert.sameValue(result.calendar, calendar, "Temporal object coerced to calendar"); + assert.sameValue(result.getISOFields().calendar, calendar, "Temporal object coerced to calendar"); assert.compareArray(actual, expected, "calendar getter not called"); }); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-undefined.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-undefined.js index 92add0be1c8c..6c0d705436f1 100644 --- a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-undefined.js +++ b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-undefined.js @@ -17,7 +17,7 @@ Object.defineProperty(Temporal.Calendar, "from", { }); const result1 = timeZone.getPlainDateTimeFor(instant); -assert.sameValue(result1.calendar.toString(), "iso8601"); +assert.sameValue(result1.calendarId, "iso8601"); const result2 = timeZone.getPlainDateTimeFor(instant, undefined); -assert.sameValue(result2.calendar.toString(), "iso8601"); +assert.sameValue(result2.calendarId, "iso8601"); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-wrong-type.js index 8c85e4e5d6e9..10b657796dda 100644 --- a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-wrong-type.js @@ -17,19 +17,19 @@ const rangeErrorTests = [ ["", "empty string"], [1, "number that doesn't convert to a valid ISO string"], [1n, "bigint"], - [new Temporal.TimeZone("UTC"), "time zone instance"], ]; for (const [arg, description] of rangeErrorTests) { assert.throws(RangeError, () => instance.getPlainDateTimeFor(new Temporal.Instant(0n), arg), `${description} does not convert to a valid ISO string`); - assert.throws(RangeError, () => instance.getPlainDateTimeFor(new Temporal.Instant(0n), { calendar: arg }), `${description} does not convert to a valid ISO string (in property bag)`); } const typeErrorTests = [ [Symbol(), "symbol"], + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], ]; for (const [arg, description] of typeErrorTests) { assert.throws(TypeError, () => instance.getPlainDateTimeFor(new Temporal.Instant(0n), arg), `${description} is not a valid object and does not convert to a string`); - assert.throws(TypeError, () => instance.getPlainDateTimeFor(new Temporal.Instant(0n), { calendar: arg }), `${description} is not a valid object and does not convert to a string (in property bag)`); } diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-case-insensitive.js index 51f74363b357..9c2c3cf78e90 100644 --- a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-case-insensitive.js @@ -12,10 +12,6 @@ const instance = new Temporal.TimeZone("UTC"); const calendar = "IsO8601"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.getPossibleInstantsFor(arg); -assert.compareArray(result1.map(i => i.epochNanoseconds), [217_123_200_000_000_000n], "Calendar is case-insensitive"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.getPossibleInstantsFor(arg); -assert.compareArray(result2.map(i => i.epochNanoseconds), [217_123_200_000_000_000n], "Calendar is case-insensitive (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.getPossibleInstantsFor(arg); +assert.compareArray(result.map(i => i.epochNanoseconds), [217_123_200_000_000_000n], "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index b0f380a15ba2..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,25 +0,0 @@ -// 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.getpossibleinstantsfor -description: > - A Temporal.Calendar instance passed to getPossibleInstantsFor() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.TimeZone("UTC"); - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -instance.getPossibleInstantsFor(arg); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -instance.getPossibleInstantsFor(arg); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-leap-second.js index 39b5d7ee9ef9..84de55acbc6f 100644 --- a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-leap-second.js @@ -12,18 +12,10 @@ const instance = new Temporal.TimeZone("UTC"); const calendar = "2016-12-31T23:59:60"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.getPossibleInstantsFor(arg); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.getPossibleInstantsFor(arg); assert.compareArray( - result1.map(i => i.epochNanoseconds), + result.map(i => i.epochNanoseconds), [217_123_200_000_000_000n], "leap second is a valid ISO string for calendar" ); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.getPossibleInstantsFor(arg); -assert.compareArray( - result2.map(i => i.epochNanoseconds), - [217_123_200_000_000_000n], - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-number.js index bee5a0819884..9e2821f5cd19 100644 --- a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-number.js @@ -12,13 +12,9 @@ const instance = new Temporal.TimeZone("UTC"); const calendar = 19970327; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.getPossibleInstantsFor(arg); -assert.compareArray(result1.map(i => i.epochNanoseconds), [217_123_200_000_000_000n], "19970327 is a valid ISO string for calendar"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.getPossibleInstantsFor(arg); -assert.compareArray(result2.map(i => i.epochNanoseconds), [217_123_200_000_000_000n], "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.getPossibleInstantsFor(arg); +assert.compareArray(result.map(i => i.epochNanoseconds), [217_123_200_000_000_000n], "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -27,16 +23,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; assert.throws( RangeError, () => instance.getPossibleInstantsFor(arg), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.getPossibleInstantsFor(arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-wrong-type.js index dd2a88d76e8a..ac83d439b105 100644 --- a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-wrong-type.js @@ -21,27 +21,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.getPossibleInstantsFor(arg), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.getPossibleInstantsFor(arg), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.getPossibleInstantsFor(arg), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.getPossibleInstantsFor(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.getPossibleInstantsFor(arg), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-string-calendar-annotation.js index 313685f5ba0c..4b18b0f3e45c 100644 --- a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-string-calendar-annotation.js @@ -14,7 +14,6 @@ const tests = [ ["1976-11-18T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["1976-11-18T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["1976-11-18T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["1976-11-18T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const instance = new Temporal.TimeZone("UTC"); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..6115c8e6d33b --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.TimeZone("UTC"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.getPossibleInstantsFor(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/fixed-offset-near-date-time-limits.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/fixed-offset-near-date-time-limits.js index 27d97938da4b..8aa1af729204 100644 --- a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/fixed-offset-near-date-time-limits.js +++ b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/fixed-offset-near-date-time-limits.js @@ -5,7 +5,7 @@ esid: sec-temporal.timezone.prototype.getpossibleinstantsfor description: > Call getPossibleInstantsFor with values near the date/time limit and a fixed offset. -features: [Temporal] +features: [Temporal, exponentiation] ---*/ const oneHour = 1n * 60n * 60n * 1000n**3n; diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/argument-string-calendar-annotation.js index e01352ea539e..6ede7be636fc 100644 --- a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/argument-string-calendar-annotation.js @@ -15,7 +15,6 @@ const tests = [ ["1970-01-01T00:00Z[u-ca=discord]", "annotation is ignored"], ["1970-01-01T00:00Z[!u-ca=discord]", "annotation with ! is ignored"], ["1970-01-01T00:00Z[u-ca=iso8601][u-ca=discord]", "two annotations are ignored"], - ["1970-01-01T00:00Z[u-ca=iso8601][!u-ca=discord]", "two annotations are ignored even with !"], ]; const instance = new Temporal.TimeZone("UTC"); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..090cfc0e4d35 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/argument-string-multiple-calendar.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getprevioustransition +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01T00:00Z[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00Z[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00Z[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00Z[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.TimeZone("UTC"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.getPreviousTransition(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/toJSON/returns-identifier-slot.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/toJSON/returns-identifier-slot.js new file mode 100644 index 000000000000..a15100c9325c --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/toJSON/returns-identifier-slot.js @@ -0,0 +1,23 @@ +// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.tojson +description: toJSON() returns the internal slot value +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const actual = []; + +const timeZone = new Temporal.TimeZone("UTC"); +TemporalHelpers.observeProperty(actual, timeZone, Symbol.toPrimitive, undefined); +TemporalHelpers.observeProperty(actual, timeZone, "id", "Etc/Bogus"); +TemporalHelpers.observeProperty(actual, timeZone, "toString", function () { + actual.push("call timeZone.toString"); + return "Etc/TAI"; +}); + +const result = timeZone.toJSON(); +assert.sameValue(result, "UTC", "toJSON gets the internal slot value"); +assert.compareArray(actual, [], "should not invoke any observable operations"); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/toJSON/tostring-call.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/toJSON/tostring-call.js deleted file mode 100644 index 2d59752680ff..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/toJSON/tostring-call.js +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (C) 2020 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.timezone.prototype.tojson -description: toJSON() calls toString() and returns its value -includes: [compareArray.js, temporalHelpers.js] -features: [Temporal] ----*/ - -const actual = []; -const expected = [ - 'get [Symbol.toPrimitive]', - 'get toString', - 'call timeZone.toString', -]; - -const timeZone = new Temporal.TimeZone("UTC"); -TemporalHelpers.observeProperty(actual, timeZone, Symbol.toPrimitive, undefined); -TemporalHelpers.observeProperty(actual, timeZone, "toString", function () { - actual.push("call timeZone.toString"); - return "Etc/TAI"; -}); - -const result = timeZone.toJSON(); -assert.sameValue(result, 'Etc/TAI', 'toString'); -assert.compareArray(actual, expected); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/toJSON/tostring-undefined-custom.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/toJSON/tostring-undefined-custom.js deleted file mode 100644 index bf9b82e08e63..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/toJSON/tostring-undefined-custom.js +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (C) 2020 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.timezone.prototype.tojson -description: TypeError thrown when toString property not present -includes: [compareArray.js, temporalHelpers.js] -features: [Temporal] ----*/ - -const actual = []; -const expected = [ - 'get [Symbol.toPrimitive]', - 'get toString', - 'get valueOf', -]; - -const timeZone = new Temporal.TimeZone("UTC"); -TemporalHelpers.observeProperty(actual, timeZone, Symbol.toPrimitive, undefined); -TemporalHelpers.observeProperty(actual, timeZone, "toString", undefined); -TemporalHelpers.observeProperty(actual, timeZone, "valueOf", Object.prototype.valueOf); - -assert.throws(TypeError, () => timeZone.toJSON()); -assert.compareArray(actual, expected); diff --git a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/toJSON/tostring-undefined.js b/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/toJSON/tostring-undefined.js deleted file mode 100644 index c0a9f0674122..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/TimeZone/prototype/toJSON/tostring-undefined.js +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (C) 2020 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.timezone.prototype.tojson -description: TypeError thrown when toString property not present -features: [Temporal] ----*/ - -const tz = Temporal.TimeZone.from('UTC'); -tz.toString = undefined; - -assert.throws(TypeError, () => tz.toJSON()); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/calendar-case-insensitive.js index a2c19488b2b6..f7b725c79776 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/calendar-case-insensitive.js @@ -10,4 +10,4 @@ features: [Temporal] const arg = "iSo8601"; const result = new Temporal.ZonedDateTime(0n, "UTC", arg); -assert.sameValue(result.calendar.id, "iso8601", "Calendar is case-insensitive"); +assert.sameValue(result.calendarId, "iso8601", "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 59cb9786ac9e..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,20 +0,0 @@ -// 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 -description: > - A Temporal.Calendar instance passed to new ZonedDateTime() does not have - its 'calendar' property observably checked -features: [Temporal] ----*/ - -const arg = new Temporal.Calendar("iso8601"); -Object.defineProperty(arg, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -new Temporal.ZonedDateTime(0n, "UTC", arg); -new Temporal.ZonedDateTime(0n, "UTC", { calendar: arg }); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/calendar-number.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/calendar-number.js index 889bf726c848..1d2409c1109e 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/calendar-number.js @@ -10,7 +10,7 @@ features: [Temporal] const arg = 19761118; const result = new Temporal.ZonedDateTime(0n, "UTC", arg); -assert.sameValue(result.calendar.id, "iso8601", "19761118 is a valid ISO string for Calendar"); +assert.sameValue(result.calendarId, "iso8601", "19761118 is a valid ISO string for Calendar"); const numbers = [ 1, diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/calendar-string.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/calendar-string.js index 783609253a54..35be85afebe7 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/calendar-string.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/calendar-string.js @@ -10,4 +10,4 @@ features: [Temporal] const arg = "iso8601"; const result = new Temporal.ZonedDateTime(0n, "UTC", arg); -assert.sameValue(result.calendar.id, "iso8601", `Calendar created from string "${arg}"`); +assert.sameValue(result.getISOFields().calendar, "iso8601", `Calendar created from string "${arg}"`); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/calendar-temporal-object.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/calendar-temporal-object.js index 8e1fba5d996b..4f423ba86e22 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/calendar-temporal-object.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/calendar-temporal-object.js @@ -6,7 +6,7 @@ esid: sec-temporal.zoneddatetime description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots info: | sec-temporal-totemporalcalendar step 1.b: - b. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then + b. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then i. Return _temporalCalendarLike_.[[Calendar]]. includes: [compareArray.js] features: [Temporal] @@ -14,12 +14,11 @@ features: [Temporal] const plainDate = new Temporal.PlainDate(2000, 5, 2); const plainDateTime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); -const plainTime = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); const plainMonthDay = new Temporal.PlainMonthDay(5, 2); const plainYearMonth = new Temporal.PlainYearMonth(2000, 5); const zonedDateTime = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); -[plainDate, plainDateTime, plainTime, plainMonthDay, plainYearMonth, zonedDateTime].forEach((arg) => { +[plainDate, plainDateTime, plainMonthDay, plainYearMonth, zonedDateTime].forEach((arg) => { const actual = []; const expected = []; @@ -33,7 +32,7 @@ const zonedDateTime = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UT }); const result = new Temporal.ZonedDateTime(0n, "UTC", arg); - assert.sameValue(result.calendar, calendar, "Temporal object coerced to calendar"); + assert.sameValue(result.getISOFields().calendar, calendar, "Temporal object coerced to calendar"); assert.compareArray(actual, expected, "calendar getter not called"); }); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/calendar-undefined.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/calendar-undefined.js index baaf93c7f0a4..0de531db8a7e 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/calendar-undefined.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/calendar-undefined.js @@ -16,7 +16,7 @@ Object.defineProperty(Temporal.Calendar, "from", { }); const explicit = new Temporal.ZonedDateTime(...args, undefined); -assert.sameValue(explicit.calendar.toString(), "iso8601"); +assert.sameValue(explicit.getISOFields().calendar, "iso8601", "calendar slot should store a string"); const implicit = new Temporal.ZonedDateTime(...args); -assert.sameValue(implicit.calendar.toString(), "iso8601"); +assert.sameValue(implicit.getISOFields().calendar, "iso8601", "calendar slot should store a string"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/calendar-wrong-type.js index 082c904fdabd..537bcca972b7 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/calendar-wrong-type.js @@ -23,6 +23,9 @@ for (const [arg, description] of rangeErrorTests) { const typeErrorTests = [ [Symbol(), "symbol"], + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], ]; for (const [arg, description] of typeErrorTests) { diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-case-insensitive.js index bae1a5f2fb19..986ede0cbc02 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-case-insensitive.js @@ -12,14 +12,8 @@ const calendar = "IsO8601"; const timeZone = new Temporal.TimeZone("UTC"); const datetime = new Temporal.ZonedDateTime(0n, timeZone); -let arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; +const arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; const result1 = Temporal.ZonedDateTime.compare(arg, datetime); assert.sameValue(result1, 0, "Calendar is case-insensitive (first argument)"); const result2 = Temporal.ZonedDateTime.compare(datetime, arg); assert.sameValue(result2, 0, "Calendar is case-insensitive (second argument)"); - -arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar: { calendar } }; -const result3 = Temporal.ZonedDateTime.compare(arg, datetime); -assert.sameValue(result3, 0, "Calendar is case-insensitive (nested property, first argument)"); -const result4 = Temporal.ZonedDateTime.compare(datetime, arg); -assert.sameValue(result4, 0, "Calendar is case-insensitive (nested property, second argument)"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 46e70fa546bb..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,21 +0,0 @@ -// 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: > - A Temporal.Calendar instance passed to compare() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -const timeZone = new Temporal.TimeZone("UTC"); -const arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; -Temporal.ZonedDateTime.compare(arg, arg); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-leap-second.js index 8a6c34e0b881..0bf607c3237f 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-leap-second.js @@ -11,14 +11,8 @@ const timeZone = new Temporal.TimeZone("UTC"); const datetime = new Temporal.ZonedDateTime(217_123_200_000_000_000n, timeZone); const calendar = "2016-12-31T23:59:60+00:00[UTC]"; -let arg = { year: 1976, monthCode: "M11", day: 18, timeZone, calendar }; +const arg = { year: 1976, monthCode: "M11", day: 18, timeZone, calendar }; const result1 = Temporal.ZonedDateTime.compare(arg, datetime); assert.sameValue(result1, 0, "leap second is a valid ISO string for calendar (first argument)"); const result2 = Temporal.ZonedDateTime.compare(datetime, arg); assert.sameValue(result2, 0, "leap second is a valid ISO string for calendar (second argument)"); - -arg = { year: 1976, monthCode: "M11", day: 18, timeZone, calendar: { calendar } }; -const result3 = Temporal.ZonedDateTime.compare(arg, datetime); -assert.sameValue(result3, 0, "leap second is a valid ISO string for calendar (nested property, first argument)"); -const result4 = Temporal.ZonedDateTime.compare(datetime, arg); -assert.sameValue(result4, 0, "leap second is a valid ISO string for calendar (nested property, second argument)"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-number.js index e75341024315..50cc9b4cb680 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-number.js @@ -12,18 +12,12 @@ const calendar = 19970327; const timeZone = new Temporal.TimeZone("UTC"); const datetime = new Temporal.ZonedDateTime(0n, timeZone); -let arg = { year: 1970, monthCode: "M01", day: 1, calendar, timeZone }; +const arg = { year: 1970, monthCode: "M01", day: 1, calendar, timeZone }; const result1 = Temporal.ZonedDateTime.compare(arg, datetime); assert.sameValue(result1, 0, "19970327 is a valid ISO string for calendar (first argument)"); const result2 = Temporal.ZonedDateTime.compare(datetime, arg); assert.sameValue(result2, 0, "19970327 is a valid ISO string for calendar (second argument)"); -arg = { year: 1970, monthCode: "M01", day: 1, calendar: { calendar }, timeZone }; -const result3 = Temporal.ZonedDateTime.compare(arg, datetime); -assert.sameValue(result3, 0, "19970327 is a valid ISO string for calendar (nested property, first argument)"); -const result4 = Temporal.ZonedDateTime.compare(datetime, arg); -assert.sameValue(result4, 0, "19970327 is a valid ISO string for calendar (nested property, second argument)"); - const numbers = [ 1, -19970327, @@ -31,7 +25,7 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 1970, monthCode: "M01", day: 1, calendar, timeZone }; + const arg = { year: 1970, monthCode: "M01", day: 1, calendar, timeZone }; assert.throws( RangeError, () => Temporal.ZonedDateTime.compare(arg, datetime), @@ -42,15 +36,4 @@ for (const calendar of numbers) { () => Temporal.ZonedDateTime.compare(datetime, arg), `Number ${calendar} does not convert to a valid ISO string for calendar (second argument)` ); - arg = { year: 1970, monthCode: "M01", day: 1, calendar: { calendar }, timeZone }; - assert.throws( - RangeError, - () => Temporal.ZonedDateTime.compare(arg, datetime), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property, first argument)` - ); - assert.throws( - RangeError, - () => Temporal.ZonedDateTime.compare(datetime, arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property, second argument)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-string.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-string.js index 07c9fa2e9717..d0208d54198b 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-string.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-string.js @@ -4,9 +4,19 @@ /*--- esid: sec-temporal.zoneddatetime.compare description: A calendar ID is valid input for Calendar +includes: [temporalHelpers.js] features: [Temporal] ---*/ +const dateFromFieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dateFromFields"); +Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("dateFromFields should not be looked up"); + }, +}); + const calendar = "iso8601"; const timeZone = new Temporal.TimeZone("UTC"); @@ -18,3 +28,5 @@ assert.sameValue(result1, 0, `Calendar created from string "${arg}" (first argum const result2 = Temporal.ZonedDateTime.compare(datetime, arg); assert.sameValue(result2, 0, `Calendar created from string "${arg}" (second argument)`); + +Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", dateFromFieldsOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-wrong-type.js index e226a10ddad3..b0a235e9396d 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-wrong-type.js @@ -17,36 +17,24 @@ const rangeErrorTests = [ ["", "empty string"], [1, "number that doesn't convert to a valid ISO string"], [1n, "bigint"], - [new Temporal.TimeZone("UTC"), "time zone instance"], ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => Temporal.ZonedDateTime.compare(arg, datetime), `${description} does not convert to a valid ISO string (first argument)`); assert.throws(RangeError, () => Temporal.ZonedDateTime.compare(datetime, arg), `${description} does not convert to a valid ISO string (second argument)`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => Temporal.ZonedDateTime.compare(arg, datetime), `${description} does not convert to a valid ISO string (nested property, first argument)`); - assert.throws(RangeError, () => Temporal.ZonedDateTime.compare(datetime, arg), `${description} does not convert to a valid ISO string (nested property, second argument)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => Temporal.ZonedDateTime.compare(arg, datetime), `${description} is not a valid property bag and does not convert to a string (first argument)`); assert.throws(TypeError, () => Temporal.ZonedDateTime.compare(datetime, arg), `${description} is not a valid property bag and does not convert to a string (second argument)`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => Temporal.ZonedDateTime.compare(arg, datetime), `${description} is not a valid property bag and does not convert to a string (nested property, first argument)`); - assert.throws(TypeError, () => Temporal.ZonedDateTime.compare(datetime, arg), `${description} is not a valid property bag and does not convert to a string (nested property, second argument)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => Temporal.ZonedDateTime.compare(arg, datetime), `nested undefined calendar property is always a RangeError (first argument)`); -assert.throws(RangeError, () => Temporal.ZonedDateTime.compare(datetime, arg), `nested undefined calendar property is always a RangeError (second argument)`); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-timezone-instance-does-not-get-timeZone-property.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-timezone-instance-does-not-get-timeZone-property.js deleted file mode 100644 index 0a2b360ac593..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-timezone-instance-does-not-get-timeZone-property.js +++ /dev/null @@ -1,23 +0,0 @@ -// 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: > - A Temporal.TimeZone instance passed to compare() does not have its - 'timeZone' property observably checked -features: [Temporal] ----*/ - -const timeZone = new Temporal.TimeZone("UTC"); -Object.defineProperty(timeZone, "timeZone", { - get() { - throw new Test262Error("timeZone.timeZone should not be accessed"); - }, -}); - -const arg1 = { year: 2020, month: 5, day: 2, timeZone }; -Temporal.ZonedDateTime.compare(arg1, arg1); - -const arg2 = { year: 2020, month: 5, day: 2, timeZone: { timeZone } }; -Temporal.ZonedDateTime.compare(arg2, arg2); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-timezone-string-datetime.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-timezone-string-datetime.js index e61d15819f33..27db89caecb3 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-timezone-string-datetime.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-timezone-string-datetime.js @@ -12,8 +12,6 @@ const instance = new Temporal.ZonedDateTime(0n, "UTC"); let timeZone = "2021-08-19T17:30"; assert.throws(RangeError, () => Temporal.ZonedDateTime.compare({ year: 2000, month: 5, day: 2, timeZone }, instance), "bare date-time string is not a time zone (arg 1)"); assert.throws(RangeError, () => Temporal.ZonedDateTime.compare(instance, { year: 2000, month: 5, day: 2, timeZone }), "bare date-time string is not a time zone (arg 2)"); -assert.throws(RangeError, () => Temporal.ZonedDateTime.compare({ year: 2000, month: 5, day: 2, timeZone: { timeZone } }, instance), "bare date-time string is not a time zone (arg 1)"); -assert.throws(RangeError, () => Temporal.ZonedDateTime.compare(instance, { year: 2000, month: 5, day: 2, timeZone: { timeZone } }), "bare date-time string is not a time zone (arg 2)"); // The following are all valid strings so should not throw: @@ -26,6 +24,4 @@ assert.throws(RangeError, () => Temporal.ZonedDateTime.compare(instance, { year: ].forEach((timeZone) => { Temporal.ZonedDateTime.compare({ year: 2000, month: 5, day: 2, timeZone }, instance); Temporal.ZonedDateTime.compare(instance, { year: 2000, month: 5, day: 2, timeZone }); - Temporal.ZonedDateTime.compare({ year: 2000, month: 5, day: 2, timeZone: { timeZone } }, instance); - Temporal.ZonedDateTime.compare(instance, { year: 2000, month: 5, day: 2, timeZone: { timeZone } }); }); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-timezone-string-leap-second.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-timezone-string-leap-second.js index 15726d7695e8..629490c71033 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-timezone-string-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-timezone-string-leap-second.js @@ -15,13 +15,7 @@ const result1 = Temporal.ZonedDateTime.compare({ year: 2020, month: 5, day: 2, t assert.sameValue(result1, 0, "leap second is a valid ISO string for TimeZone (first argument)"); const result2 = Temporal.ZonedDateTime.compare(instance, { year: 2020, month: 5, day: 2, timeZone }); assert.sameValue(result2, 0, "leap second is a valid ISO string for TimeZone (second argument)"); -const result3 = Temporal.ZonedDateTime.compare({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }, instance); -assert.sameValue(result3, 0, "leap second is a valid ISO string for TimeZone (nested property, first argument)"); -const result4 = Temporal.ZonedDateTime.compare(instance, { year: 2020, month: 5, day: 2, timeZone: { timeZone } }); -assert.sameValue(result4, 0, "leap second is a valid ISO string for TimeZone (nested property, second argument)"); timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; assert.throws(RangeError, () => Temporal.ZonedDateTime.compare({ year: 2020, month: 5, day: 2, timeZone }, instance), "leap second in time zone name not valid (first argument)"); assert.throws(RangeError, () => Temporal.ZonedDateTime.compare(instance, { year: 2020, month: 5, day: 2, timeZone }), "leap second in time zone name not valid (second argument)"); -assert.throws(RangeError, () => Temporal.ZonedDateTime.compare({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }, instance), "leap second in time zone name not valid (nested property, first argument)"); -assert.throws(RangeError, () => Temporal.ZonedDateTime.compare(instance, { year: 2020, month: 5, day: 2, timeZone: { timeZone } }), "leap second in time zone name not valid (nested property, second argument)"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-timezone-string-multiple-offsets.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-timezone-string-multiple-offsets.js new file mode 100644 index 000000000000..32c03c5f7e3c --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-timezone-string-multiple-offsets.js @@ -0,0 +1,17 @@ +// Copyright (C) 2021 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: Time zone strings with UTC offset fractional part are not confused with time fractional part +features: [Temporal] +---*/ + +const instance = new Temporal.ZonedDateTime(1588371269_012_345_679n, "+01:45:30.987654321"); + +const timeZone = "2021-08-19T17:30:45.123456789+01:46[+01:45:30.987654321]"; + +const result1 = Temporal.ZonedDateTime.compare({ year: 2020, month: 5, day: 2, timeZone }, instance); +assert.sameValue(result1, 0, "Time zone string determined from bracket name (first argument)"); +const result2 = Temporal.ZonedDateTime.compare(instance, { year: 2020, month: 5, day: 2, timeZone }); +assert.sameValue(result2, 0, "Time zone string determined from bracket name (first argument)"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-timezone-string-year-zero.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-timezone-string-year-zero.js index 7f170bfe7e6e..b5a4de63df23 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-timezone-string-year-zero.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-timezone-string-year-zero.js @@ -23,15 +23,4 @@ invalidStrings.forEach((timeZone) => { () => Temporal.ZonedDateTime.compare(datetime, { year: 2020, month: 5, day: 2, timeZone }), "reject minus zero as extended year (second argument)" ); - - assert.throws( - RangeError, - () => Temporal.ZonedDateTime.compare({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }, datetime), - "reject minus zero as extended year (nested property, first argument)" - ); - assert.throws( - RangeError, - () => Temporal.ZonedDateTime.compare(datetime, { year: 2020, month: 5, day: 2, timeZone: { timeZone } }), - "reject minus zero as extended year (nested property, second argument)" - ); }); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-timezone-string.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-timezone-string.js index 1a94c074a567..e5f1be57ffb4 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-timezone-string.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-timezone-string.js @@ -4,9 +4,27 @@ /*--- esid: sec-temporal.zoneddatetime.compare description: Time zone IDs are valid input for a time zone +includes: [temporalHelpers.js] features: [Temporal] ---*/ +const getPossibleInstantsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getPossibleInstantsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getPossibleInstantsFor should not be looked up"); + }, +}); +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + ["UTC", "+01:30"].forEach((timeZone) => { const epoch = new Temporal.ZonedDateTime(0n, new Temporal.TimeZone(timeZone)); @@ -14,3 +32,6 @@ features: [Temporal] Temporal.ZonedDateTime.compare({ year: 2020, month: 5, day: 2, timeZone }, epoch); Temporal.ZonedDateTime.compare(epoch, { year: 2020, month: 5, day: 2, timeZone }); }); + +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", getPossibleInstantsForOriginal); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-timezone-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-timezone-wrong-type.js index 6ba49eac3eae..12ae11172c70 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-timezone-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-timezone-wrong-type.js @@ -18,27 +18,20 @@ const rangeErrorTests = [ [1, "number that doesn't convert to a valid ISO string"], [19761118, "number that would convert to a valid ISO string in other contexts"], [1n, "bigint"], - [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of rangeErrorTests) { assert.throws(RangeError, () => Temporal.ZonedDateTime.compare({ year: 2020, month: 5, day: 2, timeZone }, datetime), `${description} does not convert to a valid ISO string (first argument)`); assert.throws(RangeError, () => Temporal.ZonedDateTime.compare(datetime, { year: 2020, month: 5, day: 2, timeZone }), `${description} does not convert to a valid ISO string (second argument)`); - assert.throws(RangeError, () => Temporal.ZonedDateTime.compare({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }, datetime), `${description} does not convert to a valid ISO string (nested property, first argument)`); - assert.throws(RangeError, () => Temporal.ZonedDateTime.compare(datetime, { year: 2020, month: 5, day: 2, timeZone: { timeZone } }), `${description} does not convert to a valid ISO string (nested property, second argument)`); } const typeErrorTests = [ [Symbol(), "symbol"], + [{}, "object not implementing time zone protocol"], + [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of typeErrorTests) { assert.throws(TypeError, () => Temporal.ZonedDateTime.compare({ year: 2020, month: 5, day: 2, timeZone }, datetime), `${description} is not a valid object and does not convert to a string (first argument)`); assert.throws(TypeError, () => Temporal.ZonedDateTime.compare(datetime, { year: 2020, month: 5, day: 2, timeZone }), `${description} is not a valid object and does not convert to a string (second argument)`); - assert.throws(TypeError, () => Temporal.ZonedDateTime.compare({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }, datetime), `${description} is not a valid object and does not convert to a string (nested property, first argument)`); - assert.throws(TypeError, () => Temporal.ZonedDateTime.compare(datetime, { year: 2020, month: 5, day: 2, timeZone: { timeZone } }), `${description} is not a valid object and does not convert to a string (nested property, second argument)`); } - -const timeZone = undefined; -assert.throws(RangeError, () => Temporal.ZonedDateTime.compare({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }, datetime), `undefined is always a RangeError as nested property (first argument)`); -assert.throws(RangeError, () => Temporal.ZonedDateTime.compare(datetime, { year: 2020, month: 5, day: 2, timeZone: { timeZone } }), `undefined is always a RangeError as nested property (second argument)`); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-string-calendar-annotation.js index 63075d2efa47..57b0ceff3c64 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-string-calendar-annotation.js @@ -11,7 +11,6 @@ const tests = [ ["1970-01-01T00:00[UTC][u-ca=iso8601]", "without !"], ["1970-01-01T00:00[UTC][!u-ca=iso8601]", "with !"], ["1970-01-01T00:00[UTC][u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; tests.forEach(([arg, description]) => { diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..bf1c1ebebb06 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/argument-string-multiple-calendar.js @@ -0,0 +1,31 @@ +// Copyright (C) 2023 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: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[UTC][!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; + +const datetime = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); + +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => Temporal.ZonedDateTime.compare(arg, datetime), + `reject more than one calendar annotation if any critical: ${arg} (first argument)` + ); + assert.throws( + RangeError, + () => Temporal.ZonedDateTime.compare(datetime, arg), + `reject more than one calendar annotation if any critical: ${arg} (second argument)` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/order-of-operations.js index a2318aee618f..1c64febece16 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/compare/order-of-operations.js @@ -10,7 +10,27 @@ features: [Temporal] const expected = [ "get one.calendar", - "has one.calendar.calendar", + "has one.calendar.dateAdd", + "has one.calendar.dateFromFields", + "has one.calendar.dateUntil", + "has one.calendar.day", + "has one.calendar.dayOfWeek", + "has one.calendar.dayOfYear", + "has one.calendar.daysInMonth", + "has one.calendar.daysInWeek", + "has one.calendar.daysInYear", + "has one.calendar.fields", + "has one.calendar.id", + "has one.calendar.inLeapYear", + "has one.calendar.mergeFields", + "has one.calendar.month", + "has one.calendar.monthCode", + "has one.calendar.monthDayFromFields", + "has one.calendar.monthsInYear", + "has one.calendar.weekOfYear", + "has one.calendar.year", + "has one.calendar.yearMonthFromFields", + "has one.calendar.yearOfWeek", "get one.calendar.fields", "call one.calendar.fields", // PrepareTemporalFields @@ -48,7 +68,9 @@ const expected = [ "get one.year", "get one.year.valueOf", "call one.year.valueOf", - "has one.timeZone.timeZone", + "has one.timeZone.getOffsetNanosecondsFor", + "has one.timeZone.getPossibleInstantsFor", + "has one.timeZone.id", // InterpretTemporalDateTimeFields "get one.calendar.dateFromFields", "call one.calendar.dateFromFields", @@ -59,7 +81,27 @@ const expected = [ "call one.timeZone.getOffsetNanosecondsFor", // Same set of operations, for the other argument: "get two.calendar", - "has two.calendar.calendar", + "has two.calendar.dateAdd", + "has two.calendar.dateFromFields", + "has two.calendar.dateUntil", + "has two.calendar.day", + "has two.calendar.dayOfWeek", + "has two.calendar.dayOfYear", + "has two.calendar.daysInMonth", + "has two.calendar.daysInWeek", + "has two.calendar.daysInYear", + "has two.calendar.fields", + "has two.calendar.id", + "has two.calendar.inLeapYear", + "has two.calendar.mergeFields", + "has two.calendar.month", + "has two.calendar.monthCode", + "has two.calendar.monthDayFromFields", + "has two.calendar.monthsInYear", + "has two.calendar.weekOfYear", + "has two.calendar.year", + "has two.calendar.yearMonthFromFields", + "has two.calendar.yearOfWeek", "get two.calendar.fields", "call two.calendar.fields", // PrepareTemporalFields @@ -97,7 +139,9 @@ const expected = [ "get two.year", "get two.year.valueOf", "call two.year.valueOf", - "has two.timeZone.timeZone", + "has two.timeZone.getOffsetNanosecondsFor", + "has two.timeZone.getPossibleInstantsFor", + "has two.timeZone.id", // InterpretTemporalDateTimeFields "get two.calendar.dateFromFields", "call two.calendar.dateFromFields", diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-case-insensitive.js index 4b270f898a25..2efae5a2ba3f 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-case-insensitive.js @@ -10,10 +10,6 @@ features: [Temporal] const calendar = "IsO8601"; const timeZone = new Temporal.TimeZone("UTC"); -let arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; -const result1 = Temporal.ZonedDateTime.from(arg); -assert.sameValue(result1.calendar.id, "iso8601", "Calendar is case-insensitive"); - -arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar: { calendar } }; -const result2 = Temporal.ZonedDateTime.from(arg); -assert.sameValue(result2.calendar.id, "iso8601", "Calendar is case-insensitive (nested property)"); +const arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; +const result = Temporal.ZonedDateTime.from(arg); +assert.sameValue(result.calendarId, "iso8601", "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 205bdabd9982..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,24 +0,0 @@ -// 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: > - A Temporal.Calendar instance passed to from() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -const timeZone = new Temporal.TimeZone("UTC"); -let arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; -Temporal.ZonedDateTime.from(arg); - -arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar: { calendar } }; -Temporal.ZonedDateTime.from(arg); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-leap-second.js index 2d68e15b7257..338a162ad5fa 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-leap-second.js @@ -10,18 +10,10 @@ features: [Temporal] const timeZone = new Temporal.TimeZone("UTC"); const calendar = "2016-12-31T23:59:60+00:00[UTC]"; -let arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; -const result1 = Temporal.ZonedDateTime.from(arg); +const arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; +const result = Temporal.ZonedDateTime.from(arg); assert.sameValue( - result1.calendar.id, + result.calendarId, "iso8601", "leap second is a valid ISO string for calendar" ); - -arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar: { calendar } }; -const result2 = Temporal.ZonedDateTime.from(arg); -assert.sameValue( - result2.calendar.id, - "iso8601", - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-number.js index 58775d77ae54..750cbeda5d7b 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-number.js @@ -10,13 +10,9 @@ features: [Temporal] const calendar = 19970327; const timeZone = new Temporal.TimeZone("UTC"); -let arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; -const result1 = Temporal.ZonedDateTime.from(arg); -assert.sameValue(result1.calendar.id, "iso8601", "19970327 is a valid ISO string for calendar"); - -arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar: { calendar } }; -const result2 = Temporal.ZonedDateTime.from(arg); -assert.sameValue(result2.calendar.id, "iso8601", "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; +const result = Temporal.ZonedDateTime.from(arg); +assert.sameValue(result.calendarId, "iso8601", "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -25,16 +21,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; + const arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; assert.throws( RangeError, () => Temporal.ZonedDateTime.from(arg), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar: { calendar } }; - assert.throws( - RangeError, - () => Temporal.ZonedDateTime.from(arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-string.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-string.js index bbaff1285fc2..c9d1b7bddb93 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-string.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-string.js @@ -12,4 +12,5 @@ const calendar = "iso8601"; const timeZone = new Temporal.TimeZone("UTC"); const arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; const result = Temporal.ZonedDateTime.from(arg); -assert.sameValue(result.calendar.id, "iso8601", `Calendar created from string "${calendar}"`); +assert.sameValue(result.calendarId, "iso8601", `Calendar created from string "${calendar}"`); +assert.sameValue(result.getISOFields().calendar, "iso8601", "calendar slot stores a string"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-wrong-type.js index fc1dfa9604f5..c2b810525f25 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-wrong-type.js @@ -18,27 +18,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => Temporal.ZonedDateTime.from(arg), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => Temporal.ZonedDateTime.from(arg), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => Temporal.ZonedDateTime.from(arg), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => Temporal.ZonedDateTime.from(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => Temporal.ZonedDateTime.from(arg), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-instance-does-not-get-timeZone-property.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-instance-does-not-get-timeZone-property.js deleted file mode 100644 index b8edbb9bd59a..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-instance-does-not-get-timeZone-property.js +++ /dev/null @@ -1,20 +0,0 @@ -// 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: > - A Temporal.TimeZone instance passed to from() does not have its - 'timeZone' property observably checked -features: [Temporal] ----*/ - -const timeZone = new Temporal.TimeZone("UTC"); -Object.defineProperty(timeZone, "timeZone", { - get() { - throw new Test262Error("timeZone.timeZone should not be accessed"); - }, -}); - -Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone }); -Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone: { timeZone } }); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-string-datetime.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-string-datetime.js index c75c47dddafc..174134875110 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-string-datetime.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-string-datetime.js @@ -9,34 +9,23 @@ features: [Temporal] let timeZone = "2021-08-19T17:30"; assert.throws(RangeError, () => Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone }), "bare date-time string is not a time zone"); -assert.throws(RangeError, () => Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone: { timeZone } }), "bare date-time string is not a time zone"); timeZone = "2021-08-19T17:30Z"; const result1 = Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone }); -assert.sameValue(result1.timeZone.id, "UTC", "date-time + Z is UTC time zone"); -const result2 = Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone: { timeZone } }); -assert.sameValue(result2.timeZone.id, "UTC", "date-time + Z is UTC time zone (string in property bag)"); +assert.sameValue(result1.timeZoneId, "UTC", "date-time + Z is UTC time zone"); timeZone = "2021-08-19T17:30-07:00"; -const result3 = Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone }); -assert.sameValue(result3.timeZone.id, "-07:00", "date-time + offset is the offset time zone"); -const result4 = Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone: { timeZone } }); -assert.sameValue(result4.timeZone.id, "-07:00", "date-time + offset is the offset time zone (string in property bag)"); +const result2 = Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone }); +assert.sameValue(result2.timeZoneId, "-07:00", "date-time + offset is the offset time zone"); timeZone = "2021-08-19T17:30[UTC]"; -const result5 = Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone }); -assert.sameValue(result5.timeZone.id, "UTC", "date-time + IANA annotation is the IANA time zone"); -const result6 = Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone: { timeZone } }); -assert.sameValue(result6.timeZone.id, "UTC", "date-time + IANA annotation is the IANA time zone (string in property bag)"); +const result3 = Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone }); +assert.sameValue(result3.timeZoneId, "UTC", "date-time + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30Z[UTC]"; -const result7 = Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone }); -assert.sameValue(result7.timeZone.id, "UTC", "date-time + Z + IANA annotation is the IANA time zone"); -const result8 = Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone: { timeZone } }); -assert.sameValue(result8.timeZone.id, "UTC", "date-time + Z + IANA annotation is the IANA time zone (string in property bag)"); +const result4 = Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone }); +assert.sameValue(result4.timeZoneId, "UTC", "date-time + Z + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30-07:00[UTC]"; -const result9 = Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone }); -assert.sameValue(result9.timeZone.id, "UTC", "date-time + offset + IANA annotation is the IANA time zone"); -const result10 = Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone: { timeZone } }); -assert.sameValue(result10.timeZone.id, "UTC", "date-time + offset + IANA annotation is the IANA time zone (string in property bag)"); +const result5 = Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone }); +assert.sameValue(result5.timeZoneId, "UTC", "date-time + offset + IANA annotation is the IANA time zone"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-string-leap-second.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-string-leap-second.js index 2b2a9eb311d8..c117fbd77618 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-string-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-string-leap-second.js @@ -9,11 +9,8 @@ features: [Temporal] let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; -const result1 = Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone }); -assert.sameValue(result1.timeZone.id, "UTC", "leap second is a valid ISO string for TimeZone"); -const result2 = Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone: { timeZone } }); -assert.sameValue(result2.timeZone.id, "UTC", "leap second is a valid ISO string for TimeZone (nested property)"); +const result = Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone }); +assert.sameValue(result.timeZoneId, "UTC", "leap second is a valid ISO string for TimeZone"); timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; assert.throws(RangeError, () => Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone }), "leap second in time zone name not valid"); -assert.throws(RangeError, () => Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone: { timeZone } }), "leap second in time zone name not valid (nested property)"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-string-multiple-offsets.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-string-multiple-offsets.js index 5b6d5264c61d..0ed9870136ab 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-string-multiple-offsets.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-string-multiple-offsets.js @@ -9,7 +9,5 @@ features: [Temporal] const timeZone = "2021-08-19T17:30:45.123456789+01:46[+01:45:30.987654321]"; -const result1 = Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone }); -assert.sameValue(result1.timeZone.id, "+01:45:30.987654321", "Time zone string determined from bracket name"); -const result2 = Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone: { timeZone } }); -assert.sameValue(result2.timeZone.id, "+01:45:30.987654321", "Time zone string determined from bracket name"); +const result = Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone }); +assert.sameValue(result.timeZoneId, "+01:45:30.987654321", "Time zone string determined from bracket name"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-string-year-zero.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-string-year-zero.js index 0065848f01c6..9f0328fcb5ec 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-string-year-zero.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-string-year-zero.js @@ -17,9 +17,4 @@ invalidStrings.forEach((timeZone) => { () => Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone }), "reject minus zero as extended year" ); - assert.throws( - RangeError, - () => Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone: { timeZone } }), - "reject minus zero as extended year (nested property)" - ); }); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-string.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-string.js index c0736cd2354d..a0a4175926e2 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-string.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-string.js @@ -4,10 +4,31 @@ /*--- esid: sec-temporal.zoneddatetime.from description: Time zone IDs are valid input for a time zone +includes: [temporalHelpers.js] features: [Temporal] ---*/ +const getPossibleInstantsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getPossibleInstantsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getPossibleInstantsFor should not be looked up"); + }, +}); +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + ["UTC", "+01:30"].forEach((timeZone) => { const result = Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone }); - assert.sameValue(result.timeZone.id, timeZone, `Time zone created from string "${timeZone}"`); + assert.sameValue(result.getISOFields().timeZone, timeZone, `Time zone created from string "${timeZone}"`); }); + +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", getPossibleInstantsForOriginal); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-wrong-type.js index a879d7f7565a..d4e814ebbe5e 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-wrong-type.js @@ -16,22 +16,18 @@ const rangeErrorTests = [ [1, "number that doesn't convert to a valid ISO string"], [19761118, "number that would convert to a valid ISO string in other contexts"], [1n, "bigint"], - [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of rangeErrorTests) { assert.throws(RangeError, () => Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone }), `${description} does not convert to a valid ISO string`); - assert.throws(RangeError, () => Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone: { timeZone } }), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], + [{}, "object not implementing time zone protocol"], + [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of typeErrorTests) { assert.throws(TypeError, () => Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone }), `${description} is not a valid object and does not convert to a string`); - assert.throws(TypeError, () => Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone: { timeZone } }), `${description} is not a valid object and does not convert to a string (nested property)`); } - -const timeZone = undefined; -assert.throws(RangeError, () => Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone: { timeZone } }), `undefined is always a RangeError as nested property`); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-string-calendar-annotation.js index 8bf82dcaf1c8..197ef49f8e7c 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-string-calendar-annotation.js @@ -11,15 +11,10 @@ const tests = [ ["1970-01-01T00:00[UTC][u-ca=iso8601]", "without !"], ["1970-01-01T00:00[UTC][!u-ca=iso8601]", "with !"], ["1970-01-01T00:00[UTC][u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; tests.forEach(([arg, description]) => { const result = Temporal.ZonedDateTime.from(arg); - assert.sameValue( - result.calendar.toString(), - "iso8601", - `calendar annotation (${description})` - ); + assert.sameValue(result.calendarId, "iso8601", `calendar annotation (${description})`); }); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-string-date-with-utc-offset.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-string-date-with-utc-offset.js index eab1c442029a..f9079bf64123 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-string-date-with-utc-offset.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-string-date-with-utc-offset.js @@ -18,7 +18,7 @@ for (const arg of validStrings) { const result = Temporal.ZonedDateTime.from(arg); assert.sameValue( - result.timeZone.toString(), + result.timeZoneId, "UTC", `"${arg}" is a valid UTC offset with time for ZonedDateTime` ); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..996aa7ddcf60 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-string-multiple-calendar.js @@ -0,0 +1,24 @@ +// Copyright (C) 2023 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: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[UTC][!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; + +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => Temporal.ZonedDateTime.from(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-string-time-separators.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-string-time-separators.js index f92d64127e0d..4225d68b9f76 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-string-time-separators.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-string-time-separators.js @@ -17,7 +17,7 @@ tests.forEach(([arg, description]) => { const result = Temporal.ZonedDateTime.from(arg); assert.sameValue( - result.timeZone.toString(), + result.timeZoneId, "UTC", `variant time separators (${description})` ); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-string-time-zone-annotation.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-string-time-zone-annotation.js index 22f081061e96..ccfa4a8a4fc6 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-string-time-zone-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-string-time-zone-annotation.js @@ -26,7 +26,7 @@ tests.forEach(([arg, expectedZone, description]) => { const result = Temporal.ZonedDateTime.from(arg); assert.sameValue( - result.timeZone.toString(), + result.timeZoneId, expectedZone, `time zone annotation (${description})` ); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-zoneddatetime.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-zoneddatetime.js index eb1c6c67ae1d..d1452483ceb5 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-zoneddatetime.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/argument-zoneddatetime.js @@ -12,7 +12,7 @@ const result = Temporal.ZonedDateTime.from(orig); assert.sameValue(result.epochNanoseconds, 946684800_000_000_010n, "ZonedDateTime is copied"); assert.sameValue(result.timeZone, orig.timeZone, "time zone is the same"); -assert.sameValue(result.calendar, orig.calendar, "calendar is the same"); +assert.sameValue(result.getISOFields().calendar, orig.getISOFields().calendar, "calendar is the same"); assert.notSameValue( result, diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/calendar-temporal-object.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/calendar-temporal-object.js index 60ffe57b2123..0489c499255f 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/calendar-temporal-object.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/calendar-temporal-object.js @@ -22,5 +22,5 @@ features: [Temporal] TemporalHelpers.checkToTemporalCalendarFastPath((temporalObject, calendar) => { const result = Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone: "UTC", calendar: temporalObject }); - assert.sameValue(result.calendar, calendar, "Temporal object coerced to calendar"); + assert.sameValue(result.getCalendar(), calendar, "Temporal object coerced to calendar"); }); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/order-of-operations.js index 2fc0b85b7d52..3e9a74abab64 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/order-of-operations.js @@ -10,7 +10,27 @@ features: [Temporal] const expected = [ "get item.calendar", - "has item.calendar.calendar", + "has item.calendar.dateAdd", + "has item.calendar.dateFromFields", + "has item.calendar.dateUntil", + "has item.calendar.day", + "has item.calendar.dayOfWeek", + "has item.calendar.dayOfYear", + "has item.calendar.daysInMonth", + "has item.calendar.daysInWeek", + "has item.calendar.daysInYear", + "has item.calendar.fields", + "has item.calendar.id", + "has item.calendar.inLeapYear", + "has item.calendar.mergeFields", + "has item.calendar.month", + "has item.calendar.monthCode", + "has item.calendar.monthDayFromFields", + "has item.calendar.monthsInYear", + "has item.calendar.weekOfYear", + "has item.calendar.year", + "has item.calendar.yearMonthFromFields", + "has item.calendar.yearOfWeek", "get item.calendar.fields", "call item.calendar.fields", // PrepareTemporalFields @@ -48,7 +68,9 @@ const expected = [ "get item.year", "get item.year.valueOf", "call item.year.valueOf", - "has item.timeZone.timeZone", + "has item.timeZone.getOffsetNanosecondsFor", + "has item.timeZone.getPossibleInstantsFor", + "has item.timeZone.id", // InterpretTemporalDateTimeFields "get options.disambiguation", "get options.disambiguation.toString", diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/timezone-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/timezone-case-insensitive.js index c6b4dec2e32a..a90581a8cc2b 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/timezone-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/timezone-case-insensitive.js @@ -9,4 +9,4 @@ features: [Temporal] const timeZone = 'uTc'; const result = Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone }); -assert.sameValue(result.timeZone.id, 'UTC', `Time zone created from string "${timeZone}"`); +assert.sameValue(result.timeZoneId, 'UTC', `Time zone created from string "${timeZone}"`); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/zoneddatetime-string-multiple-offsets.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/zoneddatetime-string-multiple-offsets.js index 06191770f62c..5ceb088ed2d7 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/zoneddatetime-string-multiple-offsets.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/zoneddatetime-string-multiple-offsets.js @@ -10,4 +10,4 @@ features: [Temporal] const str = "1970-01-01T00:02:00.000000000+00:02[+00:01:30.987654321]"; const result = Temporal.ZonedDateTime.from(str); -assert.sameValue(result.timeZone.toString(), "+00:01:30.987654321", "Time zone determined from bracket name"); +assert.sameValue(result.timeZoneId, "+00:01:30.987654321", "Time zone determined from bracket name"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/zoneddatetime-string.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/zoneddatetime-string.js index 1002c2e669cd..e49bd3cc4994 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/zoneddatetime-string.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/from/zoneddatetime-string.js @@ -17,21 +17,21 @@ assert.throws(RangeError, () => Temporal.ZonedDateTime.from(str), "date-time + o str = "1970-01-01T00:00[+01:00]"; const result1 = Temporal.ZonedDateTime.from(str); assert.sameValue(result1.epochNanoseconds, -3600_000_000_000n, "date-time + IANA annotation preserves wall time in the time zone"); -assert.sameValue(result1.timeZone.toString(), "+01:00", "IANA annotation is not ignored"); +assert.sameValue(result1.timeZoneId, "+01:00", "IANA annotation is not ignored"); str = "1970-01-01T00:00Z[+01:00]"; const result2 = Temporal.ZonedDateTime.from(str); assert.sameValue(result2.epochNanoseconds, 0n, "date-time + Z + IANA annotation preserves exact time in the time zone"); -assert.sameValue(result2.timeZone.toString(), "+01:00", "IANA annotation is not ignored"); +assert.sameValue(result2.timeZoneId, "+01:00", "IANA annotation is not ignored"); str = "1970-01-01T00:00+01:00[+01:00]"; const result3 = Temporal.ZonedDateTime.from(str); assert.sameValue(result3.epochNanoseconds, -3600_000_000_000n, "date-time + offset + IANA annotation ensures both exact and wall time match"); -assert.sameValue(result3.timeZone.toString(), "+01:00", "IANA annotation is not ignored"); +assert.sameValue(result3.timeZoneId, "+01:00", "IANA annotation is not ignored"); str = "1970-01-01T00:00-04:15[+01:00]"; assert.throws(RangeError, () => Temporal.ZonedDateTime.from(str), "date-time + offset + IANA annotation throws if wall time and exact time mismatch"); assert.throws(RangeError, () => Temporal.ZonedDateTime.from(str, { offset: "reject" }), "date-time + offset + IANA annotation throws if wall time and exact time mismatch (explicit reject option)"); const result4 = Temporal.ZonedDateTime.from(str, { offset: "ignore" }); assert.sameValue(result4.epochNanoseconds, -3600_000_000_000n, "date-time + wrong offset + IANA annotation preserves wall time in the time zone (offset: ignore option)"); -assert.sameValue(result4.timeZone.toString(), "+01:00", "IANA annotation is not ignored"); +assert.sameValue(result4.timeZoneId, "+01:00", "IANA annotation is not ignored"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/add/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/add/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..a196a45ce33d --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/add/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 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: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const dateAddOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dateAdd"); +Object.defineProperty(Temporal.Calendar.prototype, "dateAdd", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("dateAdd should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.add(new Temporal.Duration(1)); + +Object.defineProperty(Temporal.Calendar.prototype, "dateAdd", dateAddOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/add/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/add/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..9e5e22d980fb --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/add/builtin-timezone-no-observable-calls.js @@ -0,0 +1,34 @@ +// Copyright (C) 2023 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: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); +const getPossibleInstantsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getPossibleInstantsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getPossibleInstantsFor should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.add(new Temporal.Duration(1)); + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", getPossibleInstantsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/calendar/branding.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/calendar/branding.js deleted file mode 100644 index ba792ca71a5d..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/calendar/branding.js +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-get-temporal.zoneddatetime.prototype.calendar -description: Throw a TypeError if the receiver is invalid -features: [Symbol, Temporal] ----*/ - -const calendar = Object.getOwnPropertyDescriptor(Temporal.ZonedDateTime.prototype, "calendar").get; - -assert.sameValue(typeof calendar, "function"); - -assert.throws(TypeError, () => calendar.call(undefined), "undefined"); -assert.throws(TypeError, () => calendar.call(null), "null"); -assert.throws(TypeError, () => calendar.call(true), "true"); -assert.throws(TypeError, () => calendar.call(""), "empty string"); -assert.throws(TypeError, () => calendar.call(Symbol()), "symbol"); -assert.throws(TypeError, () => calendar.call(1), "1"); -assert.throws(TypeError, () => calendar.call({}), "plain object"); -assert.throws(TypeError, () => calendar.call(Temporal.ZonedDateTime), "Temporal.ZonedDateTime"); -assert.throws(TypeError, () => calendar.call(Temporal.ZonedDateTime.prototype), "Temporal.ZonedDateTime.prototype"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/calendar/prop-desc.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/calendar/prop-desc.js deleted file mode 100644 index 323413d3c14f..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/calendar/prop-desc.js +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-get-temporal.zoneddatetime.prototype.calendar -description: The "calendar" property of Temporal.ZonedDateTime.prototype -features: [Temporal] ----*/ - -const descriptor = Object.getOwnPropertyDescriptor(Temporal.ZonedDateTime.prototype, "calendar"); -assert.sameValue(typeof descriptor.get, "function"); -assert.sameValue(descriptor.set, undefined); -assert.sameValue(descriptor.enumerable, false); -assert.sameValue(descriptor.configurable, true); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/calendarId/branding.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/calendarId/branding.js new file mode 100644 index 000000000000..813bf47808d6 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/calendarId/branding.js @@ -0,0 +1,22 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-get-temporal.zoneddatetime.prototype.calendarid +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const calendarId = Object.getOwnPropertyDescriptor(Temporal.ZonedDateTime.prototype, "calendarId").get; + +assert.sameValue(typeof calendarId, "function"); + +assert.throws(TypeError, () => calendarId.call(undefined), "undefined"); +assert.throws(TypeError, () => calendarId.call(null), "null"); +assert.throws(TypeError, () => calendarId.call(true), "true"); +assert.throws(TypeError, () => calendarId.call(""), "empty string"); +assert.throws(TypeError, () => calendarId.call(Symbol()), "symbol"); +assert.throws(TypeError, () => calendarId.call(1), "1"); +assert.throws(TypeError, () => calendarId.call({}), "plain object"); +assert.throws(TypeError, () => calendarId.call(Temporal.ZonedDateTime), "Temporal.ZonedDateTime"); +assert.throws(TypeError, () => calendarId.call(Temporal.ZonedDateTime.prototype), "Temporal.ZonedDateTime.prototype"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/calendarId/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/calendarId/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..76826e23669c --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/calendarId/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.calendarid +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const idOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "id"); +Object.defineProperty(Temporal.Calendar.prototype, "id", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("id should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.calendarId; + +Object.defineProperty(Temporal.Calendar.prototype, "id", idOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/calendarId/prop-desc.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/calendarId/prop-desc.js new file mode 100644 index 000000000000..93cad46ad644 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/calendarId/prop-desc.js @@ -0,0 +1,14 @@ +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-get-temporal.zoneddatetime.prototype.calendarid +description: The "calendarId" property of Temporal.ZonedDateTime.prototype +features: [Temporal] +---*/ + +const descriptor = Object.getOwnPropertyDescriptor(Temporal.ZonedDateTime.prototype, "calendarId"); +assert.sameValue(typeof descriptor.get, "function"); +assert.sameValue(descriptor.set, undefined); +assert.sameValue(descriptor.enumerable, false); +assert.sameValue(descriptor.configurable, true); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/day/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/day/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..0d706f0fca7c --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/day/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.day +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const dayOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "day"); +Object.defineProperty(Temporal.Calendar.prototype, "day", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("day should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.day; + +Object.defineProperty(Temporal.Calendar.prototype, "day", dayOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/day/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/day/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..46c6ed54eb4f --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/day/builtin-timezone-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.day +description: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.day; + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/dayOfWeek/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/dayOfWeek/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..d041f62ae8cf --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/dayOfWeek/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.dayofweek +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const dayOfWeekOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dayOfWeek"); +Object.defineProperty(Temporal.Calendar.prototype, "dayOfWeek", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("dayOfWeek should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.dayOfWeek; + +Object.defineProperty(Temporal.Calendar.prototype, "dayOfWeek", dayOfWeekOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/dayOfWeek/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/dayOfWeek/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..935614eff315 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/dayOfWeek/builtin-timezone-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.dayofweek +description: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.dayOfWeek; + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/dayOfYear/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/dayOfYear/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..56b34eaa1366 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/dayOfYear/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.dayofyear +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const dayOfYearOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dayOfYear"); +Object.defineProperty(Temporal.Calendar.prototype, "dayOfYear", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("dayOfYear should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.dayOfYear; + +Object.defineProperty(Temporal.Calendar.prototype, "dayOfYear", dayOfYearOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/dayOfYear/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/dayOfYear/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..dec583d631b7 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/dayOfYear/builtin-timezone-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.dayofyear +description: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.dayOfYear; + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/daysInMonth/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/daysInMonth/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..29b0f586f357 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/daysInMonth/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.daysinmonth +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const daysInMonthOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "daysInMonth"); +Object.defineProperty(Temporal.Calendar.prototype, "daysInMonth", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("daysInMonth should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.daysInMonth; + +Object.defineProperty(Temporal.Calendar.prototype, "daysInMonth", daysInMonthOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/daysInMonth/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/daysInMonth/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..80b9481e4ccf --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/daysInMonth/builtin-timezone-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.daysinmonth +description: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.daysInMonth; + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/daysInWeek/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/daysInWeek/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..6063de158379 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/daysInWeek/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.daysinweek +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const daysInWeekOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "daysInWeek"); +Object.defineProperty(Temporal.Calendar.prototype, "daysInWeek", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("daysInWeek should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.daysInWeek; + +Object.defineProperty(Temporal.Calendar.prototype, "daysInWeek", daysInWeekOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/daysInWeek/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/daysInWeek/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..ef010891d51f --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/daysInWeek/builtin-timezone-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.daysinweek +description: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.daysInWeek; + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/daysInYear/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/daysInYear/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..b9488ccda69e --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/daysInYear/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.daysinyear +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const daysInYearOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "daysInYear"); +Object.defineProperty(Temporal.Calendar.prototype, "daysInYear", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("daysInYear should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.daysInYear; + +Object.defineProperty(Temporal.Calendar.prototype, "daysInYear", daysInYearOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/daysInYear/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/daysInYear/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..bd57ba806187 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/daysInYear/builtin-timezone-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.daysinyear +description: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.daysInYear; + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/epochMicroseconds/basic.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/epochMicroseconds/basic.js index 2c31cef34a26..33844e45f4b4 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/epochMicroseconds/basic.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/epochMicroseconds/basic.js @@ -12,5 +12,5 @@ assert.sameValue(afterEpoch.epochMicroseconds, 217175010_123_456n, "epochMicrose assert.sameValue(typeof afterEpoch.epochMicroseconds, "bigint", "epochMicroseconds value is a bigint"); const beforeEpoch = new Temporal.ZonedDateTime(-217175010_876_543_211n, "UTC"); -assert.sameValue(beforeEpoch.epochMicroseconds, -217175010_876_543n, "epochMicroseconds pre epoch"); +assert.sameValue(beforeEpoch.epochMicroseconds, -217175010_876_544n, "epochMicroseconds pre epoch"); assert.sameValue(typeof beforeEpoch.epochMicroseconds, "bigint", "epochMicroseconds value is a bigint"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/epochMilliseconds/basic.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/epochMilliseconds/basic.js index 2208a5cb8ce6..9fc2b0e316bc 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/epochMilliseconds/basic.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/epochMilliseconds/basic.js @@ -12,5 +12,5 @@ assert.sameValue(afterEpoch.epochMilliseconds, 217175010_123, "epochMilliseconds assert.sameValue(typeof afterEpoch.epochMilliseconds, "number", "epochMilliseconds value is a number"); const beforeEpoch = new Temporal.ZonedDateTime(-217175010_876_543_211n, "UTC"); -assert.sameValue(beforeEpoch.epochMilliseconds, -217175010_876, "epochMilliseconds pre epoch"); +assert.sameValue(beforeEpoch.epochMilliseconds, -217175010_877, "epochMilliseconds pre epoch"); assert.sameValue(typeof beforeEpoch.epochMilliseconds, "number", "epochMilliseconds value is a number"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/epochSeconds/basic.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/epochSeconds/basic.js index 651c254f89de..7e693d15a0cc 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/epochSeconds/basic.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/epochSeconds/basic.js @@ -12,5 +12,5 @@ assert.sameValue(afterEpoch.epochSeconds, 217175010, "epochSeconds post epoch"); assert.sameValue(typeof afterEpoch.epochSeconds, "number", "epochSeconds value is a number"); const beforeEpoch = new Temporal.ZonedDateTime(-217175010_876_543_211n, "UTC"); -assert.sameValue(beforeEpoch.epochSeconds, -217175010, "epochSeconds pre epoch"); +assert.sameValue(beforeEpoch.epochSeconds, -217175011, "epochSeconds pre epoch"); assert.sameValue(typeof beforeEpoch.epochSeconds, "number", "epochSeconds value is a number"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-case-insensitive.js index d571f91a7c63..b4f97b662994 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-case-insensitive.js @@ -12,10 +12,6 @@ const instance = new Temporal.ZonedDateTime(0n, timeZone); const calendar = "IsO8601"; -let arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; -const result1 = instance.equals(arg); -assert.sameValue(result1, true, "Calendar is case-insensitive"); - -arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar: { calendar } }; -const result2 = instance.equals(arg); -assert.sameValue(result2, true, "Calendar is case-insensitive (nested property)"); +const arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; +const result = instance.equals(arg); +assert.sameValue(result, true, "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index fe60ee3e2164..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,26 +0,0 @@ -// 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: > - A Temporal.Calendar instance passed to equals() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const timeZone = new Temporal.TimeZone("UTC"); -const instance = new Temporal.ZonedDateTime(0n, timeZone); - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -let arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; -instance.equals(arg); - -arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar: { calendar } }; -instance.equals(arg); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-leap-second.js index 8957994ea29c..43fca0aa85f9 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-leap-second.js @@ -12,18 +12,10 @@ const instance = new Temporal.ZonedDateTime(0n, timeZone); const calendar = "2016-12-31T23:59:60+00:00[UTC]"; -let arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; -const result1 = instance.equals(arg); +const arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; +const result = instance.equals(arg); assert.sameValue( - result1, + result, true, "leap second is a valid ISO string for calendar" ); - -arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar: { calendar } }; -const result2 = instance.equals(arg); -assert.sameValue( - result2, - true, - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-number.js index d3419b97b86c..7d1b55efd12d 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-number.js @@ -12,13 +12,9 @@ const instance = new Temporal.ZonedDateTime(0n, timeZone); const calendar = 19970327; -let arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; -const result1 = instance.equals(arg); -assert.sameValue(result1, true, "19970327 is a valid ISO string for calendar"); - -arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar: { calendar } }; -const result2 = instance.equals(arg); -assert.sameValue(result2, true, "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; +const result = instance.equals(arg); +assert.sameValue(result, true, "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -27,16 +23,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; + const arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; assert.throws( RangeError, () => instance.equals(arg), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.equals(arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-wrong-type.js index 599ec149ace2..a78ed4b4edd4 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-wrong-type.js @@ -21,27 +21,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.equals(arg), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.equals(arg), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.equals(arg), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.equals(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.equals(arg), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-instance-does-not-get-timeZone-property.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-instance-does-not-get-timeZone-property.js deleted file mode 100644 index 092ee494ea01..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-instance-does-not-get-timeZone-property.js +++ /dev/null @@ -1,22 +0,0 @@ -// 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: > - A Temporal.TimeZone instance passed to equals() does not have its - 'timeZone' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.ZonedDateTime(0n, new Temporal.TimeZone("UTC")); - -const timeZone = new Temporal.TimeZone("UTC"); -Object.defineProperty(timeZone, "timeZone", { - get() { - throw new Test262Error("timeZone.timeZone should not be accessed"); - }, -}); - -instance.equals({ year: 2020, month: 5, day: 2, timeZone }); -instance.equals({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-string-datetime.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-string-datetime.js index 1feb0e36aab0..e39e593354da 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-string-datetime.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-string-datetime.js @@ -12,7 +12,6 @@ const instance1 = new Temporal.ZonedDateTime(0n, expectedTimeZone); let timeZone = "2021-02-19T17:30"; assert.throws(RangeError, () => instance1.equals({ year: 1970, month: 1, day: 1, timeZone }), "bare date-time string is not a time zone"); -assert.throws(RangeError, () => instance1.equals({ year: 1970, month: 1, day: 1, timeZone: { timeZone } }), "bare date-time string is not a time zone"); // The following are all valid strings so should not throw. They should produce // expectedTimeZone, so additionally the operation should return true, because @@ -20,23 +19,18 @@ assert.throws(RangeError, () => instance1.equals({ year: 1970, month: 1, day: 1, timeZone = "2021-02-19T17:30Z"; assert(instance1.equals({ year: 1970, month: 1, day: 1, timeZone }), "date-time + Z is UTC time zone"); -assert(instance1.equals({ year: 1970, month: 1, day: 1, timeZone: { timeZone } }), "date-time + Z is UTC time zone (string in property bag)"); expectedTimeZone = "-08:00"; const instance2 = new Temporal.ZonedDateTime(0n, expectedTimeZone); timeZone = "2021-02-19T17:30-08:00"; assert(instance2.equals({ year: 1969, month: 12, day: 31, hour: 16, timeZone }), "date-time + offset is the offset time zone"); -assert(instance2.equals({ year: 1969, month: 12, day: 31, hour: 16, timeZone: { timeZone } }), "date-time + offset is the offset time zone (string in property bag)"); const instance3 = new Temporal.ZonedDateTime(0n, expectedTimeZone); timeZone = "2021-02-19T17:30[-08:00]"; assert(instance3.equals({ year: 1969, month: 12, day: 31, hour: 16, timeZone }), "date-time + IANA annotation is the IANA time zone"); -assert(instance3.equals({ year: 1969, month: 12, day: 31, hour: 16, timeZone: { timeZone } }), "date-time + IANA annotation is the IANA time zone (string in property bag)"); timeZone = "2021-02-19T17:30Z[-08:00]"; assert(instance3.equals({ year: 1969, month: 12, day: 31, hour: 16, timeZone }), "date-time + Z + IANA annotation is the IANA time zone"); -assert(instance3.equals({ year: 1969, month: 12, day: 31, hour: 16, timeZone: { timeZone } }), "date-time + Z + IANA annotation is the IANA time zone (string in property bag)"); timeZone = "2021-02-19T17:30-08:00[-08:00]"; assert(instance3.equals({ year: 1969, month: 12, day: 31, hour: 16, timeZone }), "date-time + offset + IANA annotation is the IANA time zone"); -assert(instance3.equals({ year: 1969, month: 12, day: 31, hour: 16, timeZone: { timeZone } }), "date-time + offset + IANA annotation is the IANA time zone (string in property bag)"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-string-leap-second.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-string-leap-second.js index 8470aacdbf92..4095674ad271 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-string-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-string-leap-second.js @@ -11,8 +11,6 @@ const instance = new Temporal.ZonedDateTime(1588377600_000_000_000n, new Tempora let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; assert(instance.equals({ year: 2020, month: 5, day: 2, timeZone }), "leap second is a valid ISO string for TimeZone"); -assert(instance.equals({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }), "leap second is a valid ISO String for TimeZone (nested property)"); timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; assert.throws(RangeError, () => instance.equals({ year: 2020, month: 5, day: 2, timeZone }), "leap second in time zone name not valid"); -assert.throws(RangeError, () => instance.equals({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }), "leap second in time zone name not valid (nested property)"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-string-multiple-offsets.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-string-multiple-offsets.js index 2e2d7a84bb3f..ae1c3017ebfa 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-string-multiple-offsets.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-string-multiple-offsets.js @@ -11,10 +11,9 @@ const expectedTimeZone = "+01:45:30.987654321"; const instance = new Temporal.ZonedDateTime(0n, expectedTimeZone); const timeZone = "2021-08-19T17:30:45.123456789+01:46[+01:45:30.987654321]"; -// These operations should produce expectedTimeZone, so the following should +// This operation should produce expectedTimeZone, so the following should // be equal due to the time zones being different on the receiver and // the argument. const properties = { year: 1970, month: 1, day: 1, hour: 1, minute: 45, second: 30, millisecond: 987, microsecond: 654, nanosecond: 321 }; assert(instance.equals({ ...properties, timeZone }), "time zone string should produce expected time zone"); -assert(instance.equals({ ...properties, timeZone: { timeZone } }), "time zone string should produce expected time zone"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-string-year-zero.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-string-year-zero.js index 9a58704f1ff2..54780e6540e8 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-string-year-zero.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-string-year-zero.js @@ -18,9 +18,4 @@ invalidStrings.forEach((timeZone) => { () => instance.equals({ year: 2020, month: 5, day: 2, timeZone }), "reject minus zero as extended year" ); - assert.throws( - RangeError, - () => instance.equals({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }), - "reject minus zero as extended year (nested property)" - ); }); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-string.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-string.js index a8039bf3294e..57de6c0244c8 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-string.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-string.js @@ -4,11 +4,32 @@ /*--- esid: sec-temporal.zoneddatetime.prototype.equals description: Time zone IDs are valid input for a time zone +includes: [temporalHelpers.js] features: [Temporal] ---*/ +const getPossibleInstantsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getPossibleInstantsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getPossibleInstantsFor should not be looked up"); + }, +}); +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + const instance1 = new Temporal.ZonedDateTime(0n, new Temporal.TimeZone("UTC")); assert(instance1.equals({ year: 1970, month: 1, day: 1, timeZone: "UTC" }), "Time zone created from string 'UTC'"); const instance2 = new Temporal.ZonedDateTime(0n, new Temporal.TimeZone("-01:30")); assert(instance2.equals({ year: 1969, month: 12, day: 31, hour: 22, minute: 30, timeZone: "-01:30" }), "Time zone created from string '-01:30'"); + +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", getPossibleInstantsForOriginal); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-wrong-type.js index a122215527a4..2f5480eea3e2 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-wrong-type.js @@ -18,22 +18,18 @@ const rangeErrorTests = [ [1, "number that doesn't convert to a valid ISO string"], [19761118, "number that would convert to a valid ISO string in other contexts"], [1n, "bigint"], - [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of rangeErrorTests) { assert.throws(RangeError, () => instance.equals({ year: 2020, month: 5, day: 2, timeZone }), `${description} does not convert to a valid ISO string`); - assert.throws(RangeError, () => instance.equals({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], + [{}, "object not implementing time zone protocol"], + [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of typeErrorTests) { assert.throws(TypeError, () => instance.equals({ year: 2020, month: 5, day: 2, timeZone }), `${description} is not a valid object and does not convert to a string`); - assert.throws(TypeError, () => instance.equals({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }), `${description} is not a valid object and does not convert to a string (nested property)`); } - -const timeZone = undefined; -assert.throws(RangeError, () => instance.equals({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }), `undefined is always a RangeError as nested property`); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-string-calendar-annotation.js index ada074e5d4ca..72352bbc3b7b 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-string-calendar-annotation.js @@ -11,7 +11,6 @@ const tests = [ ["1970-01-01T00:00[UTC][u-ca=iso8601]", "without !"], ["1970-01-01T00:00[UTC][!u-ca=iso8601]", "with !"], ["1970-01-01T00:00[UTC][u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const timeZone = new Temporal.TimeZone("UTC"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..7627303897b6 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-string-multiple-calendar.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 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: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[UTC][!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.ZonedDateTime(0n, timeZone); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.equals(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..cef90b77f8df --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 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: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const idOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "id"); +Object.defineProperty(Temporal.Calendar.prototype, "id", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("id should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.equals(new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC")); + +Object.defineProperty(Temporal.Calendar.prototype, "id", idOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..6c8a4188bb06 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/builtin-timezone-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 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: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const idOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "id"); +Object.defineProperty(Temporal.TimeZone.prototype, "id", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("id should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.equals(new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC")); + +Object.defineProperty(Temporal.TimeZone.prototype, "id", idOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/order-of-operations.js index f45365a84934..fb44faa7513e 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/equals/order-of-operations.js @@ -10,7 +10,27 @@ features: [Temporal] const expected = [ "get other.calendar", - "has other.calendar.calendar", + "has other.calendar.dateAdd", + "has other.calendar.dateFromFields", + "has other.calendar.dateUntil", + "has other.calendar.day", + "has other.calendar.dayOfWeek", + "has other.calendar.dayOfYear", + "has other.calendar.daysInMonth", + "has other.calendar.daysInWeek", + "has other.calendar.daysInYear", + "has other.calendar.fields", + "has other.calendar.id", + "has other.calendar.inLeapYear", + "has other.calendar.mergeFields", + "has other.calendar.month", + "has other.calendar.monthCode", + "has other.calendar.monthDayFromFields", + "has other.calendar.monthsInYear", + "has other.calendar.weekOfYear", + "has other.calendar.year", + "has other.calendar.yearMonthFromFields", + "has other.calendar.yearOfWeek", "get other.calendar.fields", "call other.calendar.fields", // PrepareTemporalFields @@ -48,7 +68,9 @@ const expected = [ "get other.year", "get other.year.valueOf", "call other.year.valueOf", - "has other.timeZone.timeZone", + "has other.timeZone.getOffsetNanosecondsFor", + "has other.timeZone.getPossibleInstantsFor", + "has other.timeZone.id", // InterpretTemporalDateTimeFields "get other.calendar.dateFromFields", "call other.calendar.dateFromFields", @@ -58,19 +80,11 @@ const expected = [ "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", + "get this.timeZone.id", + "get other.timeZone.id", // CalendarEquals - "get this.calendar[Symbol.toPrimitive]", - "get this.calendar.toString", - "call this.calendar.toString", - "get other.calendar[Symbol.toPrimitive]", - "get other.calendar.toString", - "call other.calendar.toString", + "get this.calendar.id", + "get other.calendar.id", ]; const actual = []; diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getCalendar/branding.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getCalendar/branding.js new file mode 100644 index 000000000000..3dfefde3bf3b --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getCalendar/branding.js @@ -0,0 +1,22 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.getcalendar +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const getCalendar = Temporal.ZonedDateTime.prototype.getCalendar; + +assert.sameValue(typeof getCalendar, "function"); + +assert.throws(TypeError, () => getCalendar.call(undefined), "undefined"); +assert.throws(TypeError, () => getCalendar.call(null), "null"); +assert.throws(TypeError, () => getCalendar.call(true), "true"); +assert.throws(TypeError, () => getCalendar.call(""), "empty string"); +assert.throws(TypeError, () => getCalendar.call(Symbol()), "symbol"); +assert.throws(TypeError, () => getCalendar.call(1), "1"); +assert.throws(TypeError, () => getCalendar.call({}), "plain object"); +assert.throws(TypeError, () => getCalendar.call(Temporal.ZonedDateTime), "Temporal.ZonedDateTime"); +assert.throws(TypeError, () => getCalendar.call(Temporal.ZonedDateTime.prototype), "Temporal.ZonedDateTime.prototype"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getCalendar/builtin.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getCalendar/builtin.js new file mode 100644 index 000000000000..65be1d8c8fa7 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getCalendar/builtin.js @@ -0,0 +1,33 @@ +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.getcalendar +description: > + Tests that Temporal.ZonedDateTime.prototype.getCalendar + meets the requirements for built-in objects defined by the + introduction of chapter 17 of the ECMAScript Language Specification. +info: | + Built-in functions that are not constructors do not have a "prototype" property unless + otherwise specified in the description of a particular function. + + Unless specified otherwise, a built-in object that is callable as a function is a built-in + function object with the characteristics described in 10.3. Unless specified otherwise, the + [[Extensible]] internal slot of a built-in object initially has the value true. + + Unless otherwise specified every built-in function and every built-in constructor has the + Function prototype object [...] as the value of its [[Prototype]] internal slot. +features: [Temporal] +---*/ + +assert.sameValue(Object.isExtensible(Temporal.ZonedDateTime.prototype.getCalendar), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.ZonedDateTime.prototype.getCalendar), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.ZonedDateTime.prototype.getCalendar), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.ZonedDateTime.prototype.getCalendar.hasOwnProperty("prototype"), + false, "prototype property"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getCalendar/length.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getCalendar/length.js new file mode 100644 index 000000000000..2fb3cc1ba7cd --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getCalendar/length.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.getcalendar +description: Temporal.ZonedDateTime.prototype.getCalendar.length is 0 +info: | + Every built-in function object, including constructors, has a "length" property whose value is + an integer. Unless otherwise specified, this value is equal to the largest number of named + arguments shown in the subclause headings for the function description. Optional parameters + (which are indicated with brackets: [ ]) or rest parameters (which are shown using the form + «...name») are not included in the default argument count. + + Unless otherwise specified, the "length" property of a built-in function object has the + attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +verifyProperty(Temporal.ZonedDateTime.prototype.getCalendar, "length", { + value: 0, + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getCalendar/name.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getCalendar/name.js new file mode 100644 index 000000000000..ad3636660383 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getCalendar/name.js @@ -0,0 +1,23 @@ +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.getcalendar +description: Temporal.ZonedDateTime.prototype.getCalendar.name is "getCalendar". +info: | + Every built-in function object, including constructors, that is not identified as an anonymous + function has a "name" property whose value is a String. Unless otherwise specified, this value + is the name that is given to the function in this specification. + + Unless otherwise specified, the "name" property of a built-in function object, if it exists, + has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +verifyProperty(Temporal.ZonedDateTime.prototype.getCalendar, "name", { + value: "getCalendar", + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getCalendar/not-a-constructor.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getCalendar/not-a-constructor.js new file mode 100644 index 000000000000..2f7c96899f57 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getCalendar/not-a-constructor.js @@ -0,0 +1,21 @@ +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.getcalendar +description: > + Temporal.ZonedDateTime.prototype.getCalendar does not implement [[Construct]], is not new-able +info: | + Built-in function objects that are not identified as constructors do not implement the + [[Construct]] internal method unless otherwise specified in the description of a particular + function. +includes: [isConstructor.js] +features: [Reflect.construct, Temporal] +---*/ + +assert.throws(TypeError, () => { + new Temporal.ZonedDateTime.prototype.getCalendar(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.ZonedDateTime.prototype.getCalendar), false, + "isConstructor(Temporal.ZonedDateTime.prototype.getCalendar)"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getCalendar/prop-desc.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getCalendar/prop-desc.js new file mode 100644 index 000000000000..a6346fbccf9c --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getCalendar/prop-desc.js @@ -0,0 +1,21 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.getcalendar +description: The "getCalendar" property of Temporal.ZonedDateTime.prototype +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.ZonedDateTime.prototype.getCalendar, + "function", + "`typeof ZonedDateTime.prototype.getCalendar` is `function`" +); + +verifyProperty(Temporal.ZonedDateTime.prototype, "getCalendar", { + writable: true, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getISOFields/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getISOFields/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..d4384733e62f --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getISOFields/builtin-timezone-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.getisofields +description: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.getISOFields(); + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getISOFields/custom.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getISOFields/custom.js index 972b3fcb1d57..2900a83ee076 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getISOFields/custom.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getISOFields/custom.js @@ -23,4 +23,4 @@ assert.sameValue(result.isoMicrosecond, 654, "isoMicrosecond result"); assert.sameValue(result.isoNanosecond, 321, "isoNanosecond result"); assert.sameValue(result.offset, "+00:00", "offset result"); assert.sameValue(result.calendar, calendar, "calendar result"); -assert.sameValue(result.timeZone.id, "UTC", "timeZone result"); +assert.sameValue(result.timeZone, "UTC", "timeZone result"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getISOFields/field-names.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getISOFields/field-names.js index 150e8dd11d9d..10861de182b6 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getISOFields/field-names.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getISOFields/field-names.js @@ -20,5 +20,5 @@ assert.sameValue(result.isoMillisecond, 987, "isoMillisecond result"); assert.sameValue(result.isoMicrosecond, 654, "isoMicrosecond result"); assert.sameValue(result.isoNanosecond, 321, "isoNanosecond result"); assert.sameValue(result.offset, "+00:00", "offset result"); -assert.sameValue(result.calendar.id, "iso8601", "calendar result"); -assert.sameValue(result.timeZone.id, "UTC", "timeZone result"); +assert.sameValue(result.calendar, "iso8601", "calendar result"); +assert.sameValue(result.timeZone, "UTC", "timeZone result"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getISOFields/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getISOFields/order-of-operations.js new file mode 100644 index 000000000000..23c57b5bf50d --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getISOFields/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.zoneddatetime.prototype.getisofields +description: > + Properties on the calendar or time zone of the receiver of getISOFields() + are accessed in the correct order +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const expected = [ + "get this.timeZone.getOffsetNanosecondsFor", + "call this.timeZone.getOffsetNanosecondsFor", + "get this.timeZone.getOffsetNanosecondsFor", + "call this.timeZone.getOffsetNanosecondsFor", +]; +const actual = []; + +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.getISOFields(); +assert.compareArray(actual, expected, "order of operations"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getTimeZone/branding.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getTimeZone/branding.js new file mode 100644 index 000000000000..c76788b8c09b --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getTimeZone/branding.js @@ -0,0 +1,22 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.gettimezone +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const getTimeZone = Temporal.ZonedDateTime.prototype.getTimeZone; + +assert.sameValue(typeof getTimeZone, "function"); + +assert.throws(TypeError, () => getTimeZone.call(undefined), "undefined"); +assert.throws(TypeError, () => getTimeZone.call(null), "null"); +assert.throws(TypeError, () => getTimeZone.call(true), "true"); +assert.throws(TypeError, () => getTimeZone.call(""), "empty string"); +assert.throws(TypeError, () => getTimeZone.call(Symbol()), "symbol"); +assert.throws(TypeError, () => getTimeZone.call(1), "1"); +assert.throws(TypeError, () => getTimeZone.call({}), "plain object"); +assert.throws(TypeError, () => getTimeZone.call(Temporal.ZonedDateTime), "Temporal.ZonedDateTime"); +assert.throws(TypeError, () => getTimeZone.call(Temporal.ZonedDateTime.prototype), "Temporal.ZonedDateTime.prototype"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getTimeZone/builtin.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getTimeZone/builtin.js new file mode 100644 index 000000000000..57e6dddd7552 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getTimeZone/builtin.js @@ -0,0 +1,33 @@ +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.gettimezone +description: > + Tests that Temporal.ZonedDateTime.prototype.getTimeZone + meets the requirements for built-in objects defined by the + introduction of chapter 17 of the ECMAScript Language Specification. +info: | + Built-in functions that are not constructors do not have a "prototype" property unless + otherwise specified in the description of a particular function. + + Unless specified otherwise, a built-in object that is callable as a function is a built-in + function object with the characteristics described in 10.3. Unless specified otherwise, the + [[Extensible]] internal slot of a built-in object initially has the value true. + + Unless otherwise specified every built-in function and every built-in constructor has the + Function prototype object [...] as the value of its [[Prototype]] internal slot. +features: [Temporal] +---*/ + +assert.sameValue(Object.isExtensible(Temporal.ZonedDateTime.prototype.getTimeZone), + true, "Built-in objects must be extensible."); + +assert.sameValue(Object.prototype.toString.call(Temporal.ZonedDateTime.prototype.getTimeZone), + "[object Function]", "Object.prototype.toString"); + +assert.sameValue(Object.getPrototypeOf(Temporal.ZonedDateTime.prototype.getTimeZone), + Function.prototype, "prototype"); + +assert.sameValue(Temporal.ZonedDateTime.prototype.getTimeZone.hasOwnProperty("prototype"), + false, "prototype property"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getTimeZone/length.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getTimeZone/length.js new file mode 100644 index 000000000000..20da9dcdc711 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getTimeZone/length.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.gettimezone +description: Temporal.ZonedDateTime.prototype.getTimeZone.length is 0 +info: | + Every built-in function object, including constructors, has a "length" property whose value is + an integer. Unless otherwise specified, this value is equal to the largest number of named + arguments shown in the subclause headings for the function description. Optional parameters + (which are indicated with brackets: [ ]) or rest parameters (which are shown using the form + «...name») are not included in the default argument count. + + Unless otherwise specified, the "length" property of a built-in function object has the + attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +verifyProperty(Temporal.ZonedDateTime.prototype.getTimeZone, "length", { + value: 0, + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getTimeZone/name.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getTimeZone/name.js new file mode 100644 index 000000000000..4f4af47f7bb2 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getTimeZone/name.js @@ -0,0 +1,23 @@ +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.gettimezone +description: Temporal.ZonedDateTime.prototype.getTimeZone.name is "getTimeZone". +info: | + Every built-in function object, including constructors, that is not identified as an anonymous + function has a "name" property whose value is a String. Unless otherwise specified, this value + is the name that is given to the function in this specification. + + Unless otherwise specified, the "name" property of a built-in function object, if it exists, + has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +verifyProperty(Temporal.ZonedDateTime.prototype.getTimeZone, "name", { + value: "getTimeZone", + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getTimeZone/not-a-constructor.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getTimeZone/not-a-constructor.js new file mode 100644 index 000000000000..56bea9fcd7ac --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getTimeZone/not-a-constructor.js @@ -0,0 +1,21 @@ +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.gettimezone +description: > + Temporal.ZonedDateTime.prototype.getTimeZone does not implement [[Construct]], is not new-able +info: | + Built-in function objects that are not identified as constructors do not implement the + [[Construct]] internal method unless otherwise specified in the description of a particular + function. +includes: [isConstructor.js] +features: [Reflect.construct, Temporal] +---*/ + +assert.throws(TypeError, () => { + new Temporal.ZonedDateTime.prototype.getTimeZone(); +}, "Calling as constructor"); + +assert.sameValue(isConstructor(Temporal.ZonedDateTime.prototype.getTimeZone), false, + "isConstructor(Temporal.ZonedDateTime.prototype.getTimeZone)"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getTimeZone/prop-desc.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getTimeZone/prop-desc.js new file mode 100644 index 000000000000..074f4345aa0b --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/getTimeZone/prop-desc.js @@ -0,0 +1,21 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.gettimezone +description: The "getTimeZone" property of Temporal.ZonedDateTime.prototype +includes: [propertyHelper.js] +features: [Temporal] +---*/ + +assert.sameValue( + typeof Temporal.ZonedDateTime.prototype.getTimeZone, + "function", + "`typeof ZonedDateTime.prototype.getTimeZone` is `function`" +); + +verifyProperty(Temporal.ZonedDateTime.prototype, "getTimeZone", { + writable: true, + enumerable: false, + configurable: true, +}); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/hour/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/hour/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..e34f3fc6b5d8 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/hour/builtin-timezone-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.hour +description: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.hour; + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/inLeapYear/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/inLeapYear/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..2cf3b7ed4833 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/inLeapYear/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.inleapyear +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const inLeapYearOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "inLeapYear"); +Object.defineProperty(Temporal.Calendar.prototype, "inLeapYear", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("inLeapYear should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.inLeapYear; + +Object.defineProperty(Temporal.Calendar.prototype, "inLeapYear", inLeapYearOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/inLeapYear/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/inLeapYear/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..7de82ddce374 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/inLeapYear/builtin-timezone-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.inleapyear +description: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.inLeapYear; + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/microsecond/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/microsecond/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..2a4fce9dcde9 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/microsecond/builtin-timezone-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.microsecond +description: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.microsecond; + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/millisecond/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/millisecond/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..118840853d2c --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/millisecond/builtin-timezone-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.millisecond +description: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.millisecond; + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/minute/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/minute/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..b3caf18e341a --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/minute/builtin-timezone-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.minute +description: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.minute; + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/month/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/month/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..5a9c1bf7fff6 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/month/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.month +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const monthOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "month"); +Object.defineProperty(Temporal.Calendar.prototype, "month", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("month should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.month; + +Object.defineProperty(Temporal.Calendar.prototype, "month", monthOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/month/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/month/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..ed00a42a108b --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/month/builtin-timezone-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.month +description: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.month; + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/monthCode/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/monthCode/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..423e7893f2b0 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/monthCode/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.monthcode +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const monthCodeOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "monthCode"); +Object.defineProperty(Temporal.Calendar.prototype, "monthCode", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("monthCode should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.monthCode; + +Object.defineProperty(Temporal.Calendar.prototype, "monthCode", monthCodeOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/monthCode/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/monthCode/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..11e3f269a038 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/monthCode/builtin-timezone-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.monthcode +description: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.monthCode; + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/monthsInYear/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/monthsInYear/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..36152494b80e --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/monthsInYear/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.monthsinyear +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const monthsInYearOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "monthsInYear"); +Object.defineProperty(Temporal.Calendar.prototype, "monthsInYear", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("monthsInYear should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.monthsInYear; + +Object.defineProperty(Temporal.Calendar.prototype, "monthsInYear", monthsInYearOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/monthsInYear/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/monthsInYear/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..ecced9bc89d9 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/monthsInYear/builtin-timezone-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.monthsinyear +description: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.monthsInYear; + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/nanosecond/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/nanosecond/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..ad09cfacb417 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/nanosecond/builtin-timezone-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.nanosecond +description: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.nanosecond; + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/offset/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/offset/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..64cd54cb41a6 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/offset/builtin-timezone-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.offset +description: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.offset; + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/offsetNanoseconds/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/offsetNanoseconds/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..a8ed9865a896 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/offsetNanoseconds/builtin-timezone-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.offsetnanoseconds +description: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.offsetNanoseconds; + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/round/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/round/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..a15f42abb33d --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/round/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.round +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const dateAddOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dateAdd"); +Object.defineProperty(Temporal.Calendar.prototype, "dateAdd", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("dateAdd should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.round("day"); + +Object.defineProperty(Temporal.Calendar.prototype, "dateAdd", dateAddOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/round/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/round/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..437977d99932 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/round/builtin-timezone-no-observable-calls.js @@ -0,0 +1,34 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.round +description: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); +const getPossibleInstantsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getPossibleInstantsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getPossibleInstantsFor should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.round("day"); + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", getPossibleInstantsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/round/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/round/order-of-operations.js new file mode 100644 index 000000000000..36198bd2018a --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/round/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.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 options.roundingIncrement", + "get options.roundingIncrement.valueOf", + "call options.roundingIncrement.valueOf", + "get options.roundingMode", + "get options.roundingMode.toString", + "call options.roundingMode.toString", + "get options.smallestUnit", + "get options.smallestUnit.toString", + "call options.smallestUnit.toString", + // GetPlainDateTimeFor on receiver's instant + "get this.timeZone.getOffsetNanosecondsFor", + "call this.timeZone.getOffsetNanosecondsFor", + // GetInstantFor on preceding midnight + "get this.timeZone.getPossibleInstantsFor", + "call this.timeZone.getPossibleInstantsFor", + // AddZonedDateTime + "get this.timeZone.getOffsetNanosecondsFor", + "call this.timeZone.getOffsetNanosecondsFor", + "get this.calendar.dateAdd", + "call this.calendar.dateAdd", + "get this.timeZone.getPossibleInstantsFor", + "call this.timeZone.getPossibleInstantsFor", + // GetOffsetNanosecondsFor + "get this.timeZone.getOffsetNanosecondsFor", + "call this.timeZone.getOffsetNanosecondsFor", + // InterpretISODateTimeOffset + "get this.timeZone.getPossibleInstantsFor", + "call this.timeZone.getPossibleInstantsFor", + "get this.timeZone.getOffsetNanosecondsFor", + "call this.timeZone.getOffsetNanosecondsFor", +]; +const actual = []; + +const options = TemporalHelpers.propertyBagObserver(actual, { + smallestUnit: "nanoseconds", + roundingMode: "halfExpand", + roundingIncrement: 1, +}, "options"); + +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.round(options); +assert.compareArray(actual, expected, "order of operations"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/second/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/second/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..fcae38ebcebe --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/second/builtin-timezone-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.second +description: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.second; + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-case-insensitive.js index 5925793a6b75..1d341ebc142e 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-case-insensitive.js @@ -13,10 +13,6 @@ const instance = new Temporal.ZonedDateTime(0n, timeZone); const calendar = "IsO8601"; -let arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; -const result1 = instance.since(arg); -TemporalHelpers.assertDuration(result1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Calendar is case-insensitive"); - -arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar: { calendar } }; -const result2 = instance.since(arg); -TemporalHelpers.assertDuration(result2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Calendar is case-insensitive (nested property)"); +const arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; +const result = instance.since(arg); +TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index f6f47c829341..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,26 +0,0 @@ -// 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.since -description: > - A Temporal.Calendar instance passed to since() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const timeZone = new Temporal.TimeZone("UTC"); -const instance = new Temporal.ZonedDateTime(0n, timeZone); - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -let arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; -instance.since(arg); - -arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar: { calendar } }; -instance.since(arg); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-leap-second.js index a907504f4b21..c2c39d97de71 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-leap-second.js @@ -13,18 +13,10 @@ const instance = new Temporal.ZonedDateTime(0n, timeZone); const calendar = "2016-12-31T23:59:60+00:00[UTC]"; -let arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; -const result1 = instance.since(arg); +const arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; +const result = instance.since(arg); TemporalHelpers.assertDuration( - result1, + result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "leap second is a valid ISO string for calendar" ); - -arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar: { calendar } }; -const result2 = instance.since(arg); -TemporalHelpers.assertDuration( - result2, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-number.js index d99297f1a023..78d9c51616ad 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-number.js @@ -13,13 +13,9 @@ const instance = new Temporal.ZonedDateTime(0n, timeZone); const calendar = 19970327; -let arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; -const result1 = instance.since(arg); -TemporalHelpers.assertDuration(result1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar"); - -arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar: { calendar } }; -const result2 = instance.since(arg); -TemporalHelpers.assertDuration(result2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; +const result = instance.since(arg); +TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -28,16 +24,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; + const arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; assert.throws( RangeError, () => instance.since(arg), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.since(arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-wrong-type.js index 2269c00245f3..d9c064e7476e 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-wrong-type.js @@ -21,27 +21,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.since(arg), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.since(arg), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.since(arg), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.since(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.since(arg), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-instance-does-not-get-timeZone-property.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-instance-does-not-get-timeZone-property.js deleted file mode 100644 index dc1b28d6d6be..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-instance-does-not-get-timeZone-property.js +++ /dev/null @@ -1,22 +0,0 @@ -// 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.since -description: > - A Temporal.TimeZone instance passed to since() does not have its - 'timeZone' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.ZonedDateTime(0n, new Temporal.TimeZone("UTC")); - -const timeZone = new Temporal.TimeZone("UTC"); -Object.defineProperty(timeZone, "timeZone", { - get() { - throw new Test262Error("timeZone.timeZone should not be accessed"); - }, -}); - -instance.since({ year: 2020, month: 5, day: 2, timeZone }); -instance.since({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-string-datetime.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-string-datetime.js index 1dbac956bd1d..cafe95f5d448 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-string-datetime.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-string-datetime.js @@ -12,7 +12,6 @@ const instance1 = new Temporal.ZonedDateTime(0n, expectedTimeZone); let timeZone = "2021-08-19T17:30"; assert.throws(RangeError, () => instance1.since({ year: 2020, month: 5, day: 2, timeZone }), "bare date-time string is not a time zone"); -assert.throws(RangeError, () => instance1.since({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }), "bare date-time string is not a time zone"); // The following are all valid strings so should not throw. They should produce // expectedTimeZone, so additionally the operation will not throw due to the @@ -20,24 +19,19 @@ assert.throws(RangeError, () => instance1.since({ year: 2020, month: 5, day: 2, timeZone = "2021-08-19T17:30Z"; instance1.since({ year: 2020, month: 5, day: 2, timeZone }); -instance1.since({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }); expectedTimeZone = "-07:00"; const instance2 = new Temporal.ZonedDateTime(0n, expectedTimeZone); timeZone = "2021-08-19T17:30-07:00"; instance2.since({ year: 2020, month: 5, day: 2, timeZone }); -instance2.since({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }); expectedTimeZone = "UTC"; const instance3 = new Temporal.ZonedDateTime(0n, expectedTimeZone); timeZone = "2021-08-19T17:30[UTC]"; instance3.since({ year: 2020, month: 5, day: 2, timeZone }); -instance3.since({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }); timeZone = "2021-08-19T17:30Z[UTC]"; instance3.since({ year: 2020, month: 5, day: 2, timeZone }); -instance3.since({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }); timeZone = "2021-08-19T17:30-07:00[UTC]"; instance3.since({ year: 2020, month: 5, day: 2, timeZone }); -instance3.since({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-string-leap-second.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-string-leap-second.js index 5bce2e354783..024a7569cef0 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-string-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-string-leap-second.js @@ -11,13 +11,11 @@ const expectedTimeZone = "UTC"; const instance = new Temporal.ZonedDateTime(0n, expectedTimeZone); let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; -// These operations should produce expectedTimeZone, so the following operations +// This operation should produce expectedTimeZone, so the following operation // should not throw due to the time zones being different on the receiver and // the argument. instance.since({ year: 2020, month: 5, day: 2, timeZone }); -instance.since({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }); timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; assert.throws(RangeError, () => instance.since({ year: 2020, month: 5, day: 2, timeZone }), "leap second in time zone name not valid"); -assert.throws(RangeError, () => instance.since({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }), "leap second in time zone name not valid (nested property)"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-string-multiple-offsets.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-string-multiple-offsets.js index 94426467cf59..c2a4fce8f124 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-string-multiple-offsets.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-string-multiple-offsets.js @@ -11,9 +11,8 @@ const expectedTimeZone = "+01:45:30.987654321"; const instance = new Temporal.ZonedDateTime(0n, expectedTimeZone); const timeZone = "2021-08-19T17:30:45.123456789+01:46[+01:45:30.987654321]"; -// These operations should produce expectedTimeZone, so the following operations +// This operation should produce expectedTimeZone, so the following operation // should not throw due to the time zones being different on the receiver and // the argument. instance.since({ year: 2020, month: 5, day: 2, timeZone }); -instance.since({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-string-year-zero.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-string-year-zero.js index 4c4cd97e92dc..27e043ae0e22 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-string-year-zero.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-string-year-zero.js @@ -18,9 +18,4 @@ invalidStrings.forEach((timeZone) => { () => instance.since({ year: 2020, month: 5, day: 2, timeZone }), "reject minus zero as extended year" ); - assert.throws( - RangeError, - () => instance.since({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }), - "reject minus zero as extended year (nested property)" - ); }); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-string.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-string.js index 39d985a81860..bc33b46d3931 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-string.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-string.js @@ -4,11 +4,32 @@ /*--- esid: sec-temporal.zoneddatetime.prototype.since description: Time zone IDs are valid input for a time zone +includes: [temporalHelpers.js] features: [Temporal] ---*/ +const getPossibleInstantsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getPossibleInstantsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getPossibleInstantsFor should not be looked up"); + }, +}); +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + const instance1 = new Temporal.ZonedDateTime(0n, new Temporal.TimeZone("UTC")); assert(instance1.since({ year: 1970, month: 1, day: 1, timeZone: "UTC" }).blank, "Time zone created from string 'UTC'"); const instance2 = new Temporal.ZonedDateTime(0n, new Temporal.TimeZone("-01:30")); assert(instance2.since({ year: 1969, month: 12, day: 31, hour: 22, minute: 30, timeZone: "-01:30" }).blank, "Time zone created from string '-01:30'"); + +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", getPossibleInstantsForOriginal); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-wrong-type.js index da877e7a535e..4535b54017ee 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-wrong-type.js @@ -18,22 +18,18 @@ const rangeErrorTests = [ [1, "number that doesn't convert to a valid ISO string"], [19761118, "number that would convert to a valid ISO string in other contexts"], [1n, "bigint"], - [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of rangeErrorTests) { assert.throws(RangeError, () => instance.since({ year: 2020, month: 5, day: 2, timeZone }), `${description} does not convert to a valid ISO string`); - assert.throws(RangeError, () => instance.since({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], + [{}, "object not implementing time zone protocol"], + [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of typeErrorTests) { assert.throws(TypeError, () => instance.since({ year: 2020, month: 5, day: 2, timeZone }), `${description} is not a valid object and does not convert to a string`); - assert.throws(TypeError, () => instance.since({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }), `${description} is not a valid object and does not convert to a string (nested property)`); } - -const timeZone = undefined; -assert.throws(RangeError, () => instance.since({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }), `undefined is always a RangeError as nested property`); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-string-calendar-annotation.js index 1797eb7b50d1..575382d8ed61 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-string-calendar-annotation.js @@ -12,7 +12,6 @@ const tests = [ ["1970-01-01T00:00[UTC][u-ca=iso8601]", "without !"], ["1970-01-01T00:00[UTC][!u-ca=iso8601]", "with !"], ["1970-01-01T00:00[UTC][u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const timeZone = new Temporal.TimeZone("UTC"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..4e6737e1832e --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-string-multiple-calendar.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.since +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[UTC][!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.ZonedDateTime(0n, timeZone); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.since(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..054dadd5416d --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.since +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const dateUntilOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dateUntil"); +Object.defineProperty(Temporal.Calendar.prototype, "dateUntil", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("dateUntil should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.since(new Temporal.ZonedDateTime(0n, "UTC")); + +Object.defineProperty(Temporal.Calendar.prototype, "dateUntil", dateUntilOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..3b7e4ac0f083 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/builtin-timezone-no-observable-calls.js @@ -0,0 +1,34 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.since +description: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); +const getPossibleInstantsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getPossibleInstantsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getPossibleInstantsFor should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.since(new Temporal.ZonedDateTime(0n, "UTC")); + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", getPossibleInstantsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/order-of-operations.js index a0e64466f57a..5c50c76e4f74 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/since/order-of-operations.js @@ -11,7 +11,27 @@ features: [Temporal] const expected = [ // ToTemporalZonedDateTime "get other.calendar", - "has other.calendar.calendar", + "has other.calendar.dateAdd", + "has other.calendar.dateFromFields", + "has other.calendar.dateUntil", + "has other.calendar.day", + "has other.calendar.dayOfWeek", + "has other.calendar.dayOfYear", + "has other.calendar.daysInMonth", + "has other.calendar.daysInWeek", + "has other.calendar.daysInYear", + "has other.calendar.fields", + "has other.calendar.id", + "has other.calendar.inLeapYear", + "has other.calendar.mergeFields", + "has other.calendar.month", + "has other.calendar.monthCode", + "has other.calendar.monthDayFromFields", + "has other.calendar.monthsInYear", + "has other.calendar.weekOfYear", + "has other.calendar.year", + "has other.calendar.yearMonthFromFields", + "has other.calendar.yearOfWeek", "get other.calendar.fields", "call other.calendar.fields", "get other.day", @@ -48,7 +68,9 @@ const expected = [ "get other.year", "get other.year.valueOf", "call other.year.valueOf", - "has other.timeZone.timeZone", + "has other.timeZone.getOffsetNanosecondsFor", + "has other.timeZone.getPossibleInstantsFor", + "has other.timeZone.id", "get other.calendar.dateFromFields", "call other.calendar.dateFromFields", "get other.timeZone.getPossibleInstantsFor", @@ -56,12 +78,8 @@ const expected = [ "get other.timeZone.getOffsetNanosecondsFor", "call other.timeZone.getOffsetNanosecondsFor", // CalendarEquals - "get this.calendar[Symbol.toPrimitive]", - "get this.calendar.toString", - "call this.calendar.toString", - "get other.calendar[Symbol.toPrimitive]", - "get other.calendar.toString", - "call other.calendar.toString", + "get this.calendar.id", + "get other.calendar.id", // CopyDataProperties "ownKeys options", "getOwnPropertyDescriptor options.roundingIncrement", @@ -129,12 +147,8 @@ actual.splice(0); // clear // Making largestUnit a calendar unit adds the following observable operations: const expectedOpsForCalendarDifference = [ // 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", + "get this.timeZone.id", + "get other.timeZone.id", // DifferenceZonedDateTime "get this.timeZone.getOffsetNanosecondsFor", "call this.timeZone.getOffsetNanosecondsFor", @@ -231,4 +245,9 @@ const expectedOpsForWeekRounding = expected.concat(expectedOpsForCalendarDiffere "call this.calendar.dateAdd", // 11.d MoveRelativeDate ]); // (11.g.iii MoveRelativeDate not called because days already balanced) instance.since(otherDateTimePropertyBag, createOptionsObserver({ smallestUnit: "weeks" })); -assert.compareArray(actual.slice(expected.length), expectedOpsForWeekRounding.slice(expected.length), "order of operations with smallestUnit = weeks"); +assert.compareArray(actual, expectedOpsForWeekRounding, "order of operations with smallestUnit = weeks"); +actual.splice(0); // clear + +instance.since(otherDateTimePropertyBag, createOptionsObserver({ largestUnit: "hours" })); +assert.compareArray(actual, expected, "order of operations with largestUnit being a time unit"); +actual.splice(0); // clear diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/startOfDay/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/startOfDay/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..60141122a26b --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/startOfDay/builtin-timezone-no-observable-calls.js @@ -0,0 +1,34 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.startofday +description: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); +const getPossibleInstantsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getPossibleInstantsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getPossibleInstantsFor should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.startOfDay(); + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", getPossibleInstantsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/subtract/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/subtract/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..008e58843e0c --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/subtract/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 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: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const dateAddOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dateAdd"); +Object.defineProperty(Temporal.Calendar.prototype, "dateAdd", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("dateAdd should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.subtract(new Temporal.Duration(1)); + +Object.defineProperty(Temporal.Calendar.prototype, "dateAdd", dateAddOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/subtract/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/subtract/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..1d1f7f974a81 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/subtract/builtin-timezone-no-observable-calls.js @@ -0,0 +1,34 @@ +// Copyright (C) 2023 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: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); +const getPossibleInstantsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getPossibleInstantsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getPossibleInstantsFor should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.subtract(new Temporal.Duration(1)); + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", getPossibleInstantsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/timeZone/branding.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/timeZone/branding.js deleted file mode 100644 index 15ac6fc049ab..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/timeZone/branding.js +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-get-temporal.zoneddatetime.prototype.timezone -description: Throw a TypeError if the receiver is invalid -features: [Symbol, Temporal] ----*/ - -const timeZone = Object.getOwnPropertyDescriptor(Temporal.ZonedDateTime.prototype, "timeZone").get; - -assert.sameValue(typeof timeZone, "function"); - -assert.throws(TypeError, () => timeZone.call(undefined), "undefined"); -assert.throws(TypeError, () => timeZone.call(null), "null"); -assert.throws(TypeError, () => timeZone.call(true), "true"); -assert.throws(TypeError, () => timeZone.call(""), "empty string"); -assert.throws(TypeError, () => timeZone.call(Symbol()), "symbol"); -assert.throws(TypeError, () => timeZone.call(1), "1"); -assert.throws(TypeError, () => timeZone.call({}), "plain object"); -assert.throws(TypeError, () => timeZone.call(Temporal.ZonedDateTime), "Temporal.ZonedDateTime"); -assert.throws(TypeError, () => timeZone.call(Temporal.ZonedDateTime.prototype), "Temporal.ZonedDateTime.prototype"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/timeZone/prop-desc.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/timeZone/prop-desc.js deleted file mode 100644 index e01a0f9d659b..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/timeZone/prop-desc.js +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-get-temporal.zoneddatetime.prototype.timezone -description: The "timeZone" property of Temporal.ZonedDateTime.prototype -features: [Temporal] ----*/ - -const descriptor = Object.getOwnPropertyDescriptor(Temporal.ZonedDateTime.prototype, "timeZone"); -assert.sameValue(typeof descriptor.get, "function"); -assert.sameValue(descriptor.set, undefined); -assert.sameValue(descriptor.enumerable, false); -assert.sameValue(descriptor.configurable, true); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/timeZoneId/branding.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/timeZoneId/branding.js new file mode 100644 index 000000000000..9db21cb80ba1 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/timeZoneId/branding.js @@ -0,0 +1,22 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-get-temporal.zoneddatetime.prototype.timezoneid +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const timeZoneId = Object.getOwnPropertyDescriptor(Temporal.ZonedDateTime.prototype, "timeZoneId").get; + +assert.sameValue(typeof timeZoneId, "function"); + +assert.throws(TypeError, () => timeZoneId.call(undefined), "undefined"); +assert.throws(TypeError, () => timeZoneId.call(null), "null"); +assert.throws(TypeError, () => timeZoneId.call(true), "true"); +assert.throws(TypeError, () => timeZoneId.call(""), "empty string"); +assert.throws(TypeError, () => timeZoneId.call(Symbol()), "symbol"); +assert.throws(TypeError, () => timeZoneId.call(1), "1"); +assert.throws(TypeError, () => timeZoneId.call({}), "plain object"); +assert.throws(TypeError, () => timeZoneId.call(Temporal.ZonedDateTime), "Temporal.ZonedDateTime"); +assert.throws(TypeError, () => timeZoneId.call(Temporal.ZonedDateTime.prototype), "Temporal.ZonedDateTime.prototype"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/timeZoneId/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/timeZoneId/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..f7ec46285c3f --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/timeZoneId/builtin-timezone-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.timezoneid +description: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const idOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "id"); +Object.defineProperty(Temporal.TimeZone.prototype, "id", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("id should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.timeZoneId; + +Object.defineProperty(Temporal.TimeZone.prototype, "id", idOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/timeZoneId/prop-desc.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/timeZoneId/prop-desc.js new file mode 100644 index 000000000000..989bfa4eeb25 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/timeZoneId/prop-desc.js @@ -0,0 +1,14 @@ +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-get-temporal.zoneddatetime.prototype.timezoneid +description: The "timeZoneId" property of Temporal.ZonedDateTime.prototype +features: [Temporal] +---*/ + +const descriptor = Object.getOwnPropertyDescriptor(Temporal.ZonedDateTime.prototype, "timeZoneId"); +assert.sameValue(typeof descriptor.get, "function"); +assert.sameValue(descriptor.set, undefined); +assert.sameValue(descriptor.enumerable, false); +assert.sameValue(descriptor.configurable, true); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toJSON/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toJSON/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..f3a62d7b3266 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toJSON/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.tojson +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const idOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "id"); +Object.defineProperty(Temporal.Calendar.prototype, "id", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("id should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.toJSON(); + +Object.defineProperty(Temporal.Calendar.prototype, "id", idOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toJSON/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toJSON/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..8f5de5a5603d --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toJSON/builtin-timezone-no-observable-calls.js @@ -0,0 +1,34 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.tojson +description: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); +const idOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "id"); +Object.defineProperty(Temporal.TimeZone.prototype, "id", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("id should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.toJSON(); + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); +Object.defineProperty(Temporal.TimeZone.prototype, "id", idOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toLocaleString/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toLocaleString/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..e820073c718f --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toLocaleString/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.tolocalestring +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const idOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "id"); +Object.defineProperty(Temporal.Calendar.prototype, "id", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("id should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.toLocaleString(); + +Object.defineProperty(Temporal.Calendar.prototype, "id", idOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toLocaleString/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toLocaleString/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..00ff2997c10c --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toLocaleString/builtin-timezone-no-observable-calls.js @@ -0,0 +1,34 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.tolocalestring +description: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); +const idOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "id"); +Object.defineProperty(Temporal.TimeZone.prototype, "id", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("id should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.toLocaleString(); + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); +Object.defineProperty(Temporal.TimeZone.prototype, "id", idOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toPlainDate/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toPlainDate/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..cf4cb037cf5c --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toPlainDate/builtin-timezone-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.toplaindate +description: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.toPlainDate(); + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toPlainDateTime/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toPlainDateTime/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..afaabb6410dd --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toPlainDateTime/builtin-timezone-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.toplaindatetime +description: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.toPlainDateTime(); + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toPlainDateTime/plain-custom-timezone.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toPlainDateTime/plain-custom-timezone.js index 55d04475f317..1ec1b9a7394d 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toPlainDateTime/plain-custom-timezone.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toPlainDateTime/plain-custom-timezone.js @@ -10,7 +10,9 @@ features: [Temporal] const actual = []; const expected = [ - "has timeZone.timeZone", + "has timeZone.getOffsetNanosecondsFor", + "has timeZone.getPossibleInstantsFor", + "has timeZone.id", "get timeZone.getOffsetNanosecondsFor", "call timeZone.getOffsetNanosecondsFor", ]; diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toPlainMonthDay/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toPlainMonthDay/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..0aa12beface7 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toPlainMonthDay/builtin-calendar-no-observable-calls.js @@ -0,0 +1,34 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.toplainmonthday +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const fieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "fields"); +Object.defineProperty(Temporal.Calendar.prototype, "fields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("fields should not be looked up"); + }, +}); +const monthDayFromFieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "monthDayFromFields"); +Object.defineProperty(Temporal.Calendar.prototype, "monthDayFromFields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("monthDayFromFields should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.toPlainMonthDay(); + +Object.defineProperty(Temporal.Calendar.prototype, "fields", fieldsOriginal); +Object.defineProperty(Temporal.Calendar.prototype, "monthDayFromFields", monthDayFromFieldsOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toPlainMonthDay/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toPlainMonthDay/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..96f1a3c5e620 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toPlainMonthDay/builtin-timezone-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.toplainmonthday +description: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.toPlainMonthDay(); + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toPlainTime/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toPlainTime/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..04fac73de947 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toPlainTime/builtin-timezone-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.toplaintime +description: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.toPlainTime(); + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toPlainYearMonth/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toPlainYearMonth/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..32a688f7ec36 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toPlainYearMonth/builtin-calendar-no-observable-calls.js @@ -0,0 +1,34 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.toplainyearmonth +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const fieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "fields"); +Object.defineProperty(Temporal.Calendar.prototype, "fields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("fields should not be looked up"); + }, +}); +const yearMonthFromFieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "yearMonthFromFields"); +Object.defineProperty(Temporal.Calendar.prototype, "yearMonthFromFields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("yearMonthFromFields should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.toPlainYearMonth(); + +Object.defineProperty(Temporal.Calendar.prototype, "fields", fieldsOriginal); +Object.defineProperty(Temporal.Calendar.prototype, "yearMonthFromFields", yearMonthFromFieldsOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toPlainYearMonth/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toPlainYearMonth/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..58916e557683 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toPlainYearMonth/builtin-timezone-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.toplainyearmonth +description: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.toPlainYearMonth(); + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..0f43ef3f1313 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 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: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const idOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "id"); +Object.defineProperty(Temporal.Calendar.prototype, "id", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("id should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.toString(); + +Object.defineProperty(Temporal.Calendar.prototype, "id", idOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..37682749831d --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/builtin-timezone-no-observable-calls.js @@ -0,0 +1,34 @@ +// Copyright (C) 2023 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: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); +const idOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "id"); +Object.defineProperty(Temporal.TimeZone.prototype, "id", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("id should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.toString(); + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); +Object.defineProperty(Temporal.TimeZone.prototype, "id", idOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/calendar-tostring.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/calendar-tostring.js index 8d88548e4425..3c4b251bedeb 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/calendar-tostring.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/calendar-tostring.js @@ -4,15 +4,39 @@ /*--- esid: sec-temporal.zoneddatetime.protoype.tostring description: Number of observable 'toString' calls on the calendar for each value of calendarName +includes: [temporalHelpers.js] features: [Temporal] ---*/ let calls; const customCalendar = { - toString() { + get id() { ++calls; return "custom"; - } + }, + toString() { + TemporalHelpers.assertUnreachable('toString should not be called'); + }, + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, }; const date = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, "UTC", customCalendar); [ @@ -24,6 +48,6 @@ const date = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, "UTC", custo ].forEach(([calendarName, expectedResult, expectedCalls]) => { calls = 0; const result = date.toString({ calendarName }); - assert.sameValue(result, expectedResult, `toString output for calendarName = ${calendarName}`); - assert.sameValue(calls, expectedCalls, `calls to toString for calendarName = ${calendarName}`); + assert.sameValue(result, expectedResult, `id for calendarName = ${calendarName}`); + assert.sameValue(calls, expectedCalls, `calls to id getter for calendarName = ${calendarName}`); }); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/calendarname-always.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/calendarname-always.js index 6deb4cfaa8eb..08d3803acda4 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/calendarname-always.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/calendarname-always.js @@ -7,12 +7,35 @@ description: If calendarName is "always", the calendar ID should be included. features: [Temporal] ---*/ +const calendarMethods = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; + const tests = [ [[], "1970-01-01T01:01:01.987654321+00:00[UTC][u-ca=iso8601]", "built-in ISO"], - [[{ toString() { return "custom"; } }], "1970-01-01T01:01:01.987654321+00:00[UTC][u-ca=custom]", "custom"], - [[{ toString() { return "iso8601"; } }], "1970-01-01T01:01:01.987654321+00:00[UTC][u-ca=iso8601]", "custom with iso8601 toString"], - [[{ toString() { return "ISO8601"; } }], "1970-01-01T01:01:01.987654321+00:00[UTC][u-ca=ISO8601]", "custom with caps toString"], - [[{ toString() { return "\u0131so8601"; } }], "1970-01-01T01:01:01.987654321+00:00[UTC][u-ca=\u0131so8601]", "custom with dotless i toString"], + [[{ id: "custom", ...calendarMethods }], "1970-01-01T01:01:01.987654321+00:00[UTC][u-ca=custom]", "custom"], + [[{ id: "iso8601", ...calendarMethods }], "1970-01-01T01:01:01.987654321+00:00[UTC][u-ca=iso8601]", "custom with iso8601 id"], + [[{ id: "ISO8601", ...calendarMethods }], "1970-01-01T01:01:01.987654321+00:00[UTC][u-ca=ISO8601]", "custom with caps id"], + [[{ id: "\u0131so8601", ...calendarMethods }], "1970-01-01T01:01:01.987654321+00:00[UTC][u-ca=\u0131so8601]", "custom with dotless i id"], ]; for (const [args, expected, description] of tests) { diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/calendarname-auto.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/calendarname-auto.js index fef22aebacb7..5685d98990bd 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/calendarname-auto.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/calendarname-auto.js @@ -7,12 +7,35 @@ description: If calendarName is "auto", "iso8601" should be omitted. features: [Temporal] ---*/ +const calendarMethods = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; + const tests = [ [[], "1970-01-01T01:01:01.987654321+00:00[UTC]", "built-in ISO"], - [[{ toString() { return "custom"; } }], "1970-01-01T01:01:01.987654321+00:00[UTC][u-ca=custom]", "custom"], - [[{ toString() { return "iso8601"; } }], "1970-01-01T01:01:01.987654321+00:00[UTC]", "custom with iso8601 toString"], - [[{ toString() { return "ISO8601"; } }], "1970-01-01T01:01:01.987654321+00:00[UTC][u-ca=ISO8601]", "custom with caps toString"], - [[{ toString() { return "\u0131so8601"; } }], "1970-01-01T01:01:01.987654321+00:00[UTC][u-ca=\u0131so8601]", "custom with dotless i toString"], + [[{ id: "custom", ...calendarMethods }], "1970-01-01T01:01:01.987654321+00:00[UTC][u-ca=custom]", "custom"], + [[{ id: "iso8601", ...calendarMethods }], "1970-01-01T01:01:01.987654321+00:00[UTC]", "custom with iso8601 id"], + [[{ id: "ISO8601", ...calendarMethods }], "1970-01-01T01:01:01.987654321+00:00[UTC][u-ca=ISO8601]", "custom with caps id"], + [[{ id: "\u0131so8601", ...calendarMethods }], "1970-01-01T01:01:01.987654321+00:00[UTC][u-ca=\u0131so8601]", "custom with dotless i id"], ]; for (const [args, expected, description] of tests) { diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/calendarname-critical.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/calendarname-critical.js index cd1742d82dfd..4cd5f7bcde0b 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/calendarname-critical.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/calendarname-critical.js @@ -9,12 +9,35 @@ description: > features: [Temporal] ---*/ +const calendarMethods = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; + const tests = [ [[], "1970-01-01T01:01:01.987654321+00:00[UTC][!u-ca=iso8601]", "built-in ISO"], - [[{ toString() { return "custom"; } }], "1970-01-01T01:01:01.987654321+00:00[UTC][!u-ca=custom]", "custom"], - [[{ toString() { return "iso8601"; } }], "1970-01-01T01:01:01.987654321+00:00[UTC][!u-ca=iso8601]", "custom with iso8601 toString"], - [[{ toString() { return "ISO8601"; } }], "1970-01-01T01:01:01.987654321+00:00[UTC][!u-ca=ISO8601]", "custom with caps toString"], - [[{ toString() { return "\u0131so8601"; } }], "1970-01-01T01:01:01.987654321+00:00[UTC][!u-ca=\u0131so8601]", "custom with dotless i toString"], + [[{ id: "custom", ...calendarMethods }], "1970-01-01T01:01:01.987654321+00:00[UTC][!u-ca=custom]", "custom"], + [[{ id: "iso8601", ...calendarMethods }], "1970-01-01T01:01:01.987654321+00:00[UTC][!u-ca=iso8601]", "custom with iso8601 id"], + [[{ id: "ISO8601", ...calendarMethods }], "1970-01-01T01:01:01.987654321+00:00[UTC][!u-ca=ISO8601]", "custom with caps id"], + [[{ id: "\u0131so8601", ...calendarMethods }], "1970-01-01T01:01:01.987654321+00:00[UTC][!u-ca=\u0131so8601]", "custom with dotless i id"], ]; for (const [args, expected, description] of tests) { diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/calendarname-never.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/calendarname-never.js index 621c8a8c8ed3..23d81baa91bc 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/calendarname-never.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/calendarname-never.js @@ -7,12 +7,35 @@ description: If calendarName is "never", the calendar ID should be omitted. features: [Temporal] ---*/ +const calendarMethods = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; + const tests = [ [[], "1970-01-01T01:01:01.987654321+00:00[UTC]", "built-in ISO"], - [[{ toString() { return "custom"; } }], "1970-01-01T01:01:01.987654321+00:00[UTC]", "custom"], - [[{ toString() { return "iso8601"; } }], "1970-01-01T01:01:01.987654321+00:00[UTC]", "custom with iso8601 toString"], - [[{ toString() { return "ISO8601"; } }], "1970-01-01T01:01:01.987654321+00:00[UTC]", "custom with caps toString"], - [[{ toString() { return "\u0131so8601"; } }], "1970-01-01T01:01:01.987654321+00:00[UTC]", "custom with dotless i toString"], + [[{ id: "custom", ...calendarMethods }], "1970-01-01T01:01:01.987654321+00:00[UTC]", "custom"], + [[{ id: "iso8601", ...calendarMethods }], "1970-01-01T01:01:01.987654321+00:00[UTC]", "custom with iso8601 id"], + [[{ id: "ISO8601", ...calendarMethods }], "1970-01-01T01:01:01.987654321+00:00[UTC]", "custom with caps id"], + [[{ id: "\u0131so8601", ...calendarMethods }], "1970-01-01T01:01:01.987654321+00:00[UTC]", "custom with dotless i id"], ]; for (const [args, expected, description] of tests) { diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/calendarname-undefined.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/calendarname-undefined.js index 3464bc79c21d..245597ed63bd 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/calendarname-undefined.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/calendarname-undefined.js @@ -14,12 +14,35 @@ info: | features: [Temporal] ---*/ +const calendarMethods = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; + const tests = [ [[], "1970-01-01T01:01:01.987654321+00:00[UTC]", "built-in ISO"], - [[{ toString() { return "custom"; } }], "1970-01-01T01:01:01.987654321+00:00[UTC][u-ca=custom]", "custom"], - [[{ toString() { return "iso8601"; } }], "1970-01-01T01:01:01.987654321+00:00[UTC]", "custom with iso8601 toString"], - [[{ toString() { return "ISO8601"; } }], "1970-01-01T01:01:01.987654321+00:00[UTC][u-ca=ISO8601]", "custom with caps toString"], - [[{ toString() { return "\u0131so8601"; } }], "1970-01-01T01:01:01.987654321+00:00[UTC][u-ca=\u0131so8601]", "custom with dotless i toString"], + [[{ id: "custom", ...calendarMethods }], "1970-01-01T01:01:01.987654321+00:00[UTC][u-ca=custom]", "custom"], + [[{ id: "iso8601", ...calendarMethods }], "1970-01-01T01:01:01.987654321+00:00[UTC]", "custom with iso8601 id"], + [[{ id: "ISO8601", ...calendarMethods }], "1970-01-01T01:01:01.987654321+00:00[UTC][u-ca=ISO8601]", "custom with caps id"], + [[{ id: "\u0131so8601", ...calendarMethods }], "1970-01-01T01:01:01.987654321+00:00[UTC][u-ca=\u0131so8601]", "custom with dotless i id"], ]; for (const [args, expected, description] of tests) { diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/calendarname-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/calendarname-wrong-type.js index 14e15ecd2a63..21bca7e70e28 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/calendarname-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/calendarname-wrong-type.js @@ -16,7 +16,27 @@ features: [Temporal] ---*/ const calendar = { - toString() { return "custom"; } + id: "custom", + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, }; const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, "UTC", calendar); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/options-undefined.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/options-undefined.js index 4d5280cbf003..c8ba5fce0f56 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/options-undefined.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/options-undefined.js @@ -8,7 +8,27 @@ features: [Temporal] ---*/ const calendar = { - toString() { return "custom"; } + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "custom", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, }; const datetime1 = new Temporal.ZonedDateTime(957270896_987_650_000n, "UTC"); const datetime2 = new Temporal.ZonedDateTime(957270896_987_650_000n, "UTC", calendar); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/order-of-operations.js index 9c11a5cd9d4c..59e4dc1c0669 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/order-of-operations.js @@ -31,12 +31,8 @@ const expected = [ "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", + "get this.timeZone.id", + "get this.calendar.id", ]; const actual = []; @@ -81,12 +77,8 @@ const expectedForFractionalSecondDigits = [ "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", + "get this.timeZone.id", + "get this.calendar.id", ]; instance.toString( diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/timezonename-auto.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/timezonename-auto.js index 10e97af7086e..46f1b57c3bf3 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/timezonename-auto.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/timezonename-auto.js @@ -12,7 +12,8 @@ const tests = [ ["+01:00", "1970-01-01T02:01:01.987654321+01:00[+01:00]", "built-in offset"], [{ getOffsetNanosecondsFor() { return 0; }, - toString() { return "Etc/Custom"; }, + getPossibleInstantsFor() { return []; }, + id: "Etc/Custom", }, "1970-01-01T01:01:01.987654321+00:00[Etc/Custom]", "custom"], ]; diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/timezonename-critical.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/timezonename-critical.js index 05698e8272f0..b20ebe5d7a78 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/timezonename-critical.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/timezonename-critical.js @@ -14,7 +14,8 @@ const tests = [ ["+01:00", "1970-01-01T02:01:01.987654321+01:00[!+01:00]", "built-in offset"], [{ getOffsetNanosecondsFor() { return 0; }, - toString() { return "Etc/Custom"; }, + getPossibleInstantsFor() { return []; }, + id: "Etc/Custom", }, "1970-01-01T01:01:01.987654321+00:00[!Etc/Custom]", "custom"], ]; diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/timezonename-never.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/timezonename-never.js index 632dff2ccb25..5f87ca06bb80 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/timezonename-never.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/toString/timezonename-never.js @@ -12,7 +12,8 @@ const tests = [ ["+01:00", "1970-01-01T02:01:01.987654321+01:00", "built-in offset"], [{ getOffsetNanosecondsFor() { return 0; }, - toString() { return "Etc/Custom"; }, + getPossibleInstantsFor() { return []; }, + id: "Etc/Custom", }, "1970-01-01T01:01:01.987654321+00:00", "custom"], ]; diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-case-insensitive.js index 7d95519d22c5..c822b03b28c4 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-case-insensitive.js @@ -13,10 +13,6 @@ const instance = new Temporal.ZonedDateTime(0n, timeZone); const calendar = "IsO8601"; -let arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; -const result1 = instance.until(arg); -TemporalHelpers.assertDuration(result1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Calendar is case-insensitive"); - -arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar: { calendar } }; -const result2 = instance.until(arg); -TemporalHelpers.assertDuration(result2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Calendar is case-insensitive (nested property)"); +const arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; +const result = instance.until(arg); +TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 092aa0035297..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,26 +0,0 @@ -// 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.until -description: > - A Temporal.Calendar instance passed to until() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const timeZone = new Temporal.TimeZone("UTC"); -const instance = new Temporal.ZonedDateTime(0n, timeZone); - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -let arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; -instance.until(arg); - -arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar: { calendar } }; -instance.until(arg); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-leap-second.js index df3b9989a817..3d98103d9382 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-leap-second.js @@ -13,18 +13,10 @@ const instance = new Temporal.ZonedDateTime(0n, timeZone); const calendar = "2016-12-31T23:59:60+00:00[UTC]"; -let arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; -const result1 = instance.until(arg); +const arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; +const result = instance.until(arg); TemporalHelpers.assertDuration( - result1, + result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "leap second is a valid ISO string for calendar" ); - -arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar: { calendar } }; -const result2 = instance.until(arg); -TemporalHelpers.assertDuration( - result2, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-number.js index 7db7eaa625bb..80f6fa3f5b89 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-number.js @@ -13,13 +13,9 @@ const instance = new Temporal.ZonedDateTime(0n, timeZone); const calendar = 19970327; -let arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; -const result1 = instance.until(arg); -TemporalHelpers.assertDuration(result1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar"); - -arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar: { calendar } }; -const result2 = instance.until(arg); -TemporalHelpers.assertDuration(result2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; +const result = instance.until(arg); +TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -28,16 +24,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; + const arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; assert.throws( RangeError, () => instance.until(arg), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.until(arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-wrong-type.js index a2d75d18de47..b2ab7ba25948 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-wrong-type.js @@ -21,27 +21,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.until(arg), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.until(arg), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.until(arg), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.until(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.until(arg), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-timezone-instance-does-not-get-timeZone-property.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-timezone-instance-does-not-get-timeZone-property.js deleted file mode 100644 index f38e636c65cf..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-timezone-instance-does-not-get-timeZone-property.js +++ /dev/null @@ -1,22 +0,0 @@ -// 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.until -description: > - A Temporal.TimeZone instance passed to until() does not have its - 'timeZone' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.ZonedDateTime(0n, new Temporal.TimeZone("UTC")); - -const timeZone = new Temporal.TimeZone("UTC"); -Object.defineProperty(timeZone, "timeZone", { - get() { - throw new Test262Error("timeZone.timeZone should not be accessed"); - }, -}); - -instance.until({ year: 2020, month: 5, day: 2, timeZone }); -instance.until({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-timezone-string-datetime.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-timezone-string-datetime.js index 55eaf690121d..ad74231922ea 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-timezone-string-datetime.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-timezone-string-datetime.js @@ -12,7 +12,6 @@ const instance1 = new Temporal.ZonedDateTime(0n, expectedTimeZone); let timeZone = "2021-08-19T17:30"; assert.throws(RangeError, () => instance1.until({ year: 2020, month: 5, day: 2, timeZone }), "bare date-time string is not a time zone"); -assert.throws(RangeError, () => instance1.until({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }), "bare date-time string is not a time zone"); // The following are all valid strings so should not throw. They should produce // expectedTimeZone, so additionally the operation will not throw due to the @@ -20,24 +19,19 @@ assert.throws(RangeError, () => instance1.until({ year: 2020, month: 5, day: 2, timeZone = "2021-08-19T17:30Z"; instance1.until({ year: 2020, month: 5, day: 2, timeZone }); -instance1.until({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }); expectedTimeZone = "-07:00"; const instance2 = new Temporal.ZonedDateTime(0n, expectedTimeZone); timeZone = "2021-08-19T17:30-07:00"; instance2.until({ year: 2020, month: 5, day: 2, timeZone }); -instance2.until({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }); expectedTimeZone = "UTC"; const instance3 = new Temporal.ZonedDateTime(0n, expectedTimeZone); timeZone = "2021-08-19T17:30[UTC]"; instance3.until({ year: 2020, month: 5, day: 2, timeZone }); -instance3.until({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }); timeZone = "2021-08-19T17:30Z[UTC]"; instance3.until({ year: 2020, month: 5, day: 2, timeZone }); -instance3.until({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }); timeZone = "2021-08-19T17:30-07:00[UTC]"; instance3.until({ year: 2020, month: 5, day: 2, timeZone }); -instance3.until({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-timezone-string-leap-second.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-timezone-string-leap-second.js index 40dddba2e70d..337d3d893de2 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-timezone-string-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-timezone-string-leap-second.js @@ -11,13 +11,11 @@ const expectedTimeZone = "UTC"; const instance = new Temporal.ZonedDateTime(0n, expectedTimeZone); let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; -// These operations should produce expectedTimeZone, so the following operations +// This operation should produce expectedTimeZone, so the following operation // should not throw due to the time zones being different on the receiver and // the argument. instance.until({ year: 2020, month: 5, day: 2, timeZone }); -instance.until({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }); timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; assert.throws(RangeError, () => instance.until({ year: 2020, month: 5, day: 2, timeZone }), "leap second in time zone name not valid"); -assert.throws(RangeError, () => instance.until({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }), "leap second in time zone name not valid (nested property)"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-timezone-string-multiple-offsets.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-timezone-string-multiple-offsets.js index 1adbcb423901..c1d88c4c242f 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-timezone-string-multiple-offsets.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-timezone-string-multiple-offsets.js @@ -11,9 +11,8 @@ const expectedTimeZone = "+01:45:30.987654321"; const instance = new Temporal.ZonedDateTime(0n, expectedTimeZone); const timeZone = "2021-08-19T17:30:45.123456789+01:46[+01:45:30.987654321]"; -// These operations should produce expectedTimeZone, so the following operations +// This operation should produce expectedTimeZone, so the following operation // should not throw due to the time zones being different on the receiver and // the argument. instance.until({ year: 2020, month: 5, day: 2, timeZone }); -instance.until({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-timezone-string-year-zero.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-timezone-string-year-zero.js index c733c4103ead..3e01e23583eb 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-timezone-string-year-zero.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-timezone-string-year-zero.js @@ -18,9 +18,4 @@ invalidStrings.forEach((timeZone) => { () => instance.until({ year: 2020, month: 5, day: 2, timeZone }), "reject minus zero as extended year" ); - assert.throws( - RangeError, - () => instance.until({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }), - "reject minus zero as extended year (nested property)" - ); }); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-timezone-string.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-timezone-string.js index 24ff2b4ce25e..3e6f906f4910 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-timezone-string.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-timezone-string.js @@ -4,11 +4,32 @@ /*--- esid: sec-temporal.zoneddatetime.prototype.until description: Time zone IDs are valid input for a time zone +includes: [temporalHelpers.js] features: [Temporal] ---*/ +const getPossibleInstantsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getPossibleInstantsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getPossibleInstantsFor should not be looked up"); + }, +}); +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + const instance1 = new Temporal.ZonedDateTime(0n, new Temporal.TimeZone("UTC")); assert(instance1.until({ year: 1970, month: 1, day: 1, timeZone: "UTC" }).blank, "Time zone created from string 'UTC'"); const instance2 = new Temporal.ZonedDateTime(0n, new Temporal.TimeZone("-01:30")); assert(instance2.until({ year: 1969, month: 12, day: 31, hour: 22, minute: 30, timeZone: "-01:30" }).blank, "Time zone created from string '-01:30'"); + +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", getPossibleInstantsForOriginal); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-timezone-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-timezone-wrong-type.js index 7d752202d6ca..9f3dcd50419f 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-timezone-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-timezone-wrong-type.js @@ -18,22 +18,18 @@ const rangeErrorTests = [ [1, "number that doesn't convert to a valid ISO string"], [19761118, "number that would convert to a valid ISO string in other contexts"], [1n, "bigint"], - [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of rangeErrorTests) { assert.throws(RangeError, () => instance.until({ year: 2020, month: 5, day: 2, timeZone }), `${description} does not convert to a valid ISO string`); - assert.throws(RangeError, () => instance.until({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], + [{}, "object not implementing time zone protocol"], + [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of typeErrorTests) { assert.throws(TypeError, () => instance.until({ year: 2020, month: 5, day: 2, timeZone }), `${description} is not a valid object and does not convert to a string`); - assert.throws(TypeError, () => instance.until({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }), `${description} is not a valid object and does not convert to a string (nested property)`); } - -const timeZone = undefined; -assert.throws(RangeError, () => instance.until({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }), `undefined is always a RangeError as nested property`); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-string-calendar-annotation.js index eebcfa79b702..832a57b7c5d0 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-string-calendar-annotation.js @@ -12,7 +12,6 @@ const tests = [ ["1970-01-01T00:00[UTC][u-ca=iso8601]", "without !"], ["1970-01-01T00:00[UTC][!u-ca=iso8601]", "with !"], ["1970-01-01T00:00[UTC][u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const timeZone = new Temporal.TimeZone("UTC"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..1d028c548283 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-string-multiple-calendar.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.until +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[UTC][!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.ZonedDateTime(0n, timeZone); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.until(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..598a9f698b0b --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.until +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const dateUntilOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dateUntil"); +Object.defineProperty(Temporal.Calendar.prototype, "dateUntil", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("dateUntil should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.until(new Temporal.ZonedDateTime(1_100_000_000_000_000_000n, "UTC")); + +Object.defineProperty(Temporal.Calendar.prototype, "dateUntil", dateUntilOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..369dddc46281 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/builtin-timezone-no-observable-calls.js @@ -0,0 +1,34 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.until +description: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); +const getPossibleInstantsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getPossibleInstantsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getPossibleInstantsFor should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.until(new Temporal.ZonedDateTime(1_100_000_000_000_000_000n, "UTC")); + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", getPossibleInstantsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/order-of-operations.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/order-of-operations.js index e325000ea1d7..9a7d72c48ebd 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/order-of-operations.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/until/order-of-operations.js @@ -11,7 +11,27 @@ features: [Temporal] const expected = [ // ToTemporalZonedDateTime "get other.calendar", - "has other.calendar.calendar", + "has other.calendar.dateAdd", + "has other.calendar.dateFromFields", + "has other.calendar.dateUntil", + "has other.calendar.day", + "has other.calendar.dayOfWeek", + "has other.calendar.dayOfYear", + "has other.calendar.daysInMonth", + "has other.calendar.daysInWeek", + "has other.calendar.daysInYear", + "has other.calendar.fields", + "has other.calendar.id", + "has other.calendar.inLeapYear", + "has other.calendar.mergeFields", + "has other.calendar.month", + "has other.calendar.monthCode", + "has other.calendar.monthDayFromFields", + "has other.calendar.monthsInYear", + "has other.calendar.weekOfYear", + "has other.calendar.year", + "has other.calendar.yearMonthFromFields", + "has other.calendar.yearOfWeek", "get other.calendar.fields", "call other.calendar.fields", "get other.day", @@ -48,7 +68,9 @@ const expected = [ "get other.year", "get other.year.valueOf", "call other.year.valueOf", - "has other.timeZone.timeZone", + "has other.timeZone.getOffsetNanosecondsFor", + "has other.timeZone.getPossibleInstantsFor", + "has other.timeZone.id", "get other.calendar.dateFromFields", "call other.calendar.dateFromFields", "get other.timeZone.getPossibleInstantsFor", @@ -56,12 +78,8 @@ const expected = [ "get other.timeZone.getOffsetNanosecondsFor", "call other.timeZone.getOffsetNanosecondsFor", // CalendarEquals - "get this.calendar[Symbol.toPrimitive]", - "get this.calendar.toString", - "call this.calendar.toString", - "get other.calendar[Symbol.toPrimitive]", - "get other.calendar.toString", - "call other.calendar.toString", + "get this.calendar.id", + "get other.calendar.id", // CopyDataProperties "ownKeys options", "getOwnPropertyDescriptor options.roundingIncrement", @@ -129,12 +147,8 @@ actual.splice(0); // clear // Making largestUnit a calendar unit adds the following observable operations: const expectedOpsForCalendarDifference = [ // 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", + "get this.timeZone.id", + "get other.timeZone.id", // DifferenceZonedDateTime "get this.timeZone.getOffsetNanosecondsFor", "call this.timeZone.getOffsetNanosecondsFor", @@ -231,4 +245,9 @@ const expectedOpsForWeekRounding = expected.concat(expectedOpsForCalendarDiffere "call this.calendar.dateAdd", // 11.d MoveRelativeDate ]); // (11.g.iii MoveRelativeDate not called because days already balanced) instance.until(otherDateTimePropertyBag, createOptionsObserver({ smallestUnit: "weeks" })); -assert.compareArray(actual.slice(expected.length), expectedOpsForWeekRounding.slice(expected.length), "order of operations with smallestUnit = weeks"); +assert.compareArray(actual, expectedOpsForWeekRounding, "order of operations with smallestUnit = weeks"); +actual.splice(0); // clear + +instance.until(otherDateTimePropertyBag, createOptionsObserver({ largestUnit: "hours" })); +assert.compareArray(actual, expected, "order of operations with largestUnit being a time unit"); +actual.splice(0); // clear diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/weekOfYear/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/weekOfYear/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..6b49dbdd5381 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/weekOfYear/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.weekofyear +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const weekOfYearOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "weekOfYear"); +Object.defineProperty(Temporal.Calendar.prototype, "weekOfYear", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("weekOfYear should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.weekOfYear; + +Object.defineProperty(Temporal.Calendar.prototype, "weekOfYear", weekOfYearOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/weekOfYear/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/weekOfYear/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..249c94c771af --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/weekOfYear/builtin-timezone-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.weekofyear +description: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.weekOfYear; + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/with/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/with/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..18558046b7a5 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/with/builtin-calendar-no-observable-calls.js @@ -0,0 +1,43 @@ +// Copyright (C) 2023 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: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const fieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "fields"); +Object.defineProperty(Temporal.Calendar.prototype, "fields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("fields should not be looked up"); + }, +}); +const mergeFieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "mergeFields"); +Object.defineProperty(Temporal.Calendar.prototype, "mergeFields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("mergeFields should not be looked up"); + }, +}); +const dateFromFieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dateFromFields"); +Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("dateFromFields should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.with({ year: 2001 }); + +Object.defineProperty(Temporal.Calendar.prototype, "fields", fieldsOriginal); +Object.defineProperty(Temporal.Calendar.prototype, "mergeFields", mergeFieldsOriginal); +Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", dateFromFieldsOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/with/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/with/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..ed8075079b04 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/with/builtin-timezone-no-observable-calls.js @@ -0,0 +1,34 @@ +// Copyright (C) 2023 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: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); +const getPossibleInstantsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getPossibleInstantsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getPossibleInstantsFor should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.with({ year: 2001 }); + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", getPossibleInstantsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/with/timezone-getoffsetnanosecondsfor-not-callable.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/with/timezone-getoffsetnanosecondsfor-not-callable.js index 18412e810e96..bd2f5c3799eb 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/with/timezone-getoffsetnanosecondsfor-not-callable.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/with/timezone-getoffsetnanosecondsfor-not-callable.js @@ -18,6 +18,7 @@ features: [BigInt, Symbol, Temporal, arrow-function] ); const badTimeZone = { + id: "Etc/Bad", getPossibleInstantsFor() { return []; }, getOffsetNanosecondsFor: notCallable, }; diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..cfd2824753ca --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withcalendar +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const idOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "id"); +Object.defineProperty(Temporal.Calendar.prototype, "id", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("id should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.withCalendar("iso8601"); + +Object.defineProperty(Temporal.Calendar.prototype, "id", idOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-case-insensitive.js index 3320cdc5a852..5fdfeee78278 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-case-insensitive.js @@ -7,8 +7,30 @@ description: Calendar names are case-insensitive features: [Temporal] ---*/ -const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", { id: "replace-me" }); +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "replace-me", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}); const arg = "iSo8601"; const result = instance.withCalendar(arg); -assert.sameValue(result.calendar.id, "iso8601", "Calendar is case-insensitive"); +assert.sameValue(result.calendarId, "iso8601", "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index aaa5083ddf4c..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,22 +0,0 @@ -// 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.withcalendar -description: > - A Temporal.Calendar instance passed to withCalendar() does not have its - 'calendar' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", { id: "replace-me" }); - -const arg = new Temporal.Calendar("iso8601"); -Object.defineProperty(arg, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -instance.withCalendar(arg); -instance.withCalendar({ calendar: arg }); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-number.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-number.js index 0a299d540fb0..b7a194d78707 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-number.js @@ -7,12 +7,34 @@ description: A number is converted to a string, then to Temporal.Calendar features: [Temporal] ---*/ -const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", { id: "replace-me" }); +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "replace-me", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}); const arg = 19761118; const result = instance.withCalendar(arg); -assert.sameValue(result.calendar.id, "iso8601", "19761118 is a valid ISO string for Calendar"); +assert.sameValue(result.calendarId, "iso8601", "19761118 is a valid ISO string for Calendar"); const numbers = [ 1, diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-string-leap-second.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-string-leap-second.js index 29e229cc10a2..8f1dda0f1419 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-string-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-string-leap-second.js @@ -7,20 +7,34 @@ description: Leap second is a valid ISO string for Calendar features: [Temporal] ---*/ -const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", { id: "replace-me" }); +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "replace-me", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}); -let arg = "2016-12-31T23:59:60"; -const result1 = instance.withCalendar(arg); +const arg = "2016-12-31T23:59:60"; +const result = instance.withCalendar(arg); assert.sameValue( - result1.calendar.id, + result.calendarId, "iso8601", "leap second is a valid ISO string for Calendar" ); - -arg = { calendar: "2016-12-31T23:59:60" }; -const result2 = instance.withCalendar(arg); -assert.sameValue( - result2.calendar.id, - "iso8601", - "leap second is a valid ISO string for Calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-string.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-string.js index 83b7743d845a..7760408bc904 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-string.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-string.js @@ -7,9 +7,31 @@ description: A calendar ID is valid input for Calendar features: [Temporal] ---*/ -const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", { id: "replace-me" }); +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "replace-me", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}); const arg = "iso8601"; const result = instance.withCalendar(arg); -assert.sameValue(result.calendar.id, "iso8601", `Calendar created from string "${arg}"`); +assert.sameValue(result.getISOFields().calendar, "iso8601", `Calendar created from string "${arg}"`); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-temporal-object.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-temporal-object.js index 3cd5a97176a8..8ab731918d8b 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-temporal-object.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-temporal-object.js @@ -6,7 +6,7 @@ esid: sec-temporal.zoneddatetime.prototype.withcalendar description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots info: | sec-temporal-totemporalcalendar step 1.b: - b. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then + b. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then i. Return _temporalCalendarLike_.[[Calendar]]. includes: [compareArray.js] features: [Temporal] @@ -14,12 +14,11 @@ features: [Temporal] const plainDate = new Temporal.PlainDate(2000, 5, 2); const plainDateTime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); -const plainTime = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); const plainMonthDay = new Temporal.PlainMonthDay(5, 2); const plainYearMonth = new Temporal.PlainYearMonth(2000, 5); const zonedDateTime = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); -[plainDate, plainDateTime, plainTime, plainMonthDay, plainYearMonth, zonedDateTime].forEach((arg) => { +[plainDate, plainDateTime, plainMonthDay, plainYearMonth, zonedDateTime].forEach((arg) => { const actual = []; const expected = []; @@ -32,9 +31,31 @@ const zonedDateTime = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UT }, }); - const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", { id: "replace-me" }); + const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "replace-me", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}); const result = instance.withCalendar(arg); - assert.sameValue(result.calendar, calendar, "Temporal object coerced to calendar"); + assert.sameValue(result.getISOFields().calendar, calendar, "Temporal object coerced to calendar"); assert.compareArray(actual, expected, "calendar getter not called"); }); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-wrong-type.js index ffd81eb7e746..55b122aed456 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-wrong-type.js @@ -9,7 +9,29 @@ description: > features: [BigInt, Symbol, Temporal] ---*/ -const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", { id: "replace-me" }); +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "replace-me", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}); const rangeErrorTests = [ [null, "null"], @@ -17,19 +39,19 @@ const rangeErrorTests = [ ["", "empty string"], [1, "number that doesn't convert to a valid ISO string"], [1n, "bigint"], - [new Temporal.TimeZone("UTC"), "time zone instance"], ]; for (const [arg, description] of rangeErrorTests) { assert.throws(RangeError, () => instance.withCalendar(arg), `${description} does not convert to a valid ISO string`); - assert.throws(RangeError, () => instance.withCalendar({ calendar: arg }), `${description} does not convert to a valid ISO string (in property bag)`); } const typeErrorTests = [ [Symbol(), "symbol"], + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], ]; for (const [arg, description] of typeErrorTests) { assert.throws(TypeError, () => instance.withCalendar(arg), `${description} is not a valid object and does not convert to a string`); - assert.throws(TypeError, () => instance.withCalendar({ calendar: arg }), `${description} is not a valid object and does not convert to a string (in property bag)`); } diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/subclassing-ignored.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/subclassing-ignored.js index f044a122de30..1bffb6ac9d49 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/subclassing-ignored.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/subclassing-ignored.js @@ -13,6 +13,24 @@ const customCalendar = { month() { return 2; }, day() { return 5; }, toString() { return "custom-calendar"; }, + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "custom-calendar", + inLeapYear() {}, + mergeFields() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, }; TemporalHelpers.checkSubclassingIgnored( @@ -31,6 +49,6 @@ TemporalHelpers.checkSubclassingIgnored( assert.sameValue(result.millisecond, 0, "millisecond result"); assert.sameValue(result.microsecond, 0, "microsecond result"); assert.sameValue(result.nanosecond, 10, "nanosecond result"); - assert.sameValue(result.calendar, customCalendar, "calendar result"); + assert.sameValue(result.getCalendar(), customCalendar, "calendar result"); }, ); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-propertybag-calendar-case-insensitive.js index dc12a0647008..1da159c22d29 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-propertybag-calendar-case-insensitive.js @@ -12,10 +12,6 @@ const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, timeZone const calendar = "IsO8601"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.withPlainDate(arg); -assert.sameValue(result1.epochNanoseconds, 217_129_600_000_000_000n, "Calendar is case-insensitive"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.withPlainDate(arg); -assert.sameValue(result2.epochNanoseconds, 217_129_600_000_000_000n, "Calendar is case-insensitive (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.withPlainDate(arg); +assert.sameValue(result.epochNanoseconds, 217_129_600_000_000_000n, "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 82bae0ce0f5c..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,26 +0,0 @@ -// 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.withplaindate -description: > - A Temporal.Calendar instance passed to withPlainDate() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const timeZone = new Temporal.TimeZone("UTC"); -const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, timeZone); - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -instance.withPlainDate(arg); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -instance.withPlainDate(arg); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-propertybag-calendar-leap-second.js index ebc5f7ce7fdb..4d034e16c59e 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-propertybag-calendar-leap-second.js @@ -12,18 +12,10 @@ const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, timeZone const calendar = "2016-12-31T23:59:60+00:00[UTC]"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.withPlainDate(arg); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.withPlainDate(arg); assert.sameValue( - result1.epochNanoseconds, + result.epochNanoseconds, 217_129_600_000_000_000n, "leap second is a valid ISO string for calendar" ); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.withPlainDate(arg); -assert.sameValue( - result2.epochNanoseconds, - 217_129_600_000_000_000n, - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-propertybag-calendar-number.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-propertybag-calendar-number.js index b5c7061ced56..96d1f007491a 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-propertybag-calendar-number.js @@ -12,13 +12,9 @@ const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, timeZone const calendar = 19970327; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.withPlainDate(arg); -assert.sameValue(result1.epochNanoseconds, 217_129_600_000_000_000n, "19970327 is a valid ISO string for calendar"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.withPlainDate(arg); -assert.sameValue(result2.epochNanoseconds, 217_129_600_000_000_000n, "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.withPlainDate(arg); +assert.sameValue(result.epochNanoseconds, 217_129_600_000_000_000n, "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -27,16 +23,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; assert.throws( RangeError, () => instance.withPlainDate(arg), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.withPlainDate(arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-propertybag-calendar-wrong-type.js index 54ed639ee706..f1c28a2d2aa1 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-propertybag-calendar-wrong-type.js @@ -21,27 +21,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.withPlainDate(arg), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.withPlainDate(arg), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.withPlainDate(arg), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.withPlainDate(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.withPlainDate(arg), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-string-calendar-annotation.js index 0d25c4c3d00a..37e63c148990 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-string-calendar-annotation.js @@ -15,7 +15,6 @@ const tests = [ ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const timeZone = new Temporal.TimeZone("UTC"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..e28544dc36ec --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-string-multiple-calendar.js @@ -0,0 +1,30 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaindate +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.ZonedDateTime(0n, timeZone); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.withPlainDate(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..abb4cb52e139 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaindate +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const idOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "id"); +Object.defineProperty(Temporal.Calendar.prototype, "id", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("id should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.withPlainDate(new Temporal.PlainDate(2001, 6, 13)); + +Object.defineProperty(Temporal.Calendar.prototype, "id", idOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..11a9044fb528 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/builtin-timezone-no-observable-calls.js @@ -0,0 +1,34 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaindate +description: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); +const getPossibleInstantsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getPossibleInstantsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getPossibleInstantsFor should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.withPlainDate(new Temporal.PlainDate(2001, 6, 13)); + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", getPossibleInstantsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/calendar-temporal-object.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/calendar-temporal-object.js index a7423b74a8b7..f4acd3a39e71 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/calendar-temporal-object.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/calendar-temporal-object.js @@ -24,5 +24,5 @@ TemporalHelpers.checkToTemporalCalendarFastPath((temporalObject, calendar) => { const datetime = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); // the PlainDate's calendar will override the ZonedDateTime's ISO calendar const result = datetime.withPlainDate({ year: 2001, month: 6, day: 4, calendar: temporalObject }); - assert.sameValue(result.calendar, calendar, "Temporal object coerced to calendar"); + assert.sameValue(result.getCalendar(), calendar, "Temporal object coerced to calendar"); }); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-calendar-annotation.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-calendar-annotation.js index f18dc778d537..fc696e797548 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-calendar-annotation.js @@ -20,8 +20,10 @@ const tests = [ ["1970-01-01T12:34:56.987654321[UTC][u-ca=iso8601]", "with date and time zone"], ["1970-01-01T12:34:56.987654321[!u-ca=iso8601]", "with !, date, and no time zone"], ["1970-01-01T12:34:56.987654321[UTC][!u-ca=iso8601]", "with !, date, and time zone"], + ["12:34:56.987654321[u-ca=hebrew]", "calendar annotation ignored"], + ["12:34:56.987654321[u-ca=unknown]", "calendar annotation ignored even if unknown calendar"], + ["12:34:56.987654321[!u-ca=unknown]", "calendar annotation ignored even if unknown calendar with !"], ["1970-01-01T12:34:56.987654321[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["1970-01-01T12:34:56.987654321[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const timeZone = new Temporal.TimeZone("UTC"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-multiple-calendar.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..7b83150ee5b7 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-multiple-calendar.js @@ -0,0 +1,30 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaintime +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "00:00[u-ca=iso8601][!u-ca=iso8601]", + "00:00[!u-ca=iso8601][u-ca=iso8601]", + "00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.ZonedDateTime(0n, timeZone); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.withPlainTime(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..47fef9727698 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/builtin-timezone-no-observable-calls.js @@ -0,0 +1,34 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaintime +description: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); +const getPossibleInstantsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getPossibleInstantsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getPossibleInstantsFor should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.withPlainTime(new Temporal.PlainTime(12, 34, 56)); + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", getPossibleInstantsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/calendar-temporal-object.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/calendar-temporal-object.js deleted file mode 100644 index dc5866225db7..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/calendar-temporal-object.js +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.plaindatetime.prototype.withplaintime -description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots -info: | - sec-temporal.plaindatetime.prototype.withplaintime step 4: - 3. Let _plainTime_ be ? ToTemporalTime(_plainTimeLike_). - sec-temporal-totemporaltime step 3.d: - d. If _calendar_ is not *undefined*, then - i. Set _calendar_ to ? ToTemporalCalendar(_calendar_). - ii. If ? ToString(_calendar_) is not *"iso8601"*, then - 1. Throw a *RangeError* exception. - sec-temporal-totemporalcalendar step 1.a: - a. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then - i. Return _temporalCalendarLike_.[[Calendar]]. -includes: [compareArray.js, temporalHelpers.js] -features: [Temporal] ----*/ - -TemporalHelpers.checkToTemporalCalendarFastPath((temporalObject) => { - const datetime = new Temporal.PlainDateTime(2000, 5, 3, 13, 3, 27, 123, 456, 789); - assert.throws(RangeError, () => datetime.withPlainTime({ hour: 12, minute: 30, calendar: temporalObject })); -}); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..83ef37833212 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/builtin-timezone-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withtimezone +description: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const idOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "id"); +Object.defineProperty(Temporal.TimeZone.prototype, "id", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("id should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.withTimeZone("+01:00"); + +Object.defineProperty(Temporal.TimeZone.prototype, "id", idOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-case-insensitive.js index d977516ea944..7a9338cfbb09 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-case-insensitive.js @@ -7,8 +7,8 @@ description: Time zone names are case insensitive features: [Temporal] ---*/ -const instance = new Temporal.ZonedDateTime(0n, "UTC"); +const instance = new Temporal.ZonedDateTime(0n, "UTC"); const timeZone = 'uTc'; const result = instance.withTimeZone(timeZone); -assert.sameValue(result.timeZone.id, 'UTC', `Time zone created from string "${timeZone}"`); +assert.sameValue(result.timeZoneId, 'UTC', `Time zone created from string "${timeZone}"`); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-instance-does-not-get-timeZone-property.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-instance-does-not-get-timeZone-property.js deleted file mode 100644 index 2bd86e7e5b19..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-instance-does-not-get-timeZone-property.js +++ /dev/null @@ -1,22 +0,0 @@ -// 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.withtimezone -description: > - A Temporal.TimeZone instance passed to withTimeZone() does not have its - 'timeZone' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.ZonedDateTime(0n, new Temporal.TimeZone("UTC")); - -const timeZone = new Temporal.TimeZone("UTC"); -Object.defineProperty(timeZone, "timeZone", { - get() { - throw new Test262Error("timeZone.timeZone should not be accessed"); - }, -}); - -instance.withTimeZone(timeZone); -instance.withTimeZone({ timeZone }); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-string-datetime.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-string-datetime.js index 48e72411e778..6e1a291043bf 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-string-datetime.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-string-datetime.js @@ -11,34 +11,23 @@ const instance = new Temporal.ZonedDateTime(0n, "UTC"); let timeZone = "2021-08-19T17:30"; assert.throws(RangeError, () => instance.withTimeZone(timeZone), "bare date-time string is not a time zone"); -assert.throws(RangeError, () => instance.withTimeZone({ timeZone }), "bare date-time string is not a time zone"); timeZone = "2021-08-19T17:30Z"; const result1 = instance.withTimeZone(timeZone); -assert.sameValue(result1.timeZone.id, "UTC", "date-time + Z is UTC time zone"); -const result2 = instance.withTimeZone({ timeZone }); -assert.sameValue(result2.timeZone.id, "UTC", "date-time + Z is UTC time zone (string in property bag)"); +assert.sameValue(result1.timeZoneId, "UTC", "date-time + Z is UTC time zone"); timeZone = "2021-08-19T17:30-07:00"; -const result3 = instance.withTimeZone(timeZone); -assert.sameValue(result3.timeZone.id, "-07:00", "date-time + offset is the offset time zone"); -const result4 = instance.withTimeZone({ timeZone }); -assert.sameValue(result4.timeZone.id, "-07:00", "date-time + offset is the offset time zone (string in property bag)"); +const result2 = instance.withTimeZone(timeZone); +assert.sameValue(result2.timeZoneId, "-07:00", "date-time + offset is the offset time zone"); timeZone = "2021-08-19T17:30[UTC]"; -const result5 = instance.withTimeZone(timeZone); -assert.sameValue(result5.timeZone.id, "UTC", "date-time + IANA annotation is the IANA time zone"); -const result6 = instance.withTimeZone({ timeZone }); -assert.sameValue(result6.timeZone.id, "UTC", "date-time + IANA annotation is the IANA time zone (string in property bag)"); +const result3 = instance.withTimeZone(timeZone); +assert.sameValue(result3.timeZoneId, "UTC", "date-time + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30Z[UTC]"; -const result7 = instance.withTimeZone(timeZone); -assert.sameValue(result7.timeZone.id, "UTC", "date-time + Z + IANA annotation is the IANA time zone"); -const result8 = instance.withTimeZone({ timeZone }); -assert.sameValue(result8.timeZone.id, "UTC", "date-time + Z + IANA annotation is the IANA time zone (string in property bag)"); +const result4 = instance.withTimeZone(timeZone); +assert.sameValue(result4.timeZoneId, "UTC", "date-time + Z + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30-07:00[UTC]"; -const result9 = instance.withTimeZone(timeZone); -assert.sameValue(result9.timeZone.id, "UTC", "date-time + offset + IANA annotation is the IANA time zone"); -const result10 = instance.withTimeZone({ timeZone }); -assert.sameValue(result10.timeZone.id, "UTC", "date-time + offset + IANA annotation is the IANA time zone (string in property bag)"); +const result5 = instance.withTimeZone(timeZone); +assert.sameValue(result5.timeZoneId, "UTC", "date-time + offset + IANA annotation is the IANA time zone"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-string-leap-second.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-string-leap-second.js index 93fc6d9d0ea1..88f27c4153c9 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-string-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-string-leap-second.js @@ -10,11 +10,8 @@ features: [Temporal] const instance = new Temporal.ZonedDateTime(0n, "UTC"); let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; -const result1 = instance.withTimeZone(timeZone); -assert.sameValue(result1.timeZone.id, "UTC", "leap second is a valid ISO string for TimeZone"); -const result2 = instance.withTimeZone({ timeZone }); -assert.sameValue(result2.timeZone.id, "UTC", "leap second is a valid ISO string for TimeZone (nested property)"); +const result = instance.withTimeZone(timeZone); +assert.sameValue(result.timeZoneId, "UTC", "leap second is a valid ISO string for TimeZone"); timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; assert.throws(RangeError, () => instance.withTimeZone(timeZone), "leap second in time zone name not valid"); -assert.throws(RangeError, () => instance.withTimeZone({ timeZone }), "leap second in time zone name not valid (nested property)"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-string-multiple-offsets.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-string-multiple-offsets.js index e2246488f641..e36156c1aad9 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-string-multiple-offsets.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-string-multiple-offsets.js @@ -10,7 +10,5 @@ features: [Temporal] const instance = new Temporal.ZonedDateTime(0n, "UTC"); const timeZone = "2021-08-19T17:30:45.123456789+01:46[+01:45:30.987654321]"; -const result1 = instance.withTimeZone(timeZone); -assert.sameValue(result1.timeZone.id, "+01:45:30.987654321", "Time zone string determined from bracket name"); -const result2 = instance.withTimeZone({ timeZone }); -assert.sameValue(result2.timeZone.id, "+01:45:30.987654321", "Time zone string determined from bracket name"); +const result = instance.withTimeZone(timeZone); +assert.sameValue(result.timeZoneId, "+01:45:30.987654321", "Time zone string determined from bracket name"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-string-year-zero.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-string-year-zero.js index fc14d8ed3a37..727174f1b296 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-string-year-zero.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-string-year-zero.js @@ -18,9 +18,4 @@ invalidStrings.forEach((timeZone) => { () => instance.withTimeZone(timeZone), "reject minus zero as extended year" ); - assert.throws( - RangeError, - () => instance.withTimeZone({ timeZone }), - "reject minus zero as extended year (nested property)" - ); }); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-string.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-string.js index 386dfb333d24..d99aed576782 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-string.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-string.js @@ -4,12 +4,33 @@ /*--- esid: sec-temporal.zoneddatetime.prototype.withtimezone description: Time zone IDs are valid input for a time zone +includes: [temporalHelpers.js] features: [Temporal] ---*/ +const getPossibleInstantsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getPossibleInstantsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getPossibleInstantsFor should not be looked up"); + }, +}); +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + const instance = new Temporal.ZonedDateTime(0n, "UTC"); ["UTC", "+01:30"].forEach((timeZone) => { const result = instance.withTimeZone(timeZone); - assert.sameValue(result.timeZone.id, timeZone, `Time zone created from string "${timeZone}"`); + assert.sameValue(result.getISOFields().timeZone, timeZone, `time zone slot should store string "${timeZone}"`); }); + +Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", getPossibleInstantsForOriginal); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-wrong-type.js index 12c59e6ba8d0..96fee6b2cfea 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-wrong-type.js @@ -18,22 +18,18 @@ const rangeErrorTests = [ [1, "number that doesn't convert to a valid ISO string"], [19761118, "number that would convert to a valid ISO string in other contexts"], [1n, "bigint"], - [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of rangeErrorTests) { assert.throws(RangeError, () => instance.withTimeZone(timeZone), `${description} does not convert to a valid ISO string`); - assert.throws(RangeError, () => instance.withTimeZone({ timeZone }), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], + [{}, "object not implementing time zone protocol"], + [new Temporal.Calendar("iso8601"), "calendar instance"], ]; for (const [timeZone, description] of typeErrorTests) { assert.throws(TypeError, () => instance.withTimeZone(timeZone), `${description} is not a valid object and does not convert to a string`); - assert.throws(TypeError, () => instance.withTimeZone({ timeZone }), `${description} is not a valid object and does not convert to a string (nested property)`); } - -const timeZone = undefined; -assert.throws(RangeError, () => instance.withTimeZone({ timeZone }), `undefined is always a RangeError as nested property`); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/year/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/year/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..03be598d1569 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/year/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.year +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const yearOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "year"); +Object.defineProperty(Temporal.Calendar.prototype, "year", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("year should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.year; + +Object.defineProperty(Temporal.Calendar.prototype, "year", yearOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/year/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/year/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..79422e52aa1f --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/year/builtin-timezone-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.year +description: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.year; + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/yearOfWeek/builtin-calendar-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/yearOfWeek/builtin-calendar-no-observable-calls.js new file mode 100644 index 000000000000..81d9e60be872 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/yearOfWeek/builtin-calendar-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.yearofweek +description: > + Calling the method on an instance constructed with a builtin calendar causes + no observable lookups or calls to calendar methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const yearOfWeekOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "yearOfWeek"); +Object.defineProperty(Temporal.Calendar.prototype, "yearOfWeek", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("yearOfWeek should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.yearOfWeek; + +Object.defineProperty(Temporal.Calendar.prototype, "yearOfWeek", yearOfWeekOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/yearOfWeek/builtin-timezone-no-observable-calls.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/yearOfWeek/builtin-timezone-no-observable-calls.js new file mode 100644 index 000000000000..dd3f512d8329 --- /dev/null +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/prototype/yearOfWeek/builtin-timezone-no-observable-calls.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.yearofweek +description: > + Calling the method on an instance constructed with a builtin time zone causes + no observable lookups or calls to time zone methods. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor"); +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", { + configurable: true, + enumerable: false, + get() { + TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up"); + }, +}); + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601"); +instance.yearOfWeek; + +Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/timezone-case-insensitive.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/timezone-case-insensitive.js index 3c780f6a3c3a..a3e66dce0c8c 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/timezone-case-insensitive.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/timezone-case-insensitive.js @@ -9,4 +9,4 @@ features: [Temporal] const timeZone = 'uTc'; const result = new Temporal.ZonedDateTime(0n, timeZone); -assert.sameValue(result.timeZone.id, 'UTC', `Time zone created from string "${timeZone}"`); +assert.sameValue(result.timeZoneId, 'UTC', `Time zone created from string "${timeZone}"`); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/timezone-instance-does-not-get-timeZone-property.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/timezone-instance-does-not-get-timeZone-property.js deleted file mode 100644 index c91da6c755f9..000000000000 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/timezone-instance-does-not-get-timeZone-property.js +++ /dev/null @@ -1,20 +0,0 @@ -// 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 -description: > - A Temporal.TimeZone instance passed to new ZonedDateTime() does not have - its 'timeZone' property observably checked -features: [Temporal] ----*/ - -const timeZone = new Temporal.TimeZone("UTC"); -Object.defineProperty(timeZone, "timeZone", { - get() { - throw new Test262Error("timeZone.timeZone should not be accessed"); - }, -}); - -new Temporal.ZonedDateTime(0n, timeZone); -new Temporal.ZonedDateTime(0n, { timeZone }); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/timezone-string-datetime.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/timezone-string-datetime.js index 3eca69186e1b..abf963a8ef53 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/timezone-string-datetime.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/timezone-string-datetime.js @@ -9,34 +9,23 @@ features: [Temporal] let timeZone = "2021-08-19T17:30"; assert.throws(RangeError, () => new Temporal.ZonedDateTime(0n, timeZone), "bare date-time string is not a time zone"); -assert.throws(RangeError, () => new Temporal.ZonedDateTime(0n, { timeZone }), "bare date-time string is not a time zone"); timeZone = "2021-08-19T17:30Z"; const result1 = new Temporal.ZonedDateTime(0n, timeZone); -assert.sameValue(result1.timeZone.id, "UTC", "date-time + Z is UTC time zone"); -const result2 = new Temporal.ZonedDateTime(0n, { timeZone }); -assert.sameValue(result2.timeZone.id, "UTC", "date-time + Z is UTC time zone (string in property bag)"); +assert.sameValue(result1.timeZoneId, "UTC", "date-time + Z is UTC time zone"); timeZone = "2021-08-19T17:30-07:00"; -const result3 = new Temporal.ZonedDateTime(0n, timeZone); -assert.sameValue(result3.timeZone.id, "-07:00", "date-time + offset is the offset time zone"); -const result4 = new Temporal.ZonedDateTime(0n, { timeZone }); -assert.sameValue(result4.timeZone.id, "-07:00", "date-time + offset is the offset time zone (string in property bag)"); +const result2 = new Temporal.ZonedDateTime(0n, timeZone); +assert.sameValue(result2.timeZoneId, "-07:00", "date-time + offset is the offset time zone"); timeZone = "2021-08-19T17:30[UTC]"; -const result5 = new Temporal.ZonedDateTime(0n, timeZone); -assert.sameValue(result5.timeZone.id, "UTC", "date-time + IANA annotation is the IANA time zone"); -const result6 = new Temporal.ZonedDateTime(0n, { timeZone }); -assert.sameValue(result6.timeZone.id, "UTC", "date-time + IANA annotation is the IANA time zone (string in property bag)"); +const result3 = new Temporal.ZonedDateTime(0n, timeZone); +assert.sameValue(result3.timeZoneId, "UTC", "date-time + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30Z[UTC]"; -const result7 = new Temporal.ZonedDateTime(0n, timeZone); -assert.sameValue(result7.timeZone.id, "UTC", "date-time + Z + IANA annotation is the IANA time zone"); -const result8 = new Temporal.ZonedDateTime(0n, { timeZone }); -assert.sameValue(result8.timeZone.id, "UTC", "date-time + Z + IANA annotation is the IANA time zone (string in property bag)"); +const result4 = new Temporal.ZonedDateTime(0n, timeZone); +assert.sameValue(result4.timeZoneId, "UTC", "date-time + Z + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30-07:00[UTC]"; -const result9 = new Temporal.ZonedDateTime(0n, timeZone); -assert.sameValue(result9.timeZone.id, "UTC", "date-time + offset + IANA annotation is the IANA time zone"); -const result10 = new Temporal.ZonedDateTime(0n, { timeZone }); -assert.sameValue(result10.timeZone.id, "UTC", "date-time + offset + IANA annotation is the IANA time zone (string in property bag)"); +const result5 = new Temporal.ZonedDateTime(0n, timeZone); +assert.sameValue(result5.timeZoneId, "UTC", "date-time + offset + IANA annotation is the IANA time zone"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/timezone-string-leap-second.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/timezone-string-leap-second.js index 966502ef8fa3..b24c78060b2e 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/timezone-string-leap-second.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/timezone-string-leap-second.js @@ -9,11 +9,8 @@ features: [Temporal] let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; -const result1 = new Temporal.ZonedDateTime(0n, timeZone); -assert.sameValue(result1.timeZone.id, "UTC", "Time zone string determined from bracket name"); -const result2 = new Temporal.ZonedDateTime(0n, { timeZone }); -assert.sameValue(result2.timeZone.id, "UTC", "Time zone string determined from bracket name (nested property)"); +const result = new Temporal.ZonedDateTime(0n, timeZone); +assert.sameValue(result.timeZoneId, "UTC", "Time zone string determined from bracket name"); timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; assert.throws(RangeError, () => new Temporal.ZonedDateTime(0n, timeZone), "leap second in time zone name not valid"); -assert.throws(RangeError, () => new Temporal.ZonedDateTime(0n, { timeZone }), "leap second in time zone name not valid (nested property)"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/timezone-string-multiple-offsets.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/timezone-string-multiple-offsets.js index f1b9432c8f5c..a57aab67f2e8 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/timezone-string-multiple-offsets.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/timezone-string-multiple-offsets.js @@ -9,7 +9,5 @@ features: [Temporal] const timeZone = "2021-08-19T17:30:45.123456789+01:46[+01:45:30.987654321]"; -const result1 = new Temporal.ZonedDateTime(0n, timeZone); -assert.sameValue(result1.timeZone.id, "+01:45:30.987654321", "Time zone string determined from bracket name"); -const result2 = new Temporal.ZonedDateTime(0n, { timeZone }); -assert.sameValue(result2.timeZone.id, "+01:45:30.987654321", "Time zone string determined from bracket name"); +const result = new Temporal.ZonedDateTime(0n, timeZone); +assert.sameValue(result.timeZoneId, "+01:45:30.987654321", "Time zone string determined from bracket name"); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/timezone-string.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/timezone-string.js index 95d96b58d5d2..d83ef4c271d6 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/timezone-string.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/timezone-string.js @@ -9,5 +9,5 @@ features: [Temporal] ["UTC", "+01:30"].forEach((timeZone) => { const result = new Temporal.ZonedDateTime(0n, timeZone); - assert.sameValue(result.timeZone.id, timeZone, `Time zone created from string "${timeZone}"`); + assert.sameValue(result.getISOFields().timeZone, timeZone, `time zone slot should store string "${timeZone}"`); }); diff --git a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/timezone-wrong-type.js b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/timezone-wrong-type.js index 163050b3ce3e..c19d14e5e691 100644 --- a/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/timezone-wrong-type.js +++ b/JSTests/test262/test/built-ins/Temporal/ZonedDateTime/timezone-wrong-type.js @@ -20,7 +20,6 @@ const rangeErrorTests = [ for (const [timeZone, description] of rangeErrorTests) { assert.throws(RangeError, () => new Temporal.ZonedDateTime(0n, timeZone), `${description} does not convert to a valid ISO string`); - assert.throws(RangeError, () => new Temporal.ZonedDateTime(0n, { timeZone }), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ @@ -29,8 +28,4 @@ const typeErrorTests = [ for (const [timeZone, description] of typeErrorTests) { assert.throws(TypeError, () => new Temporal.ZonedDateTime(0n, timeZone), `${description} is not a valid object and does not convert to a string`); - assert.throws(TypeError, () => new Temporal.ZonedDateTime(0n, { timeZone }), `${description} is not a valid object and does not convert to a string (nested property)`); } - -const timeZone = undefined; -assert.throws(RangeError, () => new Temporal.ZonedDateTime(0n, { timeZone }), `undefined is always a RangeError as nested property`); diff --git a/JSTests/test262/test/built-ins/TypedArray/prototype/filter/BigInt/speciesctor-destination-resizable.js b/JSTests/test262/test/built-ins/TypedArray/prototype/filter/BigInt/speciesctor-destination-resizable.js new file mode 100644 index 000000000000..74da0daf464d --- /dev/null +++ b/JSTests/test262/test/built-ins/TypedArray/prototype/filter/BigInt/speciesctor-destination-resizable.js @@ -0,0 +1,40 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-%typedarray%.prototype.filter +description: > + Throws a TypeError if new typedArray's length < count +info: | + 23.2.3.10 %TypedArray%.prototype.filter ( start, end ) + + ... + 9. Let A be ? TypedArraySpeciesCreate(O, « count »). + ... + + 23.2.4.1 TypedArraySpeciesCreate ( exemplar, argumentList ) + + ... + 3. Let result be ? TypedArrayCreate(constructor, argumentList). + + 23.2.4.2 TypedArrayCreate ( constructor, argumentList ) + + ... + 3. If argumentList is a List of a single Number, then + a. If the value of newTypedArray's [[ArrayLength]] internal slot < + argumentList[0], throw a TypeError exception. + ... +includes: [testBigIntTypedArray.js] +features: [BigInt, Symbol.species, TypedArray, resizable-arraybuffer] +---*/ + +testWithBigIntTypedArrayConstructors(function(TA) { + const rab1 = new ArrayBuffer(8, {maxByteLength: 100}); + const ta = new TA(rab1); + const rab2 = new ArrayBuffer(10, {maxByteLength: 20}); + const lengthTracking = new TA(rab2); + rab2.resize(0); + ta.constructor = { [Symbol.species]: function() { return lengthTracking; } }; + assert.throws(TypeError, function() { + ta.filter(() => true); + }); +}); diff --git a/JSTests/test262/test/built-ins/TypedArray/prototype/filter/BigInt/speciesctor-get-species-custom-ctor-length-throws-resizable-arraybuffer.js b/JSTests/test262/test/built-ins/TypedArray/prototype/filter/BigInt/speciesctor-get-species-custom-ctor-length-throws-resizable-arraybuffer.js new file mode 100644 index 000000000000..d6ae1e206a66 --- /dev/null +++ b/JSTests/test262/test/built-ins/TypedArray/prototype/filter/BigInt/speciesctor-get-species-custom-ctor-length-throws-resizable-arraybuffer.js @@ -0,0 +1,42 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-%typedarray%.prototype.filter +description: > + Throws a TypeError if new typedArray's length < count +info: | + 23.2.3.10 %TypedArray%.prototype.filter ( start, end ) + + ... + 9. Let A be ? TypedArraySpeciesCreate(O, « count »). + ... + + 23.2.4.1 TypedArraySpeciesCreate ( exemplar, argumentList ) + + ... + 3. Let result be ? TypedArrayCreate(constructor, argumentList). + + 23.2.4.2 TypedArrayCreate ( constructor, argumentList ) + + ... + 3. If argumentList is a List of a single Number, then + a. If the value of newTypedArray's [[ArrayLength]] internal slot < + argumentList[0], throw a TypeError exception. + ... +includes: [testBigIntTypedArray.js] +features: [BigInt, Symbol.species, TypedArray, resizable-arraybuffer] +---*/ + +testWithBigIntTypedArrayConstructors(function(TA) { + var sample = new TA(2); + const rab = new ArrayBuffer(10, {maxByteLength: 20}); + const lengthTracking = new TA(rab); + sample.constructor = {}; + sample.constructor[Symbol.species] = function() { + return lengthTracking; + }; + rab.resize(0); + assert.throws(TypeError, function() { + sample.filter(() => { return true; }); + }); +}); diff --git a/JSTests/test262/test/built-ins/TypedArray/prototype/filter/speciesctor-destination-resizable.js b/JSTests/test262/test/built-ins/TypedArray/prototype/filter/speciesctor-destination-resizable.js new file mode 100644 index 000000000000..2358f656eee2 --- /dev/null +++ b/JSTests/test262/test/built-ins/TypedArray/prototype/filter/speciesctor-destination-resizable.js @@ -0,0 +1,40 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-%typedarray%.prototype.filter +description: > + Throws a TypeError if new typedArray's length < count +info: | + 23.2.3.10 %TypedArray%.prototype.filter ( start, end ) + + ... + 9. Let A be ? TypedArraySpeciesCreate(O, « count »). + ... + + 23.2.4.1 TypedArraySpeciesCreate ( exemplar, argumentList ) + + ... + 3. Let result be ? TypedArrayCreate(constructor, argumentList). + + 23.2.4.2 TypedArrayCreate ( constructor, argumentList ) + + ... + 3. If argumentList is a List of a single Number, then + a. If the value of newTypedArray's [[ArrayLength]] internal slot < + argumentList[0], throw a TypeError exception. + ... +includes: [testTypedArray.js] +features: [Symbol.species, TypedArray, resizable-arraybuffer] +---*/ + +testWithTypedArrayConstructors(function(TA) { + const rab1 = new ArrayBuffer(8, {maxByteLength: 100}); + const ta = new TA(rab1); + const rab2 = new ArrayBuffer(10, {maxByteLength: 20}); + const lengthTracking = new TA(rab2); + rab2.resize(0); + ta.constructor = { [Symbol.species]: function() { return lengthTracking; } }; + assert.throws(TypeError, function() { + ta.filter(() => true); + }); +}); diff --git a/JSTests/test262/test/built-ins/TypedArray/prototype/filter/speciesctor-get-species-custom-ctor-length-throws-resizable-arraybuffer.js b/JSTests/test262/test/built-ins/TypedArray/prototype/filter/speciesctor-get-species-custom-ctor-length-throws-resizable-arraybuffer.js new file mode 100644 index 000000000000..92cfa4aeb05f --- /dev/null +++ b/JSTests/test262/test/built-ins/TypedArray/prototype/filter/speciesctor-get-species-custom-ctor-length-throws-resizable-arraybuffer.js @@ -0,0 +1,42 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-%typedarray%.prototype.filter +description: > + Throws a TypeError if new typedArray's length < count +info: | + 23.2.3.10 %TypedArray%.prototype.filter ( start, end ) + + ... + 9. Let A be ? TypedArraySpeciesCreate(O, « count »). + ... + + 23.2.4.1 TypedArraySpeciesCreate ( exemplar, argumentList ) + + ... + 3. Let result be ? TypedArrayCreate(constructor, argumentList). + + 23.2.4.2 TypedArrayCreate ( constructor, argumentList ) + + ... + 3. If argumentList is a List of a single Number, then + a. If the value of newTypedArray's [[ArrayLength]] internal slot < + argumentList[0], throw a TypeError exception. + ... +includes: [testTypedArray.js] +features: [Symbol.species, TypedArray, resizable-arraybuffer] +---*/ + +testWithTypedArrayConstructors(function(TA) { + var sample = new TA(2); + const rab = new ArrayBuffer(10, {maxByteLength: 20}); + const lengthTracking = new TA(rab); + sample.constructor = {}; + sample.constructor[Symbol.species] = function() { + return lengthTracking; + }; + rab.resize(0); + assert.throws(TypeError, function() { + sample.filter(() => { return true; }); + }); +}); diff --git a/JSTests/test262/test/built-ins/TypedArray/prototype/map/BigInt/speciesctor-destination-resizable.js b/JSTests/test262/test/built-ins/TypedArray/prototype/map/BigInt/speciesctor-destination-resizable.js new file mode 100644 index 000000000000..372acf3d396b --- /dev/null +++ b/JSTests/test262/test/built-ins/TypedArray/prototype/map/BigInt/speciesctor-destination-resizable.js @@ -0,0 +1,40 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-%typedarray%.prototype.map +description: > + Throws a TypeError if new typedArray's length < count +info: | + 22.2.3.22 %TypedArray%.prototype.map ( start, end ) + + ... + 9. Let A be ? TypedArraySpeciesCreate(O, « count »). + ... + + 23.2.4.1 TypedArraySpeciesCreate ( exemplar, argumentList ) + + ... + 3. Let result be ? TypedArrayCreate(constructor, argumentList). + + 23.2.4.2 TypedArrayCreate ( constructor, argumentList ) + + ... + 3. If argumentList is a List of a single Number, then + a. If the value of newTypedArray's [[ArrayLength]] internal slot < + argumentList[0], throw a TypeError exception. + ... +includes: [testBigIntTypedArray.js] +features: [BigInt, Symbol.species, TypedArray, resizable-arraybuffer] +---*/ + +testWithBigIntTypedArrayConstructors(function(TA) { + const rab1 = new ArrayBuffer(8, {maxByteLength: 100}); + const ta = new TA(rab1); + const rab2 = new ArrayBuffer(10, {maxByteLength: 20}); + const lengthTracking = new TA(rab2); + rab2.resize(0); + ta.constructor = { [Symbol.species]: function() { return lengthTracking; } }; + assert.throws(TypeError, function() { + ta.map(() => {}); + }); +}); diff --git a/JSTests/test262/test/built-ins/TypedArray/prototype/map/BigInt/speciesctor-get-species-custom-ctor-length-throws-resizable-arraybuffer.js b/JSTests/test262/test/built-ins/TypedArray/prototype/map/BigInt/speciesctor-get-species-custom-ctor-length-throws-resizable-arraybuffer.js new file mode 100644 index 000000000000..a0bf75787394 --- /dev/null +++ b/JSTests/test262/test/built-ins/TypedArray/prototype/map/BigInt/speciesctor-get-species-custom-ctor-length-throws-resizable-arraybuffer.js @@ -0,0 +1,43 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-%typedarray%.prototype.map +description: > + Throws a TypeError if new typedArray's length < count +info: | + 22.2.3.22 %TypedArray%.prototype.map ( start, end ) + + ... + 9. Let A be ? TypedArraySpeciesCreate(O, « count »). + ... + + 23.2.4.1 TypedArraySpeciesCreate ( exemplar, argumentList ) + + ... + 3. Let result be ? TypedArrayCreate(constructor, argumentList). + + 23.2.4.2 TypedArrayCreate ( constructor, argumentList ) + + ... + 3. If argumentList is a List of a single Number, then + a. If the value of newTypedArray's [[ArrayLength]] internal slot < + argumentList[0], throw a TypeError exception. + ... +includes: [testBigIntTypedArray.js] +features: [BigInt, Symbol.species, TypedArray, resizable-arraybuffer] +---*/ + +testWithBigIntTypedArrayConstructors(function(TA) { + const sample = new TA(2); + const rab = new ArrayBuffer(10, {maxByteLength: 20}); + const lengthTracking = new TA(rab); + rab.resize(0); + sample.constructor = {}; + sample.constructor[Symbol.species] = function() { + return lengthTracking; + }; + assert.throws(TypeError, function() { + sample.map(() => {}); + }); +}); + diff --git a/JSTests/test262/test/built-ins/TypedArray/prototype/map/speciesctor-destination-resizable.js b/JSTests/test262/test/built-ins/TypedArray/prototype/map/speciesctor-destination-resizable.js new file mode 100644 index 000000000000..32d054b765b8 --- /dev/null +++ b/JSTests/test262/test/built-ins/TypedArray/prototype/map/speciesctor-destination-resizable.js @@ -0,0 +1,40 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-%typedarray%.prototype.map +description: > + Throws a TypeError if new typedArray's length < count +info: | + 22.2.3.22 %TypedArray%.prototype.map ( start, end ) + + ... + 9. Let A be ? TypedArraySpeciesCreate(O, « count »). + ... + + 23.2.4.1 TypedArraySpeciesCreate ( exemplar, argumentList ) + + ... + 3. Let result be ? TypedArrayCreate(constructor, argumentList). + + 23.2.4.2 TypedArrayCreate ( constructor, argumentList ) + + ... + 3. If argumentList is a List of a single Number, then + a. If the value of newTypedArray's [[ArrayLength]] internal slot < + argumentList[0], throw a TypeError exception. + ... +includes: [testTypedArray.js] +features: [Symbol.species, TypedArray, resizable-arraybuffer] +---*/ + +testWithTypedArrayConstructors(function(TA) { + const rab1 = new ArrayBuffer(8, {maxByteLength: 100}); + const ta = new TA(rab1); + const rab2 = new ArrayBuffer(10, {maxByteLength: 20}); + const lengthTracking = new TA(rab2); + rab2.resize(0); + ta.constructor = { [Symbol.species]: function() { return lengthTracking; } }; + assert.throws(TypeError, function() { + ta.map(() => {}); + }); +}); diff --git a/JSTests/test262/test/built-ins/TypedArray/prototype/map/speciesctor-get-species-custom-ctor-length-throws-resizable-arraybuffer.js b/JSTests/test262/test/built-ins/TypedArray/prototype/map/speciesctor-get-species-custom-ctor-length-throws-resizable-arraybuffer.js new file mode 100644 index 000000000000..6421975bf5a1 --- /dev/null +++ b/JSTests/test262/test/built-ins/TypedArray/prototype/map/speciesctor-get-species-custom-ctor-length-throws-resizable-arraybuffer.js @@ -0,0 +1,43 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-%typedarray%.prototype.map +description: > + Throws a TypeError if new typedArray's length < count +info: | + 22.2.3.22 %TypedArray%.prototype.map ( start, end ) + + ... + 9. Let A be ? TypedArraySpeciesCreate(O, « count »). + ... + + 23.2.4.1 TypedArraySpeciesCreate ( exemplar, argumentList ) + + ... + 3. Let result be ? TypedArrayCreate(constructor, argumentList). + + 23.2.4.2 TypedArrayCreate ( constructor, argumentList ) + + ... + 3. If argumentList is a List of a single Number, then + a. If the value of newTypedArray's [[ArrayLength]] internal slot < + argumentList[0], throw a TypeError exception. + ... +includes: [testTypedArray.js] +features: [Symbol.species, TypedArray, resizable-arraybuffer] +---*/ + +testWithTypedArrayConstructors(function(TA) { + const sample = new TA(2); + const rab = new ArrayBuffer(10, {maxByteLength: 20}); + const lengthTracking = new TA(rab); + rab.resize(0); + sample.constructor = {}; + sample.constructor[Symbol.species] = function() { + return lengthTracking; + }; + assert.throws(TypeError, function() { + sample.map(() => {}); + }); +}); + diff --git a/JSTests/test262/test/built-ins/TypedArray/prototype/slice/BigInt/speciesctor-destination-resizable.js b/JSTests/test262/test/built-ins/TypedArray/prototype/slice/BigInt/speciesctor-destination-resizable.js new file mode 100644 index 000000000000..cb0ff1776dde --- /dev/null +++ b/JSTests/test262/test/built-ins/TypedArray/prototype/slice/BigInt/speciesctor-destination-resizable.js @@ -0,0 +1,40 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-%typedarray%.prototype.slice +description: > + Throws a TypeError if new typedArray's length < count +info: | + 23.2.3.27 %TypedArray%.prototype.slice ( start, end ) + + ... + 9. Let A be ? TypedArraySpeciesCreate(O, « count »). + ... + + 23.2.4.1 TypedArraySpeciesCreate ( exemplar, argumentList ) + + ... + 3. Let result be ? TypedArrayCreate(constructor, argumentList). + + 23.2.4.2 TypedArrayCreate ( constructor, argumentList ) + + ... + 3. If argumentList is a List of a single Number, then + a. If the value of newTypedArray's [[ArrayLength]] internal slot < + argumentList[0], throw a TypeError exception. + ... +includes: [testBigIntTypedArray.js] +features: [BigInt, Symbol.species, TypedArray, resizable-arraybuffer] +---*/ + +testWithBigIntTypedArrayConstructors(function(TA) { + const rab1 = new ArrayBuffer(8, {maxByteLength: 100}); + const ta = new TA(rab1); + const rab2 = new ArrayBuffer(10, {maxByteLength: 20}); + const lengthTracking = new TA(rab2); + rab2.resize(0); + ta.constructor = { [Symbol.species]: function() { return lengthTracking; } }; + assert.throws(TypeError, function() { + ta.slice(); + }); +}); diff --git a/JSTests/test262/test/built-ins/TypedArray/prototype/slice/BigInt/speciesctor-get-species-custom-ctor-length-throws-resizable-arraybuffer.js b/JSTests/test262/test/built-ins/TypedArray/prototype/slice/BigInt/speciesctor-get-species-custom-ctor-length-throws-resizable-arraybuffer.js new file mode 100644 index 000000000000..cb7e63339c2b --- /dev/null +++ b/JSTests/test262/test/built-ins/TypedArray/prototype/slice/BigInt/speciesctor-get-species-custom-ctor-length-throws-resizable-arraybuffer.js @@ -0,0 +1,43 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-%typedarray%.prototype.slice +description: > + Throws a TypeError if new typedArray's length < count +info: | + 23.2.3.27 %TypedArray%.prototype.slice ( start, end ) + + ... + 9. Let A be ? TypedArraySpeciesCreate(O, « count »). + ... + + 23.2.4.1 TypedArraySpeciesCreate ( exemplar, argumentList ) + + ... + 3. Let result be ? TypedArrayCreate(constructor, argumentList). + + 23.2.4.2 TypedArrayCreate ( constructor, argumentList ) + + ... + 3. If argumentList is a List of a single Number, then + a. If the value of newTypedArray's [[ArrayLength]] internal slot < + argumentList[0], throw a TypeError exception. + ... +includes: [testBigIntTypedArray.js] +features: [BigInt, Symbol.species, TypedArray, resizable-arraybuffer] +---*/ + + +testWithBigIntTypedArrayConstructors(function(TA) { + const sample = new TA(2); + const rab = new ArrayBuffer(10, {maxByteLength: 20}); + const lengthTracking = new TA(rab); + rab.resize(0); + sample.constructor = {}; + sample.constructor[Symbol.species] = function() { + return lengthTracking; + }; + assert.throws(TypeError, function() { + sample.slice(); + }); +}); diff --git a/JSTests/test262/test/built-ins/TypedArray/prototype/slice/speciesctor-destination-resizable.js b/JSTests/test262/test/built-ins/TypedArray/prototype/slice/speciesctor-destination-resizable.js new file mode 100644 index 000000000000..9927d1718eab --- /dev/null +++ b/JSTests/test262/test/built-ins/TypedArray/prototype/slice/speciesctor-destination-resizable.js @@ -0,0 +1,40 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-%typedarray%.prototype.slice +description: > + Throws a TypeError if new typedArray's length < count +info: | + 23.2.3.27 %TypedArray%.prototype.slice ( start, end ) + + ... + 9. Let A be ? TypedArraySpeciesCreate(O, « count »). + ... + + 23.2.4.1 TypedArraySpeciesCreate ( exemplar, argumentList ) + + ... + 3. Let result be ? TypedArrayCreate(constructor, argumentList). + + 23.2.4.2 TypedArrayCreate ( constructor, argumentList ) + + ... + 3. If argumentList is a List of a single Number, then + a. If the value of newTypedArray's [[ArrayLength]] internal slot < + argumentList[0], throw a TypeError exception. + ... +includes: [testTypedArray.js] +features: [Symbol.species, TypedArray, resizable-arraybuffer] +---*/ + +testWithTypedArrayConstructors(function(TA) { + const rab1 = new ArrayBuffer(8, {maxByteLength: 100}); + const ta = new TA(rab1); + const rab2 = new ArrayBuffer(10, {maxByteLength: 20}); + const lengthTracking = new TA(rab2); + rab2.resize(0); + ta.constructor = { [Symbol.species]: function() { return lengthTracking; } }; + assert.throws(TypeError, function() { + ta.slice(); + }); +}); diff --git a/JSTests/test262/test/built-ins/TypedArray/prototype/slice/speciesctor-get-species-custom-ctor-length-throws-resizable-arraybuffer.js b/JSTests/test262/test/built-ins/TypedArray/prototype/slice/speciesctor-get-species-custom-ctor-length-throws-resizable-arraybuffer.js new file mode 100644 index 000000000000..925b59c22afb --- /dev/null +++ b/JSTests/test262/test/built-ins/TypedArray/prototype/slice/speciesctor-get-species-custom-ctor-length-throws-resizable-arraybuffer.js @@ -0,0 +1,43 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-%typedarray%.prototype.slice +description: > + Throws a TypeError if new typedArray's length < count +info: | + 23.2.3.27 %TypedArray%.prototype.slice ( start, end ) + + ... + 9. Let A be ? TypedArraySpeciesCreate(O, « count »). + ... + + 23.2.4.1 TypedArraySpeciesCreate ( exemplar, argumentList ) + + ... + 3. Let result be ? TypedArrayCreate(constructor, argumentList). + + 23.2.4.2 TypedArrayCreate ( constructor, argumentList ) + + ... + 3. If argumentList is a List of a single Number, then + a. If the value of newTypedArray's [[ArrayLength]] internal slot < + argumentList[0], throw a TypeError exception. + ... +includes: [testTypedArray.js] +features: [Symbol.species, TypedArray, resizable-arraybuffer] +---*/ + + +testWithTypedArrayConstructors(function(TA) { + const sample = new TA(2); + const rab = new ArrayBuffer(10, {maxByteLength: 20}); + const lengthTracking = new TA(rab); + rab.resize(0); + sample.constructor = {}; + sample.constructor[Symbol.species] = function() { + return lengthTracking; + }; + assert.throws(TypeError, function() { + sample.slice(); + }); +}); diff --git a/JSTests/test262/test/intl402/DateTimeFormat/casing-numbering-system-calendar-options.js b/JSTests/test262/test/intl402/DateTimeFormat/casing-numbering-system-calendar-options.js index 0753f79e0fb7..bab8f45461cb 100644 --- a/JSTests/test262/test/intl402/DateTimeFormat/casing-numbering-system-calendar-options.js +++ b/JSTests/test262/test/intl402/DateTimeFormat/casing-numbering-system-calendar-options.js @@ -7,6 +7,7 @@ description: > Tests that the options numberingSystem and calendar are mapped to lower case properly. author: Caio Lima +features: [Array.prototype.includes] ---*/ let defaultLocale = new Intl.DateTimeFormat().resolvedOptions().locale; diff --git a/JSTests/test262/test/intl402/DateTimeFormat/prototype/format/related-year-zh.js b/JSTests/test262/test/intl402/DateTimeFormat/prototype/format/related-year-zh.js index fd86e5092c36..c4b309b338c7 100644 --- a/JSTests/test262/test/intl402/DateTimeFormat/prototype/format/related-year-zh.js +++ b/JSTests/test262/test/intl402/DateTimeFormat/prototype/format/related-year-zh.js @@ -8,6 +8,7 @@ description: > Checks the output of 'relatedYear' and 'yearName' type, and the choice of pattern based on calendar. locale: [zh-u-ca-chinese] +features: [Array.prototype.includes] ---*/ const df = new Intl.DateTimeFormat("zh-u-ca-chinese", {year: "numeric"}); diff --git a/JSTests/test262/test/intl402/DateTimeFormat/prototype/format/temporal-objects-timezone-getoffsetnanosecondsfor-not-callable.js b/JSTests/test262/test/intl402/DateTimeFormat/prototype/format/temporal-objects-timezone-getoffsetnanosecondsfor-not-callable.js deleted file mode 100644 index 2777a2c9ff23..000000000000 --- a/JSTests/test262/test/intl402/DateTimeFormat/prototype/format/temporal-objects-timezone-getoffsetnanosecondsfor-not-callable.js +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-datetime-format-functions -description: TypeError thrown if timeZone.getOffsetNanosecondsFor is not callable -features: [Temporal] ----*/ - -const formatter = new Intl.DateTimeFormat(undefined, { calendar: "iso8601" }); -const date = new Temporal.PlainDate(2021, 8, 4); -const datetime = new Temporal.PlainDateTime(2021, 8, 4, 0, 30, 45, 123, 456, 789); -const monthDay = new Temporal.PlainMonthDay(8, 4); -const time = new Temporal.PlainTime(0, 30, 45, 123, 456, 789); -const month = new Temporal.PlainYearMonth(2021, 8); - -Temporal.TimeZone.prototype.getPossibleInstantsFor = function () { - return []; -}; - -[undefined, null, true, Math.PI, 'string', Symbol('sym'), 42n, {}].forEach(notCallable => { - Temporal.TimeZone.prototype.getOffsetNanosecondsFor = notCallable; - - assert.throws( - TypeError, - () => formatter.format(date), - "Uncallable getOffsetNanosecondsFor should throw TypeError (PlainDate case)" - ); - assert.throws( - TypeError, - () => formatter.format(datetime), - "Uncallable getOffsetNanosecondsFor should throw TypeError (PlainDateTime case)" - ); - assert.throws( - TypeError, - () => formatter.format(monthDay), - "Uncallable getOffsetNanosecondsFor should throw TypeError (PlainMonthDay case)" - ); - assert.throws( - TypeError, - () => formatter.format(time), - "Uncallable getOffsetNanosecondsFor should throw TypeError (PlainTime case)" - ); - assert.throws( - TypeError, - () => formatter.format(month), - "Uncallable getOffsetNanosecondsFor should throw TypeError (PlainYearMonth case)" - ); -}); diff --git a/JSTests/test262/test/intl402/DateTimeFormat/prototype/format/temporal-zoneddatetime-not-supported.js b/JSTests/test262/test/intl402/DateTimeFormat/prototype/format/temporal-zoneddatetime-not-supported.js new file mode 100644 index 000000000000..9493dcffc49b --- /dev/null +++ b/JSTests/test262/test/intl402/DateTimeFormat/prototype/format/temporal-zoneddatetime-not-supported.js @@ -0,0 +1,17 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-datetime-format-functions +description: Temporal.ZonedDateTime is not supported directly in format() +features: [Temporal] +---*/ + +const formatter = new Intl.DateTimeFormat(); + +// Check that TypeError would not be thrown for a different reason +const {timeZone, ...options} = formatter.resolvedOptions(); +const datetime = new Temporal.ZonedDateTime(0n, timeZone); +assert.sameValue(typeof datetime.toLocaleString(undefined, options), "string", "toLocaleString() with same options succeeds"); + +assert.throws(TypeError, () => formatter.format(datetime), "format() does not support Temporal.ZonedDateTime"); diff --git a/JSTests/test262/test/intl402/DateTimeFormat/prototype/format/timedatestyle-en.js b/JSTests/test262/test/intl402/DateTimeFormat/prototype/format/timedatestyle-en.js index 282e39e1b21b..5bdf1cd3d44f 100644 --- a/JSTests/test262/test/intl402/DateTimeFormat/prototype/format/timedatestyle-en.js +++ b/JSTests/test262/test/intl402/DateTimeFormat/prototype/format/timedatestyle-en.js @@ -4,7 +4,7 @@ /*--- esid: sec-date-time-style-pattern description: Checks basic handling of timeStyle and dateStyle. -features: [Intl.DateTimeFormat-datetimestyle] +features: [Intl.DateTimeFormat-datetimestyle, Array.prototype.includes] locale: [en-US] ---*/ diff --git a/JSTests/test262/test/intl402/DateTimeFormat/prototype/formatRange/temporal-objects-timezone-getoffsetnanosecondsfor-not-callable.js b/JSTests/test262/test/intl402/DateTimeFormat/prototype/formatRange/temporal-objects-timezone-getoffsetnanosecondsfor-not-callable.js deleted file mode 100644 index 560cf9b6f40f..000000000000 --- a/JSTests/test262/test/intl402/DateTimeFormat/prototype/formatRange/temporal-objects-timezone-getoffsetnanosecondsfor-not-callable.js +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-intl.datetimeformat.prototype.formatRange -description: TypeError thrown if timeZone.getOffsetNanosecondsFor is not callable -features: [Temporal] ----*/ - -const formatter = new Intl.DateTimeFormat(undefined, { calendar: "iso8601" }); -const date1 = new Temporal.PlainDate(2021, 8, 4); -const date2 = new Temporal.PlainDate(2021, 9, 4); -const datetime1 = new Temporal.PlainDateTime(2021, 8, 4, 0, 30, 45, 123, 456, 789); -const datetime2 = new Temporal.PlainDateTime(2021, 9, 4, 0, 30, 45, 123, 456, 789); -const monthDay1 = new Temporal.PlainMonthDay(8, 4); -const monthDay2 = new Temporal.PlainMonthDay(9, 4); -const time1 = new Temporal.PlainTime(0, 30, 45, 123, 456, 789); -const time2 = new Temporal.PlainTime(1, 30, 45, 123, 456, 789); -const month1 = new Temporal.PlainYearMonth(2021, 8); -const month2 = new Temporal.PlainYearMonth(2022, 8); - -Temporal.TimeZone.prototype.getPossibleInstantsFor = function () { - return []; -}; - -[undefined, null, true, Math.PI, 'string', Symbol('sym'), 42n, {}].forEach(notCallable => { - Temporal.TimeZone.prototype.getOffsetNanosecondsFor = notCallable; - - assert.throws( - TypeError, - () => formatter.formatRange(date1, date2), - "Uncallable getOffsetNanosecondsFor should throw TypeError (PlainDate case)" - ); - assert.throws( - TypeError, - () => formatter.formatRange(datetime1, datetime2), - "Uncallable getOffsetNanosecondsFor should throw TypeError (PlainDateTime case)" - ); - assert.throws( - TypeError, - () => formatter.formatRange(monthDay1, monthDay2), - "Uncallable getOffsetNanosecondsFor should throw TypeError (PlainMonthDay case)" - ); - assert.throws( - TypeError, - () => formatter.formatRange(time1, time2), - "Uncallable getOffsetNanosecondsFor should throw TypeError (PlainTime case)" - ); - assert.throws( - TypeError, - () => formatter.formatRange(month1, month2), - "Uncallable getOffsetNanosecondsFor should throw TypeError (PlainYearMonth case)" - ); -}); diff --git a/JSTests/test262/test/intl402/DateTimeFormat/prototype/formatRange/temporal-zoneddatetime-not-supported.js b/JSTests/test262/test/intl402/DateTimeFormat/prototype/formatRange/temporal-zoneddatetime-not-supported.js new file mode 100644 index 000000000000..69e14c25b598 --- /dev/null +++ b/JSTests/test262/test/intl402/DateTimeFormat/prototype/formatRange/temporal-zoneddatetime-not-supported.js @@ -0,0 +1,18 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.datetimeformat.prototype.formatRangeToParts +description: Temporal.ZonedDateTime is not supported directly in formatRangeToParts() +features: [Temporal] +---*/ + +const formatter = new Intl.DateTimeFormat(); + +// Check that TypeError would not be thrown for a different reason +const {timeZone, ...options} = formatter.resolvedOptions(); +const datetime1 = new Temporal.ZonedDateTime(0n, timeZone); +assert.sameValue(typeof datetime1.toLocaleString(undefined, options), "string", "toLocaleString() with same options succeeds"); + +const datetime2 = new Temporal.ZonedDateTime(1_000_000_000n, timeZone); +assert.throws(TypeError, () => formatter.formatRangeToParts(datetime1, datetime2), "formatRangeToParts() does not support Temporal.ZonedDateTime"); diff --git a/JSTests/test262/test/intl402/DateTimeFormat/prototype/formatRangeToParts/temporal-objects-timezone-getoffsetnanosecondsfor-not-callable.js b/JSTests/test262/test/intl402/DateTimeFormat/prototype/formatRangeToParts/temporal-objects-timezone-getoffsetnanosecondsfor-not-callable.js deleted file mode 100644 index 600ce00c8226..000000000000 --- a/JSTests/test262/test/intl402/DateTimeFormat/prototype/formatRangeToParts/temporal-objects-timezone-getoffsetnanosecondsfor-not-callable.js +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-Intl.DateTimeFormat.prototype.formatRangeToParts -description: TypeError thrown if timeZone.getOffsetNanosecondsFor is not callable -features: [Temporal] ----*/ - -const formatter = new Intl.DateTimeFormat(undefined, { calendar: "iso8601" }); -const date1 = new Temporal.PlainDate(2021, 8, 4); -const date2 = new Temporal.PlainDate(2021, 9, 4); -const datetime1 = new Temporal.PlainDateTime(2021, 8, 4, 0, 30, 45, 123, 456, 789); -const datetime2 = new Temporal.PlainDateTime(2021, 9, 4, 0, 30, 45, 123, 456, 789); -const monthDay1 = new Temporal.PlainMonthDay(8, 4); -const monthDay2 = new Temporal.PlainMonthDay(9, 4); -const time1 = new Temporal.PlainTime(0, 30, 45, 123, 456, 789); -const time2 = new Temporal.PlainTime(1, 30, 45, 123, 456, 789); -const month1 = new Temporal.PlainYearMonth(2021, 8); -const month2 = new Temporal.PlainYearMonth(2022, 8); - -Temporal.TimeZone.prototype.getPossibleInstantsFor = function () { - return []; -}; - -[undefined, null, true, Math.PI, 'string', Symbol('sym'), 42n, {}].forEach(notCallable => { - Temporal.TimeZone.prototype.getOffsetNanosecondsFor = notCallable; - - assert.throws( - TypeError, - () => formatter.formatRangeToParts(date1, date2), - "Uncallable getOffsetNanosecondsFor should throw TypeError (PlainDate case)" - ); - assert.throws( - TypeError, - () => formatter.formatRangeToParts(datetime1, datetime2), - "Uncallable getOffsetNanosecondsFor should throw TypeError (PlainDateTime case)" - ); - assert.throws( - TypeError, - () => formatter.formatRangeToParts(monthDay1, monthDay2), - "Uncallable getOffsetNanosecondsFor should throw TypeError (PlainMonthDay case)" - ); - assert.throws( - TypeError, - () => formatter.formatRangeToParts(time1, time2), - "Uncallable getOffsetNanosecondsFor should throw TypeError (PlainTime case)" - ); - assert.throws( - TypeError, - () => formatter.formatRangeToParts(month1, month2), - "Uncallable getOffsetNanosecondsFor should throw TypeError (PlainYearMonth case)" - ); -}); diff --git a/JSTests/test262/test/intl402/DateTimeFormat/prototype/formatRangeToParts/temporal-zoneddatetime-not-supported.js b/JSTests/test262/test/intl402/DateTimeFormat/prototype/formatRangeToParts/temporal-zoneddatetime-not-supported.js new file mode 100644 index 000000000000..6a9fbdc1cbb0 --- /dev/null +++ b/JSTests/test262/test/intl402/DateTimeFormat/prototype/formatRangeToParts/temporal-zoneddatetime-not-supported.js @@ -0,0 +1,18 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.datetimeformat.prototype.formatRange +description: Temporal.ZonedDateTime is not supported directly in formatRange() +features: [Temporal] +---*/ + +const formatter = new Intl.DateTimeFormat(); + +// Check that TypeError would not be thrown for a different reason +const {timeZone, ...options} = formatter.resolvedOptions(); +const datetime1 = new Temporal.ZonedDateTime(0n, timeZone); +assert.sameValue(typeof datetime1.toLocaleString(undefined, options), "string", "toLocaleString() with same options succeeds"); + +const datetime2 = new Temporal.ZonedDateTime(1_000_000_000n, timeZone); +assert.throws(TypeError, () => formatter.formatRange(datetime1, datetime2), "formatRange() does not support Temporal.ZonedDateTime"); diff --git a/JSTests/test262/test/intl402/DateTimeFormat/prototype/formatToParts/main.js b/JSTests/test262/test/intl402/DateTimeFormat/prototype/formatToParts/main.js index b89711dac66b..55330dc6e5aa 100644 --- a/JSTests/test262/test/intl402/DateTimeFormat/prototype/formatToParts/main.js +++ b/JSTests/test262/test/intl402/DateTimeFormat/prototype/formatToParts/main.js @@ -3,6 +3,7 @@ /*--- description: Tests for existance and behavior of Intl.DateTimeFormat.prototype.formatToParts +features: [Array.prototype.includes] ---*/ function reduce(parts) { diff --git a/JSTests/test262/test/intl402/DateTimeFormat/prototype/formatToParts/temporal-objects-timezone-getoffsetnanosecondsfor-not-callable.js b/JSTests/test262/test/intl402/DateTimeFormat/prototype/formatToParts/temporal-objects-timezone-getoffsetnanosecondsfor-not-callable.js deleted file mode 100644 index 82c5706a2741..000000000000 --- a/JSTests/test262/test/intl402/DateTimeFormat/prototype/formatToParts/temporal-objects-timezone-getoffsetnanosecondsfor-not-callable.js +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-Intl.DateTimeFormat.prototype.formatToParts -description: TypeError thrown if timeZone.getOffsetNanosecondsFor is not callable -features: [Temporal] ----*/ - -const formatter = new Intl.DateTimeFormat(undefined, { calendar: "iso8601" }); -const date = new Temporal.PlainDate(2021, 8, 4); -const datetime = new Temporal.PlainDateTime(2021, 8, 4, 0, 30, 45, 123, 456, 789); -const monthDay = new Temporal.PlainMonthDay(8, 4); -const time = new Temporal.PlainTime(0, 30, 45, 123, 456, 789); -const month = new Temporal.PlainYearMonth(2021, 8); - -Temporal.TimeZone.prototype.getPossibleInstantsFor = function () { - return []; -}; - -[undefined, null, true, Math.PI, 'string', Symbol('sym'), 42n, {}].forEach(notCallable => { - Temporal.TimeZone.prototype.getOffsetNanosecondsFor = notCallable; - - assert.throws( - TypeError, - () => formatter.formatToParts(date), - "Uncallable getOffsetNanosecondsFor should throw TypeError (PlainDate case)" - ); - assert.throws( - TypeError, - () => formatter.formatToParts(datetime), - "Uncallable getOffsetNanosecondsFor should throw TypeError (PlainDateTime case)" - ); - assert.throws( - TypeError, - () => formatter.formatToParts(monthDay), - "Uncallable getOffsetNanosecondsFor should throw TypeError (PlainMonthDay case)" - ); - assert.throws( - TypeError, - () => formatter.formatToParts(time), - "Uncallable getOffsetNanosecondsFor should throw TypeError (PlainTime case)" - ); - assert.throws( - TypeError, - () => formatter.formatToParts(month), - "Uncallable getOffsetNanosecondsFor should throw TypeError (PlainYearMonth case)" - ); -}); diff --git a/JSTests/test262/test/intl402/DateTimeFormat/prototype/formatToParts/temporal-zoneddatetime-not-supported.js b/JSTests/test262/test/intl402/DateTimeFormat/prototype/formatToParts/temporal-zoneddatetime-not-supported.js new file mode 100644 index 000000000000..5c65973f60ad --- /dev/null +++ b/JSTests/test262/test/intl402/DateTimeFormat/prototype/formatToParts/temporal-zoneddatetime-not-supported.js @@ -0,0 +1,17 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DateTimeFormat.prototype.formatToParts +description: Temporal.ZonedDateTime is not supported directly in formatToParts() +features: [Temporal] +---*/ + +const formatter = new Intl.DateTimeFormat(); + +// Check that TypeError would not be thrown for a different reason +const {timeZone, ...options} = formatter.resolvedOptions(); +const datetime = new Temporal.ZonedDateTime(0n, timeZone); +assert.sameValue(typeof datetime.toLocaleString(undefined, options), "string", "toLocaleString() with same options succeeds"); + +assert.throws(TypeError, () => formatter.formatToParts(datetime), "formatToParts() does not support Temporal.ZonedDateTime"); diff --git a/JSTests/test262/test/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle-timeStyle.js b/JSTests/test262/test/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle-timeStyle.js index 13795dae4588..9c7ebc1171e4 100644 --- a/JSTests/test262/test/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle-timeStyle.js +++ b/JSTests/test262/test/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle-timeStyle.js @@ -7,7 +7,7 @@ description: > Intl.DateTimeFormat.prototype.resolvedOptions properly reflect hourCycle settings when using timeStyle. includes: [propertyHelper.js] -features: [Intl.DateTimeFormat-datetimestyle] +features: [Intl.DateTimeFormat-datetimestyle, Array.prototype.includes] ---*/ const hcValues = ["h11", "h12", "h23", "h24"]; diff --git a/JSTests/test262/test/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle.js b/JSTests/test262/test/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle.js index 855edc6655b6..4b3b4dc6ca4d 100644 --- a/JSTests/test262/test/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle.js +++ b/JSTests/test262/test/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle.js @@ -10,6 +10,7 @@ info: | 12.4.5 Intl.DateTimeFormat.prototype.resolvedOptions() includes: [propertyHelper.js] +features: [Array.prototype.includes] ---*/ /* Values passed via unicode extension key work */ diff --git a/JSTests/test262/test/intl402/DurationFormat/prototype/format/style-default-en.js b/JSTests/test262/test/intl402/DurationFormat/prototype/format/style-default-en.js new file mode 100644 index 000000000000..c6dfcfe97ce8 --- /dev/null +++ b/JSTests/test262/test/intl402/DurationFormat/prototype/format/style-default-en.js @@ -0,0 +1,27 @@ +// Copyright 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DurationFormat.prototype.format +description: Test if format method formats duration correctly with different "style" arguments +locale: [en-US] +features: [Intl.DurationFormat] +---*/ + +const duration = { + years: 1, + months: 2, + weeks: 3, + days: 3, + hours: 4, + minutes: 5, + seconds: 6, + milliseconds: 7, + microseconds: 8, + nanoseconds: 9, +}; + + +const df = new Intl.DurationFormat("en"); +const expected = "1 yr, 2 mths, 3 wks, 3 days, 4 hr, 5 min, 6 sec, 7 ms, 8 μs, 9 ns"; +assert.sameValue(df.format(duration), expected, `Assert DurationFormat format output using default style option`); diff --git a/JSTests/test262/test/intl402/DurationFormat/prototype/format/style-digital-en.js b/JSTests/test262/test/intl402/DurationFormat/prototype/format/style-digital-en.js new file mode 100644 index 000000000000..2f2a3e912463 --- /dev/null +++ b/JSTests/test262/test/intl402/DurationFormat/prototype/format/style-digital-en.js @@ -0,0 +1,28 @@ +// Copyright 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DurationFormat.prototype.format +description: Test if format method formats duration correctly with different "style" arguments +locale: [en-US] +features: [Intl.DurationFormat] +---*/ + +const style = "digital"; +const expected = "1 yr 2 mths 3 wks 3 days 4:05:06"; + +const duration = { + years: 1, + months: 2, + weeks: 3, + days: 3, + hours: 4, + minutes: 5, + seconds: 6, + milliseconds: 7, + microseconds: 8, + nanoseconds: 9, +}; + +const df = new Intl.DurationFormat("en", {style}); +assert.sameValue(df.format(duration), expected, `Assert DurationFormat format output using ${style} style option`); diff --git a/JSTests/test262/test/intl402/DurationFormat/prototype/format/style-long-en.js b/JSTests/test262/test/intl402/DurationFormat/prototype/format/style-long-en.js new file mode 100644 index 000000000000..5af694893ac0 --- /dev/null +++ b/JSTests/test262/test/intl402/DurationFormat/prototype/format/style-long-en.js @@ -0,0 +1,28 @@ +// Copyright 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DurationFormat.prototype.format +description: Test if format method formats duration correctly with different "style" arguments +locale: [en-US] +features: [Intl.DurationFormat] +---*/ + +const style = "long"; +const expected = "1 year, 2 months, 3 weeks, 3 days, 4 hours, 5 minutes, 6 seconds, 7 milliseconds, 8 microseconds, 9 nanoseconds"; + +const duration = { + years: 1, + months: 2, + weeks: 3, + days: 3, + hours: 4, + minutes: 5, + seconds: 6, + milliseconds: 7, + microseconds: 8, + nanoseconds: 9, +}; + +const df = new Intl.DurationFormat("en", {style}); +assert.sameValue(df.format(duration), expected, `Assert DurationFormat format output using ${style} style option`); diff --git a/JSTests/test262/test/intl402/DurationFormat/prototype/format/style-narrow-en.js b/JSTests/test262/test/intl402/DurationFormat/prototype/format/style-narrow-en.js new file mode 100644 index 000000000000..819fe227be7d --- /dev/null +++ b/JSTests/test262/test/intl402/DurationFormat/prototype/format/style-narrow-en.js @@ -0,0 +1,28 @@ +// Copyright 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DurationFormat.prototype.format +description: Test if format method formats duration correctly with different "style" arguments +locale: [en-US] +features: [Intl.DurationFormat] +---*/ + +const style = "narrow"; +const expected = "1y 2m 3w 3d 4h 5m 6s 7ms 8μs 9ns"; + +const duration = { + years: 1, + months: 2, + weeks: 3, + days: 3, + hours: 4, + minutes: 5, + seconds: 6, + milliseconds: 7, + microseconds: 8, + nanoseconds: 9, +}; + +const df = new Intl.DurationFormat("en", {style}); +assert.sameValue(df.format(duration), expected, `Assert DurationFormat format output using ${style} style option`); diff --git a/JSTests/test262/test/intl402/DurationFormat/prototype/format/style-options-en.js b/JSTests/test262/test/intl402/DurationFormat/prototype/format/style-options-en.js deleted file mode 100644 index 61abc0e7b82e..000000000000 --- a/JSTests/test262/test/intl402/DurationFormat/prototype/format/style-options-en.js +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2022 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-Intl.DurationFormat.prototype.format -description: Test if format method formats duration correctly with different "style" arguments -locale: [en-US] -features: [Intl.DurationFormat] ----*/ - -const testData = { - "long" : "1 year, 2 months, 3 weeks, 3 days, 4 hours, 5 minutes, 6 seconds, 7 milliseconds, 8 microseconds, 9 nanoseconds", - "short": "1 yr, 2 mths, 3 wks, 3 days, 4 hr, 5 min, 6 sec, 7 ms, 8 μs, 9 ns", - "narrow":"1y 2m 3w 3d 4h 5m 6s 7ms 8μs 9ns", - "digital":"1 yr 2 mths 3 wks 3 days 4:05:06", -} - -const duration = { - years: 1, - months: 2, - weeks: 3, - days: 3, - hours: 4, - minutes: 5, - seconds: 6, - milliseconds: 7, - microseconds: 8, - nanoseconds: 9, -}; - - -for (const style in testData) { - const df = new Intl.DurationFormat("en", {style}); - const expected = testData[style]; - assert.sameValue(df.format(duration), expected, `Assert DurationFormat format output using ${style} style option`); -} - diff --git a/JSTests/test262/test/intl402/DurationFormat/prototype/format/style-short-en.js b/JSTests/test262/test/intl402/DurationFormat/prototype/format/style-short-en.js new file mode 100644 index 000000000000..44069f96ee36 --- /dev/null +++ b/JSTests/test262/test/intl402/DurationFormat/prototype/format/style-short-en.js @@ -0,0 +1,28 @@ +// Copyright 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DurationFormat.prototype.format +description: Test if format method formats duration correctly with different "style" arguments +locale: [en-US] +features: [Intl.DurationFormat] +---*/ + +const style = "short"; +const expected = "1 yr, 2 mths, 3 wks, 3 days, 4 hr, 5 min, 6 sec, 7 ms, 8 μs, 9 ns"; + +const duration = { + years: 1, + months: 2, + weeks: 3, + days: 3, + hours: 4, + minutes: 5, + seconds: 6, + milliseconds: 7, + microseconds: 8, + nanoseconds: 9, +}; + +const df = new Intl.DurationFormat("en", {style}); +assert.sameValue(df.format(duration), expected, `Assert DurationFormat format output using ${style} style option`); diff --git a/JSTests/test262/test/intl402/DurationFormat/prototype/formatToParts/formatToParts-style-default-en.js b/JSTests/test262/test/intl402/DurationFormat/prototype/formatToParts/formatToParts-style-default-en.js new file mode 100644 index 000000000000..b0717ae5a50b --- /dev/null +++ b/JSTests/test262/test/intl402/DurationFormat/prototype/formatToParts/formatToParts-style-default-en.js @@ -0,0 +1,67 @@ +// Copyright (C) 2023 Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DurationFormat.prototype.formatToParts +description: Checks basic handling of formatToParts, using long, short,narrow and digital styles. +features: [Intl.DurationFormat] +---*/ + +// Utils functions +function* zip(a, b) { + for (let i = 0; i < a.length; ++i) { + yield [i, a[i], b[i]]; + } +} + +function compare(actual, expected, message) { + assert.sameValue(Array.isArray(expected), true, `${message}: expected is Array`); + assert.sameValue(Array.isArray(actual), true, `${message}: actual is Array`); + assert.sameValue(actual.length, expected.length, `${message}: length`); + + for (const [i, actualEntry, expectedEntry] of zip(actual, expected)) { + // assertions + assert.sameValue(actualEntry.type, expectedEntry.type, `type for entry ${i}`); + assert.sameValue(actualEntry.value, expectedEntry.value, `value for entry ${i}`); + if (expectedEntry.unit) { + assert.sameValue(actualEntry.unit, expectedEntry.unit, `unit for entry ${i}`); + } + } +} +const duration = { + hours: 7, + minutes: 8, + seconds: 9, + milliseconds: 123, + microseconds: 456, + nanoseconds: 789, +}; + +const expected = [ + { type: "integer", value: "7", unit: "hour" }, + { type: "literal", value: " ", unit: "hour" }, + { type: "unit", value: "hr", unit: "hour" }, + { type: "literal", value: ", " }, + { type: "integer", value: "8", unit: "minute" }, + { type: "literal", value: " ", unit: "minute" }, + { type: "unit", value: "min", unit: "minute" }, + { type: "literal", value: ", " }, + { type: "integer", value: "9", unit: "second" }, + { type: "literal", value: " ", unit: "second" }, + { type: "unit", value: "sec", unit: "second" }, + { type: "literal", value: ", " }, + { type: "integer", value: "123", unit: "millisecond" }, + { type: "literal", value: " ", unit: "millisecond" }, + { type: "unit", value: "msec", unit: "millisecond" }, + { type: "literal", value: ", " }, + { type: "integer", value: "456", unit: "microsecond" }, + { type: "literal", value: " ", unit: "microsecond" }, + { type: "unit", value: "μsec", unit: "microsecond" }, + { type: "literal", value: " and " }, + { type: "integer", value: "789", unit: "nanosecond" }, + { type: "literal", value: " ", unit: "nanosecond" }, + { type: "unit", value: "nsec", unit: "nanosecond" }, + ]; + +let df = new Intl.DurationFormat('en'); +compare(df.formatToParts(duration), expected, `Using style : default`); diff --git a/JSTests/test262/test/intl402/DurationFormat/prototype/formatToParts/formatToParts-style-digital-en.js b/JSTests/test262/test/intl402/DurationFormat/prototype/formatToParts/formatToParts-style-digital-en.js new file mode 100644 index 000000000000..f4426d48f0f4 --- /dev/null +++ b/JSTests/test262/test/intl402/DurationFormat/prototype/formatToParts/formatToParts-style-digital-en.js @@ -0,0 +1,50 @@ +// Copyright (C) 2023 Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DurationFormat.prototype.formatToParts +description: Checks basic handling of formatToParts, using long, short,narrow and digital styles. +features: [Intl.DurationFormat] +---*/ + +// Utils functions +function* zip(a, b) { + for (let i = 0; i < a.length; ++i) { + yield [i, a[i], b[i]]; + } +} + +function compare(actual, expected, message) { + assert.sameValue(Array.isArray(expected), true, `${message}: expected is Array`); + assert.sameValue(Array.isArray(actual), true, `${message}: actual is Array`); + assert.sameValue(actual.length, expected.length, `${message}: length`); + + for (const [i, actualEntry, expectedEntry] of zip(actual, expected)) { + // assertions + assert.sameValue(actualEntry.type, expectedEntry.type, `type for entry ${i}`); + assert.sameValue(actualEntry.value, expectedEntry.value, `value for entry ${i}`); + if (expectedEntry.unit) { + assert.sameValue(actualEntry.unit, expectedEntry.unit, `unit for entry ${i}`); + } + } +} +const duration = { + hours: 7, + minutes: 8, + seconds: 9, + milliseconds: 123, + microseconds: 456, + nanoseconds: 789, +}; + +const style = "digital"; +const expected = [ + { type: "integer", value: "7", unit: "hour" }, + { type: "literal", value: ":"}, + { type: "integer", value: "08", unit: "minute" }, + { type: "literal", value: ":"}, + { type: "integer", value: "09", unit: "second" }, + ]; + +let df = new Intl.DurationFormat('en', { style }); +compare(df.formatToParts(duration), expected, `Using style : ${style}`); diff --git a/JSTests/test262/test/intl402/DurationFormat/prototype/formatToParts/formatToParts-style-long-en.js b/JSTests/test262/test/intl402/DurationFormat/prototype/formatToParts/formatToParts-style-long-en.js new file mode 100644 index 000000000000..1424544e6509 --- /dev/null +++ b/JSTests/test262/test/intl402/DurationFormat/prototype/formatToParts/formatToParts-style-long-en.js @@ -0,0 +1,68 @@ +// Copyright (C) 2023 Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DurationFormat.prototype.formatToParts +description: Checks basic handling of formatToParts, using long, short,narrow and digital styles. +features: [Intl.DurationFormat] +---*/ + +// Utils functions +function* zip(a, b) { + for (let i = 0; i < a.length; ++i) { + yield [i, a[i], b[i]]; + } +} + +function compare(actual, expected, message) { + assert.sameValue(Array.isArray(expected), true, `${message}: expected is Array`); + assert.sameValue(Array.isArray(actual), true, `${message}: actual is Array`); + assert.sameValue(actual.length, expected.length, `${message}: length`); + + for (const [i, actualEntry, expectedEntry] of zip(actual, expected)) { + // assertions + assert.sameValue(actualEntry.type, expectedEntry.type, `type for entry ${i}`); + assert.sameValue(actualEntry.value, expectedEntry.value, `value for entry ${i}`); + if (expectedEntry.unit) { + assert.sameValue(actualEntry.unit, expectedEntry.unit, `unit for entry ${i}`); + } + } +} +const duration = { + hours: 7, + minutes: 8, + seconds: 9, + milliseconds: 123, + microseconds: 456, + nanoseconds: 789, +}; + +const style = "long"; +const expected = [ + { type: "integer", value: "7", unit: "hour" }, + { type: "literal", value: " ", unit: "hour" }, + { type: "unit", value: "hours", unit: "hour" }, + { type: "literal", value: ", " }, + { type: "integer", value: "8", unit: "minute" }, + { type: "literal", value: " ", unit: "minute" }, + { type: "unit", value: "minutes", unit: "minute" }, + { type: "literal", value: ", " }, + { type: "integer", value: "9", unit: "second" }, + { type: "literal", value: " ", unit: "second" }, + { type: "unit", value: "seconds", unit: "second" }, + { type: "literal", value: ", " }, + { type: "integer", value: "123", unit: "millisecond" }, + { type: "literal", value: " ", unit: "millisecond" }, + { type: "unit", value: "milliseconds", unit: "millisecond" }, + { type: "literal", value: ", " }, + { type: "integer", value: "456", unit: "microsecond" }, + { type: "literal", value: " ", unit: "microsecond" }, + { type: "unit", value: "microseconds", unit: "microsecond" }, + { type: "literal", value: " and " }, + { type: "integer", value: "789", unit: "nanosecond" }, + { type: "literal", value: " ", unit: "nanosecond" }, + { type: "unit", value: "nanoseconds", unit: "nanosecond" }, + ]; + +let df = new Intl.DurationFormat('en', { style }); +compare(df.formatToParts(duration), expected, `Using style : ${style}`); diff --git a/JSTests/test262/test/intl402/DurationFormat/prototype/formatToParts/formatToParts-style-narrow-en.js b/JSTests/test262/test/intl402/DurationFormat/prototype/formatToParts/formatToParts-style-narrow-en.js new file mode 100644 index 000000000000..07bd519d1a26 --- /dev/null +++ b/JSTests/test262/test/intl402/DurationFormat/prototype/formatToParts/formatToParts-style-narrow-en.js @@ -0,0 +1,62 @@ +// Copyright (C) 2023 Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DurationFormat.prototype.formatToParts +description: Checks basic handling of formatToParts, using long, short,narrow and digital styles. +features: [Intl.DurationFormat] +---*/ + +// Utils functions +function* zip(a, b) { + for (let i = 0; i < a.length; ++i) { + yield [i, a[i], b[i]]; + } +} + +function compare(actual, expected, message) { + assert.sameValue(Array.isArray(expected), true, `${message}: expected is Array`); + assert.sameValue(Array.isArray(actual), true, `${message}: actual is Array`); + assert.sameValue(actual.length, expected.length, `${message}: length`); + + for (const [i, actualEntry, expectedEntry] of zip(actual, expected)) { + // assertions + assert.sameValue(actualEntry.type, expectedEntry.type, `type for entry ${i}`); + assert.sameValue(actualEntry.value, expectedEntry.value, `value for entry ${i}`); + if (expectedEntry.unit) { + assert.sameValue(actualEntry.unit, expectedEntry.unit, `unit for entry ${i}`); + } + } +} +const duration = { + hours: 7, + minutes: 8, + seconds: 9, + milliseconds: 123, + microseconds: 456, + nanoseconds: 789, +}; + +const style = "narrow"; +const expected = [ + { type: "integer", value: "7", unit: "hour" }, + { type: "unit", value: "h", unit: "hour" }, + { type: "literal", value: " " }, + { type: "integer", value: "8", unit: "minute" }, + { type: "unit", value: "m", unit: "minute" }, + { type: "literal", value: " " }, + { type: "integer", value: "9", unit: "second" }, + { type: "unit", value: "s", unit: "second" }, + { type: "literal", value: " " }, + { type: "integer", value: "123", unit: "millisecond" }, + { type: "unit", value: "ms", unit: "millisecond" }, + { type: "literal", value: " " }, + { type: "integer", value: "456", unit: "microsecond" }, + { type: "unit", value: "μs", unit: "microsecond" }, + { type: "literal", value: " " }, + { type: "integer", value: "789", unit: "nanosecond" }, + { type: "unit", value: "ns", unit: "nanosecond" }, + ]; + +let df = new Intl.DurationFormat('en', { style }); +compare(df.formatToParts(duration), expected, `Using style : ${style}`); diff --git a/JSTests/test262/test/intl402/DurationFormat/prototype/formatToParts/formatToParts-style-short-en.js b/JSTests/test262/test/intl402/DurationFormat/prototype/formatToParts/formatToParts-style-short-en.js new file mode 100644 index 000000000000..c3681ad47c0a --- /dev/null +++ b/JSTests/test262/test/intl402/DurationFormat/prototype/formatToParts/formatToParts-style-short-en.js @@ -0,0 +1,68 @@ +// Copyright (C) 2023 Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DurationFormat.prototype.formatToParts +description: Checks basic handling of formatToParts, using long, short,narrow and digital styles. +features: [Intl.DurationFormat] +---*/ + +// Utils functions +function* zip(a, b) { + for (let i = 0; i < a.length; ++i) { + yield [i, a[i], b[i]]; + } +} + +function compare(actual, expected, message) { + assert.sameValue(Array.isArray(expected), true, `${message}: expected is Array`); + assert.sameValue(Array.isArray(actual), true, `${message}: actual is Array`); + assert.sameValue(actual.length, expected.length, `${message}: length`); + + for (const [i, actualEntry, expectedEntry] of zip(actual, expected)) { + // assertions + assert.sameValue(actualEntry.type, expectedEntry.type, `type for entry ${i}`); + assert.sameValue(actualEntry.value, expectedEntry.value, `value for entry ${i}`); + if (expectedEntry.unit) { + assert.sameValue(actualEntry.unit, expectedEntry.unit, `unit for entry ${i}`); + } + } +} +const duration = { + hours: 7, + minutes: 8, + seconds: 9, + milliseconds: 123, + microseconds: 456, + nanoseconds: 789, +}; + +const style = "short"; +const expected = [ + { type: "integer", value: "7", unit: "hour" }, + { type: "literal", value: " ", unit: "hour" }, + { type: "unit", value: "hr", unit: "hour" }, + { type: "literal", value: ", " }, + { type: "integer", value: "8", unit: "minute" }, + { type: "literal", value: " ", unit: "minute" }, + { type: "unit", value: "min", unit: "minute" }, + { type: "literal", value: ", " }, + { type: "integer", value: "9", unit: "second" }, + { type: "literal", value: " ", unit: "second" }, + { type: "unit", value: "sec", unit: "second" }, + { type: "literal", value: ", " }, + { type: "integer", value: "123", unit: "millisecond" }, + { type: "literal", value: " ", unit: "millisecond" }, + { type: "unit", value: "msec", unit: "millisecond" }, + { type: "literal", value: ", " }, + { type: "integer", value: "456", unit: "microsecond" }, + { type: "literal", value: " ", unit: "microsecond" }, + { type: "unit", value: "μsec", unit: "microsecond" }, + { type: "literal", value: " and " }, + { type: "integer", value: "789", unit: "nanosecond" }, + { type: "literal", value: " ", unit: "nanosecond" }, + { type: "unit", value: "nsec", unit: "nanosecond" }, + ]; + +let df = new Intl.DurationFormat('en', { style }); +compare(df.formatToParts(duration), expected, `Using style : ${style}`); diff --git a/JSTests/test262/test/intl402/DurationFormat/prototype/formatToParts/formatToParts-styles-en.js b/JSTests/test262/test/intl402/DurationFormat/prototype/formatToParts/formatToParts-styles-en.js deleted file mode 100644 index b817c3039292..000000000000 --- a/JSTests/test262/test/intl402/DurationFormat/prototype/formatToParts/formatToParts-styles-en.js +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright (C) 2023 Igalia S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-Intl.DurationFormat.prototype.formatToParts -description: Checks basic handling of formatToParts, using long, short,narrow and digital styles. -features: [Intl.DurationFormat] ----*/ - -// Utils functions -function* zip(a, b) { - for (let i = 0; i < a.length; ++i) { - yield [i, a[i], b[i]]; - } -} - -function compare(actual, expected, message) { - assert.sameValue(Array.isArray(expected), true, `${message}: expected is Array`); - assert.sameValue(Array.isArray(actual), true, `${message}: actual is Array`); - assert.sameValue(actual.length, expected.length, `${message}: length`); - - for (const [i, actualEntry, expectedEntry] of zip(actual, expected)) { - // assertions - assert.sameValue(actualEntry.type, expectedEntry.type, `type for entry ${i}`); - assert.sameValue(actualEntry.value, expectedEntry.value, `value for entry ${i}`); - if (expectedEntry.unit) { - assert.sameValue(actualEntry.unit, expectedEntry.unit, `unit for entry ${i}`); - } - } -} -const duration = { - hours: 7, - minutes: 8, - seconds: 9, - milliseconds: 123, - microseconds: 456, - nanoseconds: 789, -}; - -const testsData = { - short: [ - { type: "integer", value: "7", unit: "hour" }, - { type: "literal", value: " ", unit: "hour" }, - { type: "unit", value: "hr", unit: "hour" }, - { type: "literal", value: ", " }, - { type: "integer", value: "8", unit: "minute" }, - { type: "literal", value: " ", unit: "minute" }, - { type: "unit", value: "min", unit: "minute" }, - { type: "literal", value: ", " }, - { type: "integer", value: "9", unit: "second" }, - { type: "literal", value: " ", unit: "second" }, - { type: "unit", value: "sec", unit: "second" }, - { type: "literal", value: ", " }, - { type: "integer", value: "123", unit: "millisecond" }, - { type: "literal", value: " ", unit: "millisecond" }, - { type: "unit", value: "msec", unit: "millisecond" }, - { type: "literal", value: ", " }, - { type: "integer", value: "456", unit: "microsecond" }, - { type: "literal", value: " ", unit: "microsecond" }, - { type: "unit", value: "μsec", unit: "microsecond" }, - { type: "literal", value: " and " }, - { type: "integer", value: "789", unit: "nanosecond" }, - { type: "literal", value: " ", unit: "nanosecond" }, - { type: "unit", value: "nsec", unit: "nanosecond" }, - ], - long: [ - { type: "integer", value: "7", unit: "hour" }, - { type: "literal", value: " ", unit: "hour" }, - { type: "unit", value: "hours", unit: "hour" }, - { type: "literal", value: ", " }, - { type: "integer", value: "8", unit: "minute" }, - { type: "literal", value: " ", unit: "minute" }, - { type: "unit", value: "minutes", unit: "minute" }, - { type: "literal", value: ", " }, - { type: "integer", value: "9", unit: "second" }, - { type: "literal", value: " ", unit: "second" }, - { type: "unit", value: "seconds", unit: "second" }, - { type: "literal", value: ", " }, - { type: "integer", value: "123", unit: "millisecond" }, - { type: "literal", value: " ", unit: "millisecond" }, - { type: "unit", value: "milliseconds", unit: "millisecond" }, - { type: "literal", value: ", " }, - { type: "integer", value: "456", unit: "microsecond" }, - { type: "literal", value: " ", unit: "microsecond" }, - { type: "unit", value: "microseconds", unit: "microsecond" }, - { type: "literal", value: " and " }, - { type: "integer", value: "789", unit: "nanosecond" }, - { type: "literal", value: " ", unit: "nanosecond" }, - { type: "unit", value: "nanoseconds", unit: "nanosecond" }, - ], - narrow: [ - { type: "integer", value: "7", unit: "hour" }, - { type: "unit", value: "h", unit: "hour" }, - { type: "literal", value: " " }, - { type: "integer", value: "8", unit: "minute" }, - { type: "unit", value: "m", unit: "minute" }, - { type: "literal", value: " " }, - { type: "integer", value: "9", unit: "second" }, - { type: "unit", value: "s", unit: "second" }, - { type: "literal", value: " " }, - { type: "integer", value: "123", unit: "millisecond" }, - { type: "unit", value: "ms", unit: "millisecond" }, - { type: "literal", value: " " }, - { type: "integer", value: "456", unit: "microsecond" }, - { type: "unit", value: "μs", unit: "microsecond" }, - { type: "literal", value: " " }, - { type: "integer", value: "789", unit: "nanosecond" }, - { type: "unit", value: "ns", unit: "nanosecond" }, - ], - digital: [ - { type: "integer", value: "7", unit: "hour" }, - { type: "literal", value: ":", unit: "hour" }, - { type: "integer", value: "08", unit: "minute" }, - { type: "literal", value: ":", unit: "minute" }, - { type: "integer", value: "09", unit: "second" }, - ], -}; - -for (const style in testsData) { - let df = new Intl.DurationFormat('en', { style }); - compare(df.formatToParts(duration), testsData[style], `Using style : ${style}`); -} diff --git a/JSTests/test262/test/intl402/Intl/supportedValuesOf/calendars-accepted-by-DateTimeFormat.js b/JSTests/test262/test/intl402/Intl/supportedValuesOf/calendars-accepted-by-DateTimeFormat.js index 901c6d4e64bb..602168dbc3e4 100644 --- a/JSTests/test262/test/intl402/Intl/supportedValuesOf/calendars-accepted-by-DateTimeFormat.js +++ b/JSTests/test262/test/intl402/Intl/supportedValuesOf/calendars-accepted-by-DateTimeFormat.js @@ -22,7 +22,7 @@ info: | Intl.DateTimeFormat objects. The list must include "gregory". includes: [testIntl.js] locale: [en] -features: [Intl-enumeration] +features: [Intl-enumeration, Array.prototype.includes] ---*/ const calendars = Intl.supportedValuesOf("calendar"); diff --git a/JSTests/test262/test/intl402/Intl/supportedValuesOf/calendars-accepted-by-DisplayNames.js b/JSTests/test262/test/intl402/Intl/supportedValuesOf/calendars-accepted-by-DisplayNames.js index 29e5ec5b242c..06c17d37e250 100644 --- a/JSTests/test262/test/intl402/Intl/supportedValuesOf/calendars-accepted-by-DisplayNames.js +++ b/JSTests/test262/test/intl402/Intl/supportedValuesOf/calendars-accepted-by-DisplayNames.js @@ -22,7 +22,7 @@ info: | Intl.DateTimeFormat objects. The list must include "gregory". includes: [testIntl.js] locale: [en] -features: [Intl-enumeration, Intl.DisplayNames-v2] +features: [Intl-enumeration, Intl.DisplayNames-v2, Array.prototype.includes] ---*/ const calendars = Intl.supportedValuesOf("calendar"); diff --git a/JSTests/test262/test/intl402/Intl/supportedValuesOf/calendars.js b/JSTests/test262/test/intl402/Intl/supportedValuesOf/calendars.js index dadfc7213c6c..8baef6d0faeb 100644 --- a/JSTests/test262/test/intl402/Intl/supportedValuesOf/calendars.js +++ b/JSTests/test262/test/intl402/Intl/supportedValuesOf/calendars.js @@ -21,7 +21,7 @@ info: | calendars for which the implementation provides the functionality of Intl.DateTimeFormat objects. The list must include "gregory". includes: [compareArray.js] -features: [Intl-enumeration, Intl.Locale] +features: [Intl-enumeration, Intl.Locale, Array.prototype.includes] ---*/ const calendars = Intl.supportedValuesOf("calendar"); diff --git a/JSTests/test262/test/intl402/Intl/supportedValuesOf/collations-accepted-by-Collator.js b/JSTests/test262/test/intl402/Intl/supportedValuesOf/collations-accepted-by-Collator.js index d4c814906b61..af8c7a934467 100644 --- a/JSTests/test262/test/intl402/Intl/supportedValuesOf/collations-accepted-by-Collator.js +++ b/JSTests/test262/test/intl402/Intl/supportedValuesOf/collations-accepted-by-Collator.js @@ -23,7 +23,7 @@ info: | Intl.Collator objects. includes: [testIntl.js] locale: [en, ar, de, es, ko, ln, si, sv, zh] -features: [Intl-enumeration] +features: [Intl-enumeration, Array.prototype.includes] ---*/ const collations = Intl.supportedValuesOf("collation"); diff --git a/JSTests/test262/test/intl402/Intl/supportedValuesOf/collations.js b/JSTests/test262/test/intl402/Intl/supportedValuesOf/collations.js index d8ccffba6911..dc923b86a89a 100644 --- a/JSTests/test262/test/intl402/Intl/supportedValuesOf/collations.js +++ b/JSTests/test262/test/intl402/Intl/supportedValuesOf/collations.js @@ -22,7 +22,7 @@ info: | collations for which the implementation provides the functionality of Intl.Collator objects. includes: [compareArray.js] -features: [Intl-enumeration, Intl.Locale] +features: [Intl-enumeration, Intl.Locale, Array.prototype.includes] ---*/ const collations = Intl.supportedValuesOf("collation"); diff --git a/JSTests/test262/test/intl402/Intl/supportedValuesOf/currencies-accepted-by-DisplayNames.js b/JSTests/test262/test/intl402/Intl/supportedValuesOf/currencies-accepted-by-DisplayNames.js index 41545f5a999c..b9930605d68f 100644 --- a/JSTests/test262/test/intl402/Intl/supportedValuesOf/currencies-accepted-by-DisplayNames.js +++ b/JSTests/test262/test/intl402/Intl/supportedValuesOf/currencies-accepted-by-DisplayNames.js @@ -23,7 +23,7 @@ info: | for which the implementation provides the functionality of Intl.DisplayNames and Intl.NumberFormat objects. locale: [en] -features: [Intl-enumeration, Intl.DisplayNames] +features: [Intl-enumeration, Intl.DisplayNames, Array.prototype.includes] ---*/ const currencies = Intl.supportedValuesOf("currency"); diff --git a/JSTests/test262/test/intl402/Intl/supportedValuesOf/numberingSystems-accepted-by-DateTimeFormat.js b/JSTests/test262/test/intl402/Intl/supportedValuesOf/numberingSystems-accepted-by-DateTimeFormat.js index 32cdcb5da89a..d4f70cb4ca26 100644 --- a/JSTests/test262/test/intl402/Intl/supportedValuesOf/numberingSystems-accepted-by-DateTimeFormat.js +++ b/JSTests/test262/test/intl402/Intl/supportedValuesOf/numberingSystems-accepted-by-DateTimeFormat.js @@ -25,7 +25,7 @@ info: | value of every row of Table 4, except the header row. includes: [testIntl.js] locale: [en] -features: [Intl-enumeration] +features: [Intl-enumeration, Array.prototype.includes] ---*/ const numberingSystems = Intl.supportedValuesOf("numberingSystem"); diff --git a/JSTests/test262/test/intl402/Intl/supportedValuesOf/numberingSystems-accepted-by-NumberFormat.js b/JSTests/test262/test/intl402/Intl/supportedValuesOf/numberingSystems-accepted-by-NumberFormat.js index 99b36942f50d..67ee2ef9813d 100644 --- a/JSTests/test262/test/intl402/Intl/supportedValuesOf/numberingSystems-accepted-by-NumberFormat.js +++ b/JSTests/test262/test/intl402/Intl/supportedValuesOf/numberingSystems-accepted-by-NumberFormat.js @@ -25,7 +25,7 @@ info: | value of every row of Table 4, except the header row. includes: [testIntl.js] locale: [en] -features: [Intl-enumeration] +features: [Intl-enumeration, Array.prototype.includes] ---*/ const numberingSystems = Intl.supportedValuesOf("numberingSystem"); diff --git a/JSTests/test262/test/intl402/Intl/supportedValuesOf/numberingSystems-accepted-by-RelativeTimeFormat.js b/JSTests/test262/test/intl402/Intl/supportedValuesOf/numberingSystems-accepted-by-RelativeTimeFormat.js index ec82f8b6b8de..5f0a5c1cde6f 100644 --- a/JSTests/test262/test/intl402/Intl/supportedValuesOf/numberingSystems-accepted-by-RelativeTimeFormat.js +++ b/JSTests/test262/test/intl402/Intl/supportedValuesOf/numberingSystems-accepted-by-RelativeTimeFormat.js @@ -25,7 +25,7 @@ info: | value of every row of Table 4, except the header row. includes: [testIntl.js] locale: [en] -features: [Intl-enumeration, Intl.RelativeTimeFormat] +features: [Intl-enumeration, Intl.RelativeTimeFormat, Array.prototype.includes] ---*/ const numberingSystems = Intl.supportedValuesOf("numberingSystem"); diff --git a/JSTests/test262/test/intl402/Intl/supportedValuesOf/numberingSystems-with-simple-digit-mappings.js b/JSTests/test262/test/intl402/Intl/supportedValuesOf/numberingSystems-with-simple-digit-mappings.js index 62211a960c8e..320f0f195de8 100644 --- a/JSTests/test262/test/intl402/Intl/supportedValuesOf/numberingSystems-with-simple-digit-mappings.js +++ b/JSTests/test262/test/intl402/Intl/supportedValuesOf/numberingSystems-with-simple-digit-mappings.js @@ -24,7 +24,7 @@ info: | Intl.RelativeTimeFormat objects. The list must include the Numbering System value of every row of Table 4, except the header row. includes: [testIntl.js] -features: [Intl-enumeration] +features: [Intl-enumeration, Array.prototype.includes] ---*/ const numberingSystems = Intl.supportedValuesOf("numberingSystem"); diff --git a/JSTests/test262/test/intl402/Intl/supportedValuesOf/units-accepted-by-NumberFormat.js b/JSTests/test262/test/intl402/Intl/supportedValuesOf/units-accepted-by-NumberFormat.js index fa47e88c7006..110972c79ad2 100644 --- a/JSTests/test262/test/intl402/Intl/supportedValuesOf/units-accepted-by-NumberFormat.js +++ b/JSTests/test262/test/intl402/Intl/supportedValuesOf/units-accepted-by-NumberFormat.js @@ -22,7 +22,7 @@ info: | identifiers listed in every row of Table 1, except the header row. includes: [testIntl.js] locale: [en] -features: [Intl-enumeration] +features: [Intl-enumeration, Array.prototype.includes] ---*/ const units = Intl.supportedValuesOf("unit"); diff --git a/JSTests/test262/test/intl402/Intl/supportedValuesOf/units.js b/JSTests/test262/test/intl402/Intl/supportedValuesOf/units.js index d05e648f8409..b3c37dcffe66 100644 --- a/JSTests/test262/test/intl402/Intl/supportedValuesOf/units.js +++ b/JSTests/test262/test/intl402/Intl/supportedValuesOf/units.js @@ -21,7 +21,7 @@ info: | undefined as comparefn, that contains the unique values of simple unit identifiers listed in every row of Table 1, except the header row. includes: [compareArray.js, testIntl.js] -features: [Intl-enumeration] +features: [Intl-enumeration, Array.prototype.includes] ---*/ const units = Intl.supportedValuesOf("unit"); diff --git a/JSTests/test262/test/intl402/Locale/constructor-non-iana-canon.js b/JSTests/test262/test/intl402/Locale/constructor-non-iana-canon.js index 8bc486dccfee..b8f93268e517 100644 --- a/JSTests/test262/test/intl402/Locale/constructor-non-iana-canon.js +++ b/JSTests/test262/test/intl402/Locale/constructor-non-iana-canon.js @@ -86,6 +86,7 @@ var testData = [ { tag: "hy-arevmda", canonical: "hyw", + maximized: "hyw-Armn-AM", }, ]; diff --git a/JSTests/test262/test/intl402/Locale/prototype/collations/output-array-values.js b/JSTests/test262/test/intl402/Locale/prototype/collations/output-array-values.js index 04dce3ea5c52..7f1656d528d8 100644 --- a/JSTests/test262/test/intl402/Locale/prototype/collations/output-array-values.js +++ b/JSTests/test262/test/intl402/Locale/prototype/collations/output-array-values.js @@ -14,7 +14,7 @@ info: | Unicode Locale Identifier, section 3.2, sorted in descending preference of those in common use for string comparison in locale. The values "standard" and "search" must be excluded from list. -features: [Intl.Locale,Intl.Locale-info] +features: [Intl.Locale, Intl.Locale-info, Array.prototype.includes] ---*/ const output = new Intl.Locale('en').collations; diff --git a/JSTests/test262/test/intl402/Locale/prototype/hourCycles/output-array-values.js b/JSTests/test262/test/intl402/Locale/prototype/hourCycles/output-array-values.js index 37cfe713eca2..3d7976a964cc 100644 --- a/JSTests/test262/test/intl402/Locale/prototype/hourCycles/output-array-values.js +++ b/JSTests/test262/test/intl402/Locale/prototype/hourCycles/output-array-values.js @@ -13,7 +13,7 @@ info: | be lower case String values indicating either the 12-hour format ("h11", "h12") or the 24-hour format ("h23", "h24"), sorted in descending preference of those in common use for date and time formatting in locale. -features: [Intl.Locale,Intl.Locale-info] +features: [Intl.Locale, Intl.Locale-info, Array.prototype.includes] ---*/ const output = new Intl.Locale('en').hourCycles; diff --git a/JSTests/test262/test/intl402/Locale/prototype/minimize/removing-likely-subtags-first-adds-likely-subtags.js b/JSTests/test262/test/intl402/Locale/prototype/minimize/removing-likely-subtags-first-adds-likely-subtags.js index 2b2368b383f7..98c28fdd1ba7 100644 --- a/JSTests/test262/test/intl402/Locale/prototype/minimize/removing-likely-subtags-first-adds-likely-subtags.js +++ b/JSTests/test262/test/intl402/Locale/prototype/minimize/removing-likely-subtags-first-adds-likely-subtags.js @@ -27,12 +27,12 @@ var testDataMinimal = { "und-AT": "de-AT", // https://unicode-org.atlassian.net/browse/ICU-13786 - "aae-Latn-IT": "aae-Latn-IT", + "aae-Latn-IT": "aae", "aae-Thai-CO": "aae-Thai-CO", // https://unicode-org.atlassian.net/browse/ICU-10220 // https://unicode-org.atlassian.net/browse/ICU-12345 - "und-CW": "pap-CW", + "und-CW": "pap", "und-US": "en", "zh-Hant": "zh-TW", "zh-Hani": "zh-Hani", diff --git a/JSTests/test262/test/intl402/NumberFormat/casing-numbering-system-options.js b/JSTests/test262/test/intl402/NumberFormat/casing-numbering-system-options.js index 8e927a9c3a8e..79d780e85651 100644 --- a/JSTests/test262/test/intl402/NumberFormat/casing-numbering-system-options.js +++ b/JSTests/test262/test/intl402/NumberFormat/casing-numbering-system-options.js @@ -6,6 +6,7 @@ esid: sec-initializenumberformat description: > Tests that the options numberingSystem are mapped to lower case. author: Caio Lima +features: [Array.prototype.includes] ---*/ let defaultLocale = new Intl.NumberFormat().resolvedOptions().locale; diff --git a/JSTests/test262/test/intl402/PluralRules/prototype/resolvedOptions/pluralCategories.js b/JSTests/test262/test/intl402/PluralRules/prototype/resolvedOptions/pluralCategories.js index 9481dc978774..173dde9f7d6a 100644 --- a/JSTests/test262/test/intl402/PluralRules/prototype/resolvedOptions/pluralCategories.js +++ b/JSTests/test262/test/intl402/PluralRules/prototype/resolvedOptions/pluralCategories.js @@ -7,6 +7,7 @@ description: > Tests that Intl.PluralRules.prototype.resolvedOptions creates a new array for the pluralCategories property on every call. includes: [propertyHelper.js, compareArray.js] +features: [Array.prototype.includes] ---*/ const allowedValues = ["zero", "one", "two", "few", "many", "other"]; diff --git a/JSTests/test262/test/intl402/Segmenter/constructor/constructor/locales-valid.js b/JSTests/test262/test/intl402/Segmenter/constructor/constructor/locales-valid.js index 2361c6e37fa8..5aa4324b6056 100644 --- a/JSTests/test262/test/intl402/Segmenter/constructor/constructor/locales-valid.js +++ b/JSTests/test262/test/intl402/Segmenter/constructor/constructor/locales-valid.js @@ -8,7 +8,7 @@ info: | Intl.Segmenter ([ locales [ , options ]]) 3. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_). -features: [Intl.Segmenter] +features: [Intl.Segmenter, Array.prototype.includes] ---*/ const defaultLocale = new Intl.Segmenter().resolvedOptions().locale; diff --git a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/dateFromFields/one-of-era-erayear-undefined.js b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/dateFromFields/one-of-era-erayear-undefined.js new file mode 100644 index 000000000000..cf39421ef25a --- /dev/null +++ b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/dateFromFields/one-of-era-erayear-undefined.js @@ -0,0 +1,19 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.datefromfields +description: Throw a RangeError if only one of era/eraYear fields is present +features: [Temporal] +---*/ + +const base = { year: 2000, month: 5, day: 2, era: 'ce' }; +const instance = new Temporal.Calendar('gregory'); +assert.throws(RangeError, () => { + instance.dateFromFields({ ...base }); +}); + +const base2 = { year: 2000, month: 5, day: 2, eraYear: 1 }; +assert.throws(RangeError, () => { + instance.dateFromFields({ ...base2 }); +}); diff --git a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/dateFromFields/order-of-operations.js b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/dateFromFields/order-of-operations.js index a5639d8e4ee0..bc67df945671 100644 --- a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/dateFromFields/order-of-operations.js +++ b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/dateFromFields/order-of-operations.js @@ -72,5 +72,5 @@ const arg2 = new Proxy(options, { const result = instance.dateFromFields(arg1, arg2); TemporalHelpers.assertPlainDate(result, 1, 1, "M01", 1, "date result", "ce", 1); -assert.sameValue(result.calendar, instance, "calendar result"); +assert.sameValue(result.getISOFields().calendar, "gregory", "calendar slot should store a string"); assert.compareArray(actual, expected, "order of operations"); diff --git a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/dateUntil/until-across-lunisolar-leap-months.js b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/dateUntil/until-across-lunisolar-leap-months.js new file mode 100644 index 000000000000..f35f6332a8c2 --- /dev/null +++ b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/dateUntil/until-across-lunisolar-leap-months.js @@ -0,0 +1,22 @@ +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: dateUntil works as expected after a leap month in a lunisolar calendar +esid: sec-temporal.calendar.prototype.dateuntil +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("chinese"); + +// 2001 is a leap year in the Chinese calendar with a M04L leap month. +// Therefore, month: 6 is M05 in 2001 but M06 in 2000 which is not a leap year. +const one = Temporal.PlainDate.from({ year: 2000, month: 6, day: 1, calendar: 'chinese' }); +const two = Temporal.PlainDate.from({ year: 2001, month: 6, day: 1, calendar: 'chinese' }); + +const expected = { years: 'P12M', months: 'P12M', weeks: 'P50W4D', days: 'P354D' }; + +Object.entries(expected).forEach(([largestUnit, expectedResult]) => { + const actualResult = instance.dateUntil(one, two, { largestUnit }); + assert.sameValue(actualResult.toString(), expectedResult); +}); diff --git a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/dateUntil/zero-length-duration-result.js b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/dateUntil/zero-length-duration-result.js new file mode 100644 index 000000000000..e852a60f4b2c --- /dev/null +++ b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/dateUntil/zero-length-duration-result.js @@ -0,0 +1,16 @@ +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: The duration from a date to itself is a zero duration (PT0S) +esid: sec-temporal.calendar.prototype.dateuntil +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("gregory"); +const date = new Temporal.PlainDate(2001, 6, 3); + +['year', 'month', 'week', 'day'].forEach((largestUnit) => { + const result = instance.dateUntil(date, date, { largestUnit }); + assert.sameValue(result.toString(), 'PT0S'); +}); diff --git a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/era/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/era/argument-propertybag-calendar-case-insensitive.js index e87641d32761..790f6401edd3 100644 --- a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/era/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/era/argument-propertybag-calendar-case-insensitive.js @@ -11,10 +11,6 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = "IsO8601"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.era(arg); -assert.sameValue(result1, undefined, "Calendar is case-insensitive"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.era(arg); -assert.sameValue(result2, undefined, "Calendar is case-insensitive (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.era(arg); +assert.sameValue(result, undefined, "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/era/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/era/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 2a05f17642cc..000000000000 --- a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/era/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,25 +0,0 @@ -// 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.era -description: > - A Temporal.Calendar instance passed to era() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.Calendar("iso8601"); - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -instance.era(arg); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -instance.era(arg); diff --git a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/era/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/era/argument-propertybag-calendar-leap-second.js index 645159e7472e..97a5dd6298ef 100644 --- a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/era/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/era/argument-propertybag-calendar-leap-second.js @@ -11,18 +11,10 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = "2016-12-31T23:59:60"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.era(arg); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.era(arg); assert.sameValue( - result1, + result, undefined, "leap second is a valid ISO string for calendar" ); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.era(arg); -assert.sameValue( - result2, - undefined, - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/era/argument-propertybag-calendar-number.js b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/era/argument-propertybag-calendar-number.js index e355b70e9518..348130bb0398 100644 --- a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/era/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/era/argument-propertybag-calendar-number.js @@ -11,13 +11,9 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = 19970327; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.era(arg); -assert.sameValue(result1, undefined, "19970327 is a valid ISO string for calendar"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.era(arg); -assert.sameValue(result2, undefined, "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.era(arg); +assert.sameValue(result, undefined, "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -26,16 +22,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; assert.throws( RangeError, () => instance.era(arg), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.era(arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/era/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/era/argument-propertybag-calendar-wrong-type.js index ef916fc9c61e..90c4346527e5 100644 --- a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/era/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/era/argument-propertybag-calendar-wrong-type.js @@ -21,27 +21,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.era(arg), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.era(arg), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.era(arg), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.era(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.era(arg), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/era/argument-string-calendar-annotation.js b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/era/argument-string-calendar-annotation.js index 68b6b81534c6..86214a5587c6 100644 --- a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/era/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/era/argument-string-calendar-annotation.js @@ -15,7 +15,6 @@ const tests = [ ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const instance = new Temporal.Calendar("iso8601"); diff --git a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/era/argument-string-multiple-calendar.js b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/era/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..6c1da80f38ca --- /dev/null +++ b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/era/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.era +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.era(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/eraYear/argument-propertybag-calendar-case-insensitive.js b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/eraYear/argument-propertybag-calendar-case-insensitive.js index 48f60e13484a..c25f3bf4ae59 100644 --- a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/eraYear/argument-propertybag-calendar-case-insensitive.js +++ b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/eraYear/argument-propertybag-calendar-case-insensitive.js @@ -11,10 +11,6 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = "IsO8601"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.eraYear(arg); -assert.sameValue(result1, undefined, "Calendar is case-insensitive"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.eraYear(arg); -assert.sameValue(result2, undefined, "Calendar is case-insensitive (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.eraYear(arg); +assert.sameValue(result, undefined, "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/eraYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/eraYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js deleted file mode 100644 index 39d5e343f26c..000000000000 --- a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/eraYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js +++ /dev/null @@ -1,25 +0,0 @@ -// 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.erayear -description: > - A Temporal.Calendar instance passed to eraYear() in a property bag does - not have its 'calendar' property observably checked -features: [Temporal] ----*/ - -const instance = new Temporal.Calendar("iso8601"); - -const calendar = new Temporal.Calendar("iso8601"); -Object.defineProperty(calendar, "calendar", { - get() { - throw new Test262Error("calendar.calendar should not be accessed"); - }, -}); - -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -instance.eraYear(arg); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -instance.eraYear(arg); diff --git a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/eraYear/argument-propertybag-calendar-leap-second.js b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/eraYear/argument-propertybag-calendar-leap-second.js index 1a2e15215b8c..9f27c8d8daaf 100644 --- a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/eraYear/argument-propertybag-calendar-leap-second.js +++ b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/eraYear/argument-propertybag-calendar-leap-second.js @@ -11,18 +11,10 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = "2016-12-31T23:59:60"; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.eraYear(arg); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.eraYear(arg); assert.sameValue( - result1, + result, undefined, "leap second is a valid ISO string for calendar" ); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.eraYear(arg); -assert.sameValue( - result2, - undefined, - "leap second is a valid ISO string for calendar (nested property)" -); diff --git a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/eraYear/argument-propertybag-calendar-number.js b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/eraYear/argument-propertybag-calendar-number.js index e1640061d821..7ea80459f9ac 100644 --- a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/eraYear/argument-propertybag-calendar-number.js +++ b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/eraYear/argument-propertybag-calendar-number.js @@ -11,13 +11,9 @@ const instance = new Temporal.Calendar("iso8601"); const calendar = 19970327; -let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; -const result1 = instance.eraYear(arg); -assert.sameValue(result1, undefined, "19970327 is a valid ISO string for calendar"); - -arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; -const result2 = instance.eraYear(arg); -assert.sameValue(result2, undefined, "19970327 is a valid ISO string for calendar (nested property)"); +const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result = instance.eraYear(arg); +assert.sameValue(result, undefined, "19970327 is a valid ISO string for calendar"); const numbers = [ 1, @@ -26,16 +22,10 @@ const numbers = [ ]; for (const calendar of numbers) { - let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + const arg = { year: 1976, monthCode: "M11", day: 18, calendar }; assert.throws( RangeError, () => instance.eraYear(arg), `Number ${calendar} does not convert to a valid ISO string for calendar` ); - arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; - assert.throws( - RangeError, - () => instance.eraYear(arg), - `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` - ); } diff --git a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/eraYear/argument-propertybag-calendar-wrong-type.js b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/eraYear/argument-propertybag-calendar-wrong-type.js index fe9969bb0cd4..4e9f42a80c5b 100644 --- a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/eraYear/argument-propertybag-calendar-wrong-type.js +++ b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/eraYear/argument-propertybag-calendar-wrong-type.js @@ -21,27 +21,19 @@ const rangeErrorTests = [ ]; for (const [calendar, description] of rangeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(RangeError, () => instance.eraYear(arg), `${description} does not convert to a valid ISO string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(RangeError, () => instance.eraYear(arg), `${description} does not convert to a valid ISO string (nested property)`); } const typeErrorTests = [ [Symbol(), "symbol"], - [{}, "plain object"], // TypeError due to missing dateFromFields() - [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [{}, "plain object that doesn't implement the protocol"], + [new Temporal.TimeZone("UTC"), "time zone instance"], + [Temporal.Calendar, "Temporal.Calendar, object"], [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() ]; for (const [calendar, description] of typeErrorTests) { - let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws(TypeError, () => instance.eraYear(arg), `${description} is not a valid property bag and does not convert to a string`); - - arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; - assert.throws(TypeError, () => instance.eraYear(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); } - -const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; -assert.throws(RangeError, () => instance.eraYear(arg), `nested undefined calendar property is always a RangeError`); diff --git a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/eraYear/argument-string-calendar-annotation.js b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/eraYear/argument-string-calendar-annotation.js index e2221c807eb1..d2d6ed0a2c9f 100644 --- a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/eraYear/argument-string-calendar-annotation.js +++ b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/eraYear/argument-string-calendar-annotation.js @@ -15,7 +15,6 @@ const tests = [ ["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"], ["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"], ["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"], - ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"], ]; const instance = new Temporal.Calendar("iso8601"); diff --git a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/eraYear/argument-string-multiple-calendar.js b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/eraYear/argument-string-multiple-calendar.js new file mode 100644 index 000000000000..7886e01eb05b --- /dev/null +++ b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/eraYear/argument-string-multiple-calendar.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.erayear +description: > + More than one calendar annotation is not syntactical if any have the criical + flag +features: [Temporal] +---*/ + +const invalidStrings = [ + "1970-01-01[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]", + "1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]", + "1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.eraYear(arg), + `reject more than one calendar annotation if any critical: ${arg}` + ); +}); diff --git a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/mergeFields/gregorian-mutually-exclusive-fields.js b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/mergeFields/gregorian-mutually-exclusive-fields.js index b8d2893c9f30..ffb5e1c0679d 100644 --- a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/mergeFields/gregorian-mutually-exclusive-fields.js +++ b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/mergeFields/gregorian-mutually-exclusive-fields.js @@ -37,34 +37,34 @@ const fullFields = { }; assertEntriesEqual(instance.mergeFields(fullFields, { era: "bce", eraYear: 1 }), [ + ["era", "bce"], + ["eraYear", 1], ["month", 12], ["monthCode", "M12"], ["day", 15], - ["era", "bce"], - ["eraYear", 1], ], "era and eraYear together exclude year"); assertEntriesEqual(instance.mergeFields(fullFields, { year: -2 }), [ + ["year", -2], ["month", 12], ["monthCode", "M12"], ["day", 15], - ["year", -2], ], "year excludes era and eraYear"); assertEntriesEqual(instance.mergeFields(fullFields, { month: 5 }), [ ["era", "ce"], ["eraYear", 1981], ["year", 1981], - ["day", 15], ["month", 5], + ["day", 15], ], "month excludes monthCode"); assertEntriesEqual(instance.mergeFields(fullFields, { monthCode: "M05" }), [ ["era", "ce"], ["eraYear", 1981], ["year", 1981], - ["day", 15], ["monthCode", "M05"], + ["day", 15], ], "monthCode excludes month"); // Specific test cases, of mergeFields on information that is not complete @@ -100,6 +100,6 @@ assertEntriesEqual(instance.mergeFields({ day: 25, monthCode: "M12", year: 1997, assertEntriesEqual(instance.mergeFields({ day: 25, monthCode: "M12", year: 1997 }, { eraYear: 1, year: 2 }), [ ["day", 25], ["monthCode", "M12"], - ["eraYear", 1], ["year", 2], + ["eraYear", 1], ], "eraYear excludes year and era, year overwritten"); diff --git a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/mergeFields/japanese-mutually-exclusive-fields.js b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/mergeFields/japanese-mutually-exclusive-fields.js index aeaa9f0cf39d..4dcb0a30e2e8 100644 --- a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/mergeFields/japanese-mutually-exclusive-fields.js +++ b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/mergeFields/japanese-mutually-exclusive-fields.js @@ -38,40 +38,40 @@ assertEntriesEqual(instance.mergeFields(lastDayOfShowaFields, { day: 10 }), [ assertEntriesEqual(instance.mergeFields(lastDayOfShowaFields, { month: 2 }), [ ["year", 1989], - ["day", 7], ["month", 2], + ["day", 7], ], "month excludes monthCode, era, and eraYear"); assertEntriesEqual(instance.mergeFields(lastDayOfShowaFields, { monthCode: "M03" }), [ ["year", 1989], - ["day", 7], ["monthCode", "M03"], + ["day", 7], ], "monthCode excludes month, era, and eraYear"); assertEntriesEqual(instance.mergeFields(lastDayOfShowaFields, { year: 1988 }), [ + ["year", 1988], ["month", 1], ["monthCode", "M01"], ["day", 7], - ["year", 1988], ], "year excludes era and eraYear (within same era)"); assertEntriesEqual(instance.mergeFields(lastDayOfShowaFields, { year: 1990 }), [ + ["year", 1990], ["month", 1], ["monthCode", "M01"], ["day", 7], - ["year", 1990], ], "year excludes era and eraYear (in a different era)"); assertEntriesEqual(instance.mergeFields(lastDayOfShowaFields, { eraYear: 1 }), [ + ["eraYear", 1], ["month", 1], ["monthCode", "M01"], ["day", 7], - ["eraYear", 1], ], "eraYear excludes year and era"); assertEntriesEqual(instance.mergeFields(lastDayOfShowaFields, { era: "heisei" }), [ + ["era", "heisei"], ["month", 1], ["monthCode", "M01"], ["day", 7], - ["era", "heisei"], ], "era excludes year and eraYear"); diff --git a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/monthDayFromFields/one-of-era-erayear-undefined.js b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/monthDayFromFields/one-of-era-erayear-undefined.js new file mode 100644 index 000000000000..4a519ceae1ff --- /dev/null +++ b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/monthDayFromFields/one-of-era-erayear-undefined.js @@ -0,0 +1,19 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.monthdayfromfields +description: Throw a RangeError if only one of era/eraYear fields is present +features: [Temporal] +---*/ + +const base = { year: 2000, month: 5, day: 2, era: 'ce' }; +const instance = new Temporal.Calendar('gregory'); +assert.throws(RangeError, () => { + instance.monthDayFromFields({ ...base }); +}); + +const base2 = { year: 2000, month: 5, day: 2, eraYear: 1 }; +assert.throws(RangeError, () => { + instance.dateFromFields({ ...base2 }); +}); diff --git a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/monthDayFromFields/order-of-operations.js b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/monthDayFromFields/order-of-operations.js index 2c39686e3d89..1dd4fe9eaa55 100644 --- a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/monthDayFromFields/order-of-operations.js +++ b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/monthDayFromFields/order-of-operations.js @@ -72,5 +72,5 @@ const arg2 = new Proxy(options, { const result = instance.monthDayFromFields(arg1, arg2); TemporalHelpers.assertPlainMonthDay(result, "M01", 1, "monthDay result"); -assert.sameValue(result.calendar, instance, "calendar result"); +assert.sameValue(result.getISOFields().calendar, "gregory", "calendar slot should store a string"); assert.compareArray(actual, expected, "order of operations"); diff --git a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/yearMonthFromFields/one-of-era-erayear-undefined.js b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/yearMonthFromFields/one-of-era-erayear-undefined.js new file mode 100644 index 000000000000..aba160a3057c --- /dev/null +++ b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/yearMonthFromFields/one-of-era-erayear-undefined.js @@ -0,0 +1,19 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.yearmonthfromfields +description: Throw a RangeError if only one of era/eraYear fields is present +features: [Temporal] +---*/ + +const base = { year: 2000, month: 5, day: 2, era: 'ce' }; +const instance = new Temporal.Calendar('gregory'); +assert.throws(RangeError, () => { + instance.yearMonthFromFields({ ...base }); +}); + +const base2 = { year: 2000, month: 5, day: 2, eraYear: 1 }; +assert.throws(RangeError, () => { + instance.yearMonthFromFields({ ...base2 }); +}); diff --git a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/yearMonthFromFields/order-of-operations.js b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/yearMonthFromFields/order-of-operations.js index ad3129730aad..48d7390b2eb9 100644 --- a/JSTests/test262/test/intl402/Temporal/Calendar/prototype/yearMonthFromFields/order-of-operations.js +++ b/JSTests/test262/test/intl402/Temporal/Calendar/prototype/yearMonthFromFields/order-of-operations.js @@ -68,5 +68,5 @@ const arg2 = new Proxy(options, { const result = instance.yearMonthFromFields(arg1, arg2); TemporalHelpers.assertPlainYearMonth(result, 1, 1, "M01", "yearMonth result", "ce", 1); -assert.sameValue(result.calendar, instance, "calendar result"); +assert.sameValue(result.getISOFields().calendar, "gregory", "calendar slot should store a string"); assert.compareArray(actual, expected, "order of operations"); diff --git a/JSTests/test262/test/intl402/Temporal/Duration/prototype/round/relativeto-string-datetime.js b/JSTests/test262/test/intl402/Temporal/Duration/prototype/round/relativeto-string-datetime.js index 3ec0960f4f09..3d4f118549c0 100644 --- a/JSTests/test262/test/intl402/Temporal/Duration/prototype/round/relativeto-string-datetime.js +++ b/JSTests/test262/test/intl402/Temporal/Duration/prototype/round/relativeto-string-datetime.js @@ -14,15 +14,15 @@ const instance = new Temporal.Duration(1, 0, 0, 0, 24); let relativeTo = "2019-11-01T00:00[America/Vancouver]"; const result4 = instance.round({ largestUnit: "years", relativeTo }); -TemporalHelpers.assertDuration(result4, 1, 0, 0, 0, 24, 0, 0, 0, 0, 0, "date-time + IANA annotation is a zoned relativeTo"); +TemporalHelpers.assertDuration(result4, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, "date-time + IANA annotation is a zoned relativeTo"); relativeTo = "2019-11-01T00:00Z[America/Vancouver]"; const result5 = instance.round({ largestUnit: "years", relativeTo }); -TemporalHelpers.assertDuration(result5, 1, 0, 0, 0, 24, 0, 0, 0, 0, 0, "date-time + Z + IANA annotation is a zoned relativeTo"); +TemporalHelpers.assertDuration(result5, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, "date-time + Z + IANA annotation is a zoned relativeTo"); relativeTo = "2019-11-01T00:00-07:00[America/Vancouver]"; const result6 = instance.round({ largestUnit: "years", relativeTo }); -TemporalHelpers.assertDuration(result6, 1, 0, 0, 0, 24, 0, 0, 0, 0, 0, "date-time + offset + IANA annotation is a zoned relativeTo"); +TemporalHelpers.assertDuration(result6, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, "date-time + offset + IANA annotation is a zoned relativeTo"); relativeTo = "2019-11-01T00:00+04:15[America/Vancouver]"; assert.throws(RangeError, () => instance.round({ largestUnit: "years", relativeTo }), "date-time + offset + IANA annotation throws if wall time and exact time mismatch"); diff --git a/JSTests/test262/test/intl402/Temporal/Instant/prototype/toString/timezone-offset.js b/JSTests/test262/test/intl402/Temporal/Instant/prototype/toString/timezone-offset.js index ee2bd1e5fba1..7016baa59d54 100644 --- a/JSTests/test262/test/intl402/Temporal/Instant/prototype/toString/timezone-offset.js +++ b/JSTests/test262/test/intl402/Temporal/Instant/prototype/toString/timezone-offset.js @@ -3,7 +3,7 @@ /*--- esid: sec-temporal.instant.prototype.tostring -description: The time zone offset part of the string serialization (Intl time zones) +description: The time zone offset part of the string serialization (IANA time zones) features: [BigInt, Temporal] ---*/ diff --git a/JSTests/test262/test/intl402/Temporal/Instant/prototype/toString/timezone-string-datetime.js b/JSTests/test262/test/intl402/Temporal/Instant/prototype/toString/timezone-string-datetime.js index 0f7c812b6a3b..85b02cf67913 100644 --- a/JSTests/test262/test/intl402/Temporal/Instant/prototype/toString/timezone-string-datetime.js +++ b/JSTests/test262/test/intl402/Temporal/Instant/prototype/toString/timezone-string-datetime.js @@ -3,7 +3,7 @@ /*--- esid: sec-temporal.instant.prototype.tostring -description: Conversion of ISO date-time strings to Temporal.TimeZone instances (with Intl time zones) +description: Conversion of ISO date-time strings to Temporal.TimeZone instances (with IANA time zones) features: [Temporal] ---*/ @@ -12,17 +12,11 @@ const instance = new Temporal.Instant(0n); let timeZone = "2021-08-19T17:30[America/Vancouver]"; const result1 = instance.toString({ timeZone }); assert.sameValue(result1.substr(-6), "-08:00", "date-time + IANA annotation is the IANA time zone"); -const result2 = instance.toString({ timeZone: { timeZone } }); -assert.sameValue(result2.substr(-6), "-08:00", "date-time + IANA annotation is the IANA time zone (string in property bag)"); timeZone = "2021-08-19T17:30Z[America/Vancouver]"; -const result3 = instance.toString({ timeZone }); -assert.sameValue(result3.substr(-6), "-08:00", "date-time + Z + IANA annotation is the IANA time zone"); -const result4 = instance.toString({ timeZone: { timeZone } }); -assert.sameValue(result4.substr(-6), "-08:00", "date-time + Z + IANA annotation is the IANA time zone (string in property bag)"); +const result2 = instance.toString({ timeZone }); +assert.sameValue(result2.substr(-6), "-08:00", "date-time + Z + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30-07:00[America/Vancouver]"; -const result5 = instance.toString({ timeZone }); -assert.sameValue(result5.substr(-6), "-08:00", "date-time + offset + IANA annotation is the IANA time zone"); -const result6 = instance.toString({ timeZone: { timeZone } }); -assert.sameValue(result6.substr(-6), "-08:00", "date-time + offset + IANA annotation is the IANA time zone (string in property bag)"); +const result3 = instance.toString({ timeZone }); +assert.sameValue(result3.substr(-6), "-08:00", "date-time + offset + IANA annotation is the IANA time zone"); diff --git a/JSTests/test262/test/intl402/Temporal/Instant/prototype/toZonedDateTime/timezone-string-datetime.js b/JSTests/test262/test/intl402/Temporal/Instant/prototype/toZonedDateTime/timezone-string-datetime.js index 220f9a132802..db587332203c 100644 --- a/JSTests/test262/test/intl402/Temporal/Instant/prototype/toZonedDateTime/timezone-string-datetime.js +++ b/JSTests/test262/test/intl402/Temporal/Instant/prototype/toZonedDateTime/timezone-string-datetime.js @@ -3,7 +3,7 @@ /*--- esid: sec-temporal.instant.prototype.tozoneddatetime -description: Conversion of ISO date-time strings to Temporal.TimeZone instances (with Intl time zones) +description: Conversion of ISO date-time strings to Temporal.TimeZone instances (with IANA time zones) features: [Temporal] ---*/ @@ -11,18 +11,12 @@ const instance = new Temporal.Instant(0n); let timeZone = "2021-08-19T17:30[America/Vancouver]"; const result1 = instance.toZonedDateTime({ timeZone, calendar: "iso8601" }); -assert.sameValue(result1.timeZone.id, "America/Vancouver", "date-time + IANA annotation is the IANA time zone"); -const result2 = instance.toZonedDateTime({ timeZone: { timeZone }, calendar: "iso8601" }); -assert.sameValue(result2.timeZone.id, "America/Vancouver", "date-time + IANA annotation is the IANA time zone (string in property bag)"); +assert.sameValue(result1.timeZoneId, "America/Vancouver", "date-time + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30Z[America/Vancouver]"; -const result3 = instance.toZonedDateTime({ timeZone, calendar: "iso8601" }); -assert.sameValue(result3.timeZone.id, "America/Vancouver", "date-time + Z + IANA annotation is the IANA time zone"); -const result4 = instance.toZonedDateTime({ timeZone: { timeZone }, calendar: "iso8601" }); -assert.sameValue(result4.timeZone.id, "America/Vancouver", "date-time + Z + IANA annotation is the IANA time zone (string in property bag)"); +const result2 = instance.toZonedDateTime({ timeZone, calendar: "iso8601" }); +assert.sameValue(result2.timeZoneId, "America/Vancouver", "date-time + Z + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30-07:00[America/Vancouver]"; -const result5 = instance.toZonedDateTime({ timeZone, calendar: "iso8601" }); -assert.sameValue(result5.timeZone.id, "America/Vancouver", "date-time + offset + IANA annotation is the IANA time zone"); -const result6 = instance.toZonedDateTime({ timeZone: { timeZone }, calendar: "iso8601" }); -assert.sameValue(result6.timeZone.id, "America/Vancouver", "date-time + offset + IANA annotation is the IANA time zone (string in property bag)"); +const result3 = instance.toZonedDateTime({ timeZone, calendar: "iso8601" }); +assert.sameValue(result3.timeZoneId, "America/Vancouver", "date-time + offset + IANA annotation is the IANA time zone"); diff --git a/JSTests/test262/test/intl402/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-string-datetime.js b/JSTests/test262/test/intl402/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-string-datetime.js index 4ff2a51e9703..12a12c39d1ef 100644 --- a/JSTests/test262/test/intl402/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-string-datetime.js +++ b/JSTests/test262/test/intl402/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-string-datetime.js @@ -3,7 +3,7 @@ /*--- esid: sec-temporal.instant.prototype.tozoneddatetimeiso -description: Conversion of ISO date-time strings to Temporal.TimeZone instances (with Intl time zones) +description: Conversion of ISO date-time strings to Temporal.TimeZone instances (with IANA time zones) features: [Temporal] ---*/ @@ -11,18 +11,12 @@ const instance = new Temporal.Instant(0n); let timeZone = "2021-08-19T17:30[America/Vancouver]"; const result1 = instance.toZonedDateTimeISO(timeZone); -assert.sameValue(result1.timeZone.id, "America/Vancouver", "date-time + IANA annotation is the IANA time zone"); -const result2 = instance.toZonedDateTimeISO({ timeZone }); -assert.sameValue(result2.timeZone.id, "America/Vancouver", "date-time + IANA annotation is the IANA time zone (string in property bag)"); +assert.sameValue(result1.timeZoneId, "America/Vancouver", "date-time + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30Z[America/Vancouver]"; -const result3 = instance.toZonedDateTimeISO(timeZone); -assert.sameValue(result3.timeZone.id, "America/Vancouver", "date-time + Z + IANA annotation is the IANA time zone"); -const result4 = instance.toZonedDateTimeISO({ timeZone }); -assert.sameValue(result4.timeZone.id, "America/Vancouver", "date-time + Z + IANA annotation is the IANA time zone (string in property bag)"); +const result2 = instance.toZonedDateTimeISO(timeZone); +assert.sameValue(result2.timeZoneId, "America/Vancouver", "date-time + Z + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30-07:00[America/Vancouver]"; -const result5 = instance.toZonedDateTimeISO(timeZone); -assert.sameValue(result5.timeZone.id, "America/Vancouver", "date-time + offset + IANA annotation is the IANA time zone"); -const result6 = instance.toZonedDateTimeISO({ timeZone }); -assert.sameValue(result6.timeZone.id, "America/Vancouver", "date-time + offset + IANA annotation is the IANA time zone (string in property bag)"); +const result3 = instance.toZonedDateTimeISO(timeZone); +assert.sameValue(result3.timeZoneId, "America/Vancouver", "date-time + offset + IANA annotation is the IANA time zone"); diff --git a/JSTests/test262/test/intl402/Temporal/Now/plainDate/calendar-string.js b/JSTests/test262/test/intl402/Temporal/Now/plainDate/calendar-string.js index e1cfa7fb14b3..4fcb57261729 100644 --- a/JSTests/test262/test/intl402/Temporal/Now/plainDate/calendar-string.js +++ b/JSTests/test262/test/intl402/Temporal/Now/plainDate/calendar-string.js @@ -9,4 +9,4 @@ features: [Temporal] const date = Temporal.Now.plainDate("gregory"); assert(date instanceof Temporal.PlainDate); -assert.sameValue(date.calendar.id, "gregory"); +assert.sameValue(date.calendarId, "gregory"); diff --git a/JSTests/test262/test/intl402/Temporal/Now/plainDateTime/calendar-string.js b/JSTests/test262/test/intl402/Temporal/Now/plainDateTime/calendar-string.js index aa1ff27ba0f4..6cfce86d54aa 100644 --- a/JSTests/test262/test/intl402/Temporal/Now/plainDateTime/calendar-string.js +++ b/JSTests/test262/test/intl402/Temporal/Now/plainDateTime/calendar-string.js @@ -9,4 +9,4 @@ features: [Temporal] const dt = Temporal.Now.plainDateTime("gregory"); assert(dt instanceof Temporal.PlainDateTime); -assert.sameValue(dt.calendar.id, "gregory"); +assert.sameValue(dt.calendarId, "gregory"); diff --git a/JSTests/test262/test/intl402/Temporal/Now/plainDateTimeISO/timezone-string-datetime.js b/JSTests/test262/test/intl402/Temporal/Now/plainDateTimeISO/timezone-string-datetime.js index f2525a95a545..fc7b26659298 100644 --- a/JSTests/test262/test/intl402/Temporal/Now/plainDateTimeISO/timezone-string-datetime.js +++ b/JSTests/test262/test/intl402/Temporal/Now/plainDateTimeISO/timezone-string-datetime.js @@ -8,7 +8,6 @@ features: [Temporal] let timeZone = "2021-08-19T17:30"; assert.throws(RangeError, () => Temporal.Now.plainDateTimeISO(timeZone), "bare date-time string is not a time zone"); -assert.throws(RangeError, () => Temporal.Now.plainDateTimeISO({ timeZone }), "bare date-time string is not a time zone"); // The following are all valid strings so should not throw: @@ -29,5 +28,4 @@ assert.throws(RangeError, () => Temporal.Now.plainDateTimeISO({ timeZone }), "ba "2021-08-19T1730-0700[America/Vancouver]", ].forEach((timeZone) => { Temporal.Now.plainDateTimeISO(timeZone); - Temporal.Now.plainDateTimeISO({ timeZone }); }); diff --git a/JSTests/test262/test/intl402/Temporal/Now/zonedDateTime/calendar-string.js b/JSTests/test262/test/intl402/Temporal/Now/zonedDateTime/calendar-string.js index 2b75ab8dfc02..0fdd7097bf90 100644 --- a/JSTests/test262/test/intl402/Temporal/Now/zonedDateTime/calendar-string.js +++ b/JSTests/test262/test/intl402/Temporal/Now/zonedDateTime/calendar-string.js @@ -8,10 +8,9 @@ features: [Temporal] ---*/ const zdt = Temporal.Now.zonedDateTime("gregory"); -const tz = Temporal.Now.timeZone(); +const tz = Temporal.Now.timeZoneId(); assert(zdt instanceof Temporal.ZonedDateTime); -assert(zdt.calendar instanceof Temporal.Calendar); -assert.sameValue(zdt.calendar.id, "gregory"); -assert(zdt.timeZone instanceof Temporal.TimeZone); -assert.sameValue(zdt.timeZone.id, tz.id); - +assert.sameValue(typeof zdt.getISOFields().calendar, "string", "calendar slot should store a string"); +assert.sameValue(zdt.calendarId, "gregory"); +assert.sameValue(typeof zdt.getISOFields().timeZone, "string", "time zone slot should store a string"); +assert.sameValue(zdt.timeZoneId, tz); diff --git a/JSTests/test262/test/intl402/Temporal/Now/zonedDateTime/calendar-timezone-string.js b/JSTests/test262/test/intl402/Temporal/Now/zonedDateTime/calendar-timezone-string.js index 98be7bc03c89..76d9962d0ee8 100644 --- a/JSTests/test262/test/intl402/Temporal/Now/zonedDateTime/calendar-timezone-string.js +++ b/JSTests/test262/test/intl402/Temporal/Now/zonedDateTime/calendar-timezone-string.js @@ -9,7 +9,7 @@ features: [Temporal] const zdt = Temporal.Now.zonedDateTime("gregory", "America/Los_Angeles"); assert(zdt instanceof Temporal.ZonedDateTime); -assert(zdt.calendar instanceof Temporal.Calendar); -assert.sameValue(zdt.calendar.id, "gregory"); -assert(zdt.timeZone instanceof Temporal.TimeZone); -assert.sameValue(zdt.timeZone.id, "America/Los_Angeles"); +assert.sameValue(typeof zdt.getISOFields().calendar, "string", "calendar slot should store a string"); +assert.sameValue(zdt.calendarId, "gregory"); +assert.sameValue(typeof zdt.getISOFields().timeZone, "string", "time zone slot should store a string"); +assert.sameValue(zdt.timeZoneId, "America/Los_Angeles"); diff --git a/JSTests/test262/test/intl402/Temporal/Now/zonedDateTime/timezone-string-datetime.js b/JSTests/test262/test/intl402/Temporal/Now/zonedDateTime/timezone-string-datetime.js index 5c69442a0161..a8dc4d386062 100644 --- a/JSTests/test262/test/intl402/Temporal/Now/zonedDateTime/timezone-string-datetime.js +++ b/JSTests/test262/test/intl402/Temporal/Now/zonedDateTime/timezone-string-datetime.js @@ -3,24 +3,18 @@ /*--- esid: sec-temporal.now.zoneddatetime -description: Conversion of ISO date-time strings to Temporal.TimeZone instances (with Intl time zones) +description: Conversion of ISO date-time strings to Temporal.TimeZone instances (with IANA time zones) features: [Temporal] ---*/ let timeZone = "2021-08-19T17:30[America/Vancouver]"; const result1 = Temporal.Now.zonedDateTime("iso8601", timeZone); -assert.sameValue(result1.timeZone.id, "America/Vancouver", "date-time + IANA annotation is the IANA time zone"); -const result2 = Temporal.Now.zonedDateTime("iso8601", { timeZone }); -assert.sameValue(result2.timeZone.id, "America/Vancouver", "date-time + IANA annotation is the IANA time zone (string in property bag)"); +assert.sameValue(result1.timeZoneId, "America/Vancouver", "date-time + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30Z[America/Vancouver]"; -const result3 = Temporal.Now.zonedDateTime("iso8601", timeZone); -assert.sameValue(result3.timeZone.id, "America/Vancouver", "date-time + Z + IANA annotation is the IANA time zone"); -const result4 = Temporal.Now.zonedDateTime("iso8601", { timeZone }); -assert.sameValue(result4.timeZone.id, "America/Vancouver", "date-time + Z + IANA annotation is the IANA time zone (string in property bag)"); +const result2 = Temporal.Now.zonedDateTime("iso8601", timeZone); +assert.sameValue(result2.timeZoneId, "America/Vancouver", "date-time + Z + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30-07:00[America/Vancouver]"; -const result5 = Temporal.Now.zonedDateTime("iso8601", timeZone); -assert.sameValue(result5.timeZone.id, "America/Vancouver", "date-time + offset + IANA annotation is the IANA time zone"); -const result6 = Temporal.Now.zonedDateTime("iso8601", { timeZone }); -assert.sameValue(result6.timeZone.id, "America/Vancouver", "date-time + offset + IANA annotation is the IANA time zone (string in property bag)"); +const result3 = Temporal.Now.zonedDateTime("iso8601", timeZone); +assert.sameValue(result3.timeZoneId, "America/Vancouver", "date-time + offset + IANA annotation is the IANA time zone"); diff --git a/JSTests/test262/test/intl402/Temporal/Now/zonedDateTimeISO/timezone-string-datetime.js b/JSTests/test262/test/intl402/Temporal/Now/zonedDateTimeISO/timezone-string-datetime.js index 4de19823d927..44a258664f07 100644 --- a/JSTests/test262/test/intl402/Temporal/Now/zonedDateTimeISO/timezone-string-datetime.js +++ b/JSTests/test262/test/intl402/Temporal/Now/zonedDateTimeISO/timezone-string-datetime.js @@ -3,24 +3,18 @@ /*--- esid: sec-temporal.now.zoneddatetimeiso -description: Conversion of ISO date-time strings to Temporal.TimeZone instances (with Intl time zones) +description: Conversion of ISO date-time strings to Temporal.TimeZone instances (with IANA time zones) features: [Temporal] ---*/ let timeZone = "2021-08-19T17:30[America/Vancouver]"; const result1 = Temporal.Now.zonedDateTimeISO(timeZone); -assert.sameValue(result1.timeZone.id, "America/Vancouver", "date-time + IANA annotation is the IANA time zone"); -const result2 = Temporal.Now.zonedDateTimeISO({ timeZone }); -assert.sameValue(result2.timeZone.id, "America/Vancouver", "date-time + IANA annotation is the IANA time zone (string in property bag)"); +assert.sameValue(result1.timeZoneId, "America/Vancouver", "date-time + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30Z[America/Vancouver]"; -const result3 = Temporal.Now.zonedDateTimeISO(timeZone); -assert.sameValue(result3.timeZone.id, "America/Vancouver", "date-time + Z + IANA annotation is the IANA time zone"); -const result4 = Temporal.Now.zonedDateTimeISO({ timeZone }); -assert.sameValue(result4.timeZone.id, "America/Vancouver", "date-time + Z + IANA annotation is the IANA time zone (string in property bag)"); +const result2 = Temporal.Now.zonedDateTimeISO(timeZone); +assert.sameValue(result2.timeZoneId, "America/Vancouver", "date-time + Z + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30-07:00[America/Vancouver]"; -const result5 = Temporal.Now.zonedDateTimeISO(timeZone); -assert.sameValue(result5.timeZone.id, "America/Vancouver", "date-time + offset + IANA annotation is the IANA time zone"); -const result6 = Temporal.Now.zonedDateTimeISO({ timeZone }); -assert.sameValue(result6.timeZone.id, "America/Vancouver", "date-time + offset + IANA annotation is the IANA time zone (string in property bag)"); +const result3 = Temporal.Now.zonedDateTimeISO(timeZone); +assert.sameValue(result3.timeZoneId, "America/Vancouver", "date-time + offset + IANA annotation is the IANA time zone"); diff --git a/JSTests/test262/test/intl402/Temporal/Now/zonedDateTimeISO/timezone-string.js b/JSTests/test262/test/intl402/Temporal/Now/zonedDateTimeISO/timezone-string.js index 2c458a80190a..79a59151e39d 100644 --- a/JSTests/test262/test/intl402/Temporal/Now/zonedDateTimeISO/timezone-string.js +++ b/JSTests/test262/test/intl402/Temporal/Now/zonedDateTimeISO/timezone-string.js @@ -9,7 +9,7 @@ features: [Temporal] const zdt = Temporal.Now.zonedDateTimeISO("America/Los_Angeles"); assert(zdt instanceof Temporal.ZonedDateTime); -assert(zdt.calendar instanceof Temporal.Calendar); -assert.sameValue(zdt.calendar.id, "iso8601"); -assert(zdt.timeZone instanceof Temporal.TimeZone); -assert.sameValue(zdt.timeZone.id, "America/Los_Angeles"); +assert.sameValue(typeof zdt.getISOFields().calendar, "string", "calendar slot should store a string"); +assert.sameValue(zdt.calendarId, "iso8601"); +assert.sameValue(typeof zdt.getISOFields().timeZone, "string", "time zone slot should store a string"); +assert.sameValue(zdt.timeZoneId, "America/Los_Angeles"); diff --git a/JSTests/test262/test/intl402/Temporal/PlainDate/prototype/toLocaleString/calendar-mismatch.js b/JSTests/test262/test/intl402/Temporal/PlainDate/prototype/toLocaleString/calendar-mismatch.js new file mode 100644 index 000000000000..acf971320ba2 --- /dev/null +++ b/JSTests/test262/test/intl402/Temporal/PlainDate/prototype/toLocaleString/calendar-mismatch.js @@ -0,0 +1,27 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.tolocalestring +description: Calendar must match the locale calendar if not "iso8601" +features: [Temporal, Intl-enumeration] +---*/ + +const localeCalendar = new Intl.DateTimeFormat().resolvedOptions().calendar; +assert.notSameValue(localeCalendar, "iso8601", "no locale has the ISO calendar"); + +const sameCalendarInstance = new Temporal.PlainDate(2000, 5, 2, localeCalendar); +const result = sameCalendarInstance.toLocaleString(); +assert.sameValue(typeof result, "string", "toLocaleString() succeeds when instance has the same calendar as locale"); + +const isoInstance = new Temporal.PlainDate(2000, 5, 2, "iso8601"); +assert.sameValue(isoInstance.toLocaleString(), result, "toLocaleString() succeeds when instance has the ISO calendar") + +// Pick a different calendar that is not ISO and not the locale's calendar +const calendars = new Set(Intl.supportedValuesOf("calendar")); +calendars.delete("iso8601"); +calendars.delete(localeCalendar); +const differentCalendar = calendars.values().next().value; + +const differentCalendarInstance = new Temporal.PlainDate(2000, 5, 2, differentCalendar); +assert.throws(RangeError, () => differentCalendarInstance.toLocaleString(), "calendar mismatch"); diff --git a/JSTests/test262/test/intl402/Temporal/PlainDate/prototype/toLocaleString/timezone-getoffsetnanosecondsfor-not-callable.js b/JSTests/test262/test/intl402/Temporal/PlainDate/prototype/toLocaleString/timezone-getoffsetnanosecondsfor-not-callable.js deleted file mode 100644 index fe76845955cd..000000000000 --- a/JSTests/test262/test/intl402/Temporal/PlainDate/prototype/toLocaleString/timezone-getoffsetnanosecondsfor-not-callable.js +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.plaindate.prototype.tolocalestring -description: TypeError thrown if timeZone.getOffsetNanosecondsFor is not callable -features: [BigInt, Symbol, Temporal, arrow-function] ----*/ - -const instance = new Temporal.PlainDate(2000, 5, 2); -Temporal.TimeZone.prototype.getPossibleInstantsFor = function () { - return []; -}; - -[undefined, null, true, Math.PI, 'string', Symbol('sym'), 42n, {}].forEach((notCallable) => { - Temporal.TimeZone.prototype.getOffsetNanosecondsFor = notCallable; - assert.throws( - TypeError, - () => instance.toLocaleString(), - `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError` - ); -}); diff --git a/JSTests/test262/test/intl402/Temporal/PlainDate/prototype/toZonedDateTime/timezone-string-datetime.js b/JSTests/test262/test/intl402/Temporal/PlainDate/prototype/toZonedDateTime/timezone-string-datetime.js index adc5b566e607..c64ab68f078f 100644 --- a/JSTests/test262/test/intl402/Temporal/PlainDate/prototype/toZonedDateTime/timezone-string-datetime.js +++ b/JSTests/test262/test/intl402/Temporal/PlainDate/prototype/toZonedDateTime/timezone-string-datetime.js @@ -3,7 +3,7 @@ /*--- esid: sec-temporal.plaindate.prototype.tozoneddatetime -description: Conversion of ISO date-time strings to Temporal.TimeZone instances (with Intl time zones) +description: Conversion of ISO date-time strings to Temporal.TimeZone instances (with IANA time zones) features: [Temporal] ---*/ @@ -11,18 +11,12 @@ const instance = new Temporal.PlainDate(2000, 5, 2); let timeZone = "2021-08-19T17:30[America/Vancouver]"; const result1 = instance.toZonedDateTime(timeZone); -assert.sameValue(result1.timeZone.id, "America/Vancouver", "date-time + IANA annotation is the IANA time zone"); -const result2 = instance.toZonedDateTime({ timeZone }); -assert.sameValue(result2.timeZone.id, "America/Vancouver", "date-time + IANA annotation is the IANA time zone (string in property bag)"); +assert.sameValue(result1.timeZoneId, "America/Vancouver", "date-time + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30Z[America/Vancouver]"; -const result3 = instance.toZonedDateTime(timeZone); -assert.sameValue(result3.timeZone.id, "America/Vancouver", "date-time + Z + IANA annotation is the IANA time zone"); -const result4 = instance.toZonedDateTime({ timeZone }); -assert.sameValue(result4.timeZone.id, "America/Vancouver", "date-time + Z + IANA annotation is the IANA time zone (string in property bag)"); +const result2 = instance.toZonedDateTime(timeZone); +assert.sameValue(result2.timeZoneId, "America/Vancouver", "date-time + Z + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30-07:00[America/Vancouver]"; -const result5 = instance.toZonedDateTime(timeZone); -assert.sameValue(result5.timeZone.id, "America/Vancouver", "date-time + offset + IANA annotation is the IANA time zone"); -const result6 = instance.toZonedDateTime({ timeZone }); -assert.sameValue(result6.timeZone.id, "America/Vancouver", "date-time + offset + IANA annotation is the IANA time zone (string in property bag)"); +const result3 = instance.toZonedDateTime(timeZone); +assert.sameValue(result3.timeZoneId, "America/Vancouver", "date-time + offset + IANA annotation is the IANA time zone"); diff --git a/JSTests/test262/test/intl402/Temporal/PlainDateTime/prototype/toLocaleString/calendar-mismatch.js b/JSTests/test262/test/intl402/Temporal/PlainDateTime/prototype/toLocaleString/calendar-mismatch.js new file mode 100644 index 000000000000..d57a32bcf39b --- /dev/null +++ b/JSTests/test262/test/intl402/Temporal/PlainDateTime/prototype/toLocaleString/calendar-mismatch.js @@ -0,0 +1,27 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.tolocalestring +description: Calendar must match the locale calendar if not "iso8601" +features: [Temporal, Intl-enumeration] +---*/ + +const localeCalendar = new Intl.DateTimeFormat().resolvedOptions().calendar; +assert.notSameValue(localeCalendar, "iso8601", "no locale has the ISO calendar"); + +const sameCalendarInstance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, localeCalendar); +const result = sameCalendarInstance.toLocaleString(); +assert.sameValue(typeof result, "string", "toLocaleString() succeeds when instance has the same calendar as locale"); + +const isoInstance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, "iso8601"); +assert.sameValue(isoInstance.toLocaleString(), result, "toLocaleString() succeeds when instance has the ISO calendar") + +// Pick a different calendar that is not ISO and not the locale's calendar +const calendars = new Set(Intl.supportedValuesOf("calendar")); +calendars.delete("iso8601"); +calendars.delete(localeCalendar); +const differentCalendar = calendars.values().next().value; + +const differentCalendarInstance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, differentCalendar); +assert.throws(RangeError, () => differentCalendarInstance.toLocaleString(), "calendar mismatch"); diff --git a/JSTests/test262/test/intl402/Temporal/PlainDateTime/prototype/toLocaleString/timezone-getoffsetnanosecondsfor-not-callable.js b/JSTests/test262/test/intl402/Temporal/PlainDateTime/prototype/toLocaleString/timezone-getoffsetnanosecondsfor-not-callable.js deleted file mode 100644 index 1d090307e42f..000000000000 --- a/JSTests/test262/test/intl402/Temporal/PlainDateTime/prototype/toLocaleString/timezone-getoffsetnanosecondsfor-not-callable.js +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.plaindatetime.prototype.tolocalestring -description: TypeError thrown if timeZone.getOffsetNanosecondsFor is not callable -features: [BigInt, Symbol, Temporal, arrow-function] ----*/ - -const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); -Temporal.TimeZone.prototype.getPossibleInstantsFor = function () { - return []; -}; - -[undefined, null, true, Math.PI, 'string', Symbol('sym'), 42n, {}].forEach((notCallable) => { - Temporal.TimeZone.prototype.getOffsetNanosecondsFor = notCallable; - assert.throws( - TypeError, - () => instance.toLocaleString(), - `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError` - ); -}); diff --git a/JSTests/test262/test/intl402/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-string-datetime.js b/JSTests/test262/test/intl402/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-string-datetime.js index f340aa7d341b..be582d082557 100644 --- a/JSTests/test262/test/intl402/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-string-datetime.js +++ b/JSTests/test262/test/intl402/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-string-datetime.js @@ -3,7 +3,7 @@ /*--- esid: sec-temporal.plaindatetime.prototype.tozoneddatetime -description: Conversion of ISO date-time strings to Temporal.TimeZone instances (with Intl time zones) +description: Conversion of ISO date-time strings to Temporal.TimeZone instances (with IANA time zones) features: [Temporal] ---*/ @@ -11,18 +11,12 @@ const instance = new Temporal.PlainDateTime(2000, 5, 2); let timeZone = "2021-08-19T17:30[America/Vancouver]"; const result1 = instance.toZonedDateTime(timeZone); -assert.sameValue(result1.timeZone.id, "America/Vancouver", "date-time + IANA annotation is the IANA time zone"); -const result2 = instance.toZonedDateTime({ timeZone }); -assert.sameValue(result2.timeZone.id, "America/Vancouver", "date-time + IANA annotation is the IANA time zone (string in property bag)"); +assert.sameValue(result1.timeZoneId, "America/Vancouver", "date-time + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30Z[America/Vancouver]"; -const result3 = instance.toZonedDateTime(timeZone); -assert.sameValue(result3.timeZone.id, "America/Vancouver", "date-time + Z + IANA annotation is the IANA time zone"); -const result4 = instance.toZonedDateTime({ timeZone }); -assert.sameValue(result4.timeZone.id, "America/Vancouver", "date-time + Z + IANA annotation is the IANA time zone (string in property bag)"); +const result2 = instance.toZonedDateTime(timeZone); +assert.sameValue(result2.timeZoneId, "America/Vancouver", "date-time + Z + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30-07:00[America/Vancouver]"; -const result5 = instance.toZonedDateTime(timeZone); -assert.sameValue(result5.timeZone.id, "America/Vancouver", "date-time + offset + IANA annotation is the IANA time zone"); -const result6 = instance.toZonedDateTime({ timeZone }); -assert.sameValue(result6.timeZone.id, "America/Vancouver", "date-time + offset + IANA annotation is the IANA time zone (string in property bag)"); +const result3 = instance.toZonedDateTime(timeZone); +assert.sameValue(result3.timeZoneId, "America/Vancouver", "date-time + offset + IANA annotation is the IANA time zone"); diff --git a/JSTests/test262/test/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-noniso.js b/JSTests/test262/test/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-noniso.js index 118282b48dec..5015812037b9 100644 --- a/JSTests/test262/test/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-noniso.js +++ b/JSTests/test262/test/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-noniso.js @@ -16,10 +16,26 @@ const cal = { year() { return 2008; }, month() { return 9; }, monthCode() { return "M09"; }, - day() { return 6; } + day() { return 6; }, + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, }; const pdt = new Temporal.PlainDateTime(1995, 12, 7, 3, 24, 30, 0, 0, 0); -assert.sameValue(pdt.calendar.toString(), "iso8601", "PlainDateTime with ISO calendar"); +assert.sameValue(pdt.calendarId, "iso8601", "PlainDateTime with ISO calendar"); const pd = new Temporal.PlainDate(2010, 11, 12, cal); const shifted = pdt.withPlainDate(pd); @@ -32,7 +48,7 @@ TemporalHelpers.assertPlainDateTime( ); assert.sameValue( - shifted.calendar, + shifted.getCalendar(), cal, "calendar is changed if receiver has ISO calendar (2)" ); diff --git a/JSTests/test262/test/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-same-id.js b/JSTests/test262/test/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-same-id.js index 284990598159..25a2124c78b8 100644 --- a/JSTests/test262/test/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-same-id.js +++ b/JSTests/test262/test/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-same-id.js @@ -9,17 +9,54 @@ includes: [temporalHelpers.js] ---*/ const cal1 = { - toString() { return "this is a string"; }, + id: "this is a string", + toString() { return "this is a another string"; }, + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, }; const cal2 = { - id: 'thisisnotiso', + id: "this is a string", era() { return "the era"; }, eraYear() { return 1909; }, - toString() { return "this is a string"; }, + toString() { return "thisisnotiso"; }, year() { return 2008; }, month() { return 9; }, monthCode() { return "M09"; }, - day() { return 6; } + day() { return 6; }, + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, }; const pdt = new Temporal.PlainDateTime(1995, 12, 7, 3, 24, 30, 0, 0, 0, cal1); const pd = new Temporal.PlainDate(2010, 11, 12, cal2); @@ -34,7 +71,7 @@ TemporalHelpers.assertPlainDateTime( ); assert.sameValue( - shifted.calendar, + shifted.getCalendar(), cal2, "calendar is changed with same id (2)" ); diff --git a/JSTests/test262/test/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-same-object.js b/JSTests/test262/test/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-same-object.js index f963a3b61d2a..c69d3e487bd2 100644 --- a/JSTests/test262/test/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-same-object.js +++ b/JSTests/test262/test/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-same-object.js @@ -10,7 +10,10 @@ includes: [temporalHelpers.js] let calls = 0; const cal = { - id: 'thisisnotiso', + get id() { + ++calls; + return "thisisnotiso"; + }, era() { return "the era"; }, eraYear() { return 1909; }, toString() { @@ -20,7 +23,23 @@ const cal = { year() { return 2008; }, month() { return 9; }, monthCode() { return "M09"; }, - day() { return 6; } + day() { return 6; }, + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, }; const pdt = new Temporal.PlainDateTime(1995, 12, 7, 3, 24, 30, 0, 0, 0, cal); const pd = new Temporal.PlainDate(2010, 11, 12, cal); @@ -35,8 +54,8 @@ TemporalHelpers.assertPlainDateTime( ); assert.sameValue( - shifted.calendar, + shifted.getCalendar(), cal, "calendar is unchanged with same calendars (2)" ); -assert.sameValue(calls, 0, "should not have called cal.toString()"); +assert.sameValue(calls, 0, "should not have called cal.toString() or accessed cal.id"); diff --git a/JSTests/test262/test/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar.js b/JSTests/test262/test/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar.js index ad9f56f7bb4f..3c5e6615717d 100644 --- a/JSTests/test262/test/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar.js +++ b/JSTests/test262/test/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar.js @@ -16,11 +16,27 @@ const cal = { year() { return 2008; }, month() { return 9; }, monthCode() { return "M09"; }, - day() { return 6; } + day() { return 6; }, + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, }; const pdt = new Temporal.PlainDateTime(1995, 12, 7, 3, 24, 30, 0, 0, 0, cal); const pd = new Temporal.PlainDate(2010, 11, 12); -assert.sameValue(pd.calendar.toString(), "iso8601", "PlainDate with ISO calendar"); +assert.sameValue(pd.calendarId, "iso8601", "PlainDate with ISO calendar"); const shifted = pdt.withPlainDate(pd); TemporalHelpers.assertPlainDateTime( @@ -32,7 +48,7 @@ TemporalHelpers.assertPlainDateTime( ); assert.sameValue( - shifted.calendar, + shifted.getCalendar(), cal, "calendar is unchanged if input has ISO calendar (2)" ); diff --git a/JSTests/test262/test/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-string-calendar.js b/JSTests/test262/test/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-string-calendar.js index 2065751f7191..d749f18012cd 100644 --- a/JSTests/test262/test/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-string-calendar.js +++ b/JSTests/test262/test/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-string-calendar.js @@ -14,12 +14,12 @@ const gregorypdt = new Temporal.PlainDateTime(1995, 12, 7, 3, 24, 30, 123, 456, const result1 = isopdt.withPlainDate("2020-11-13[u-ca=gregory]"); TemporalHelpers.assertPlainDateTime(result1, 2020, 11, "M11", 13, 3, 24, 30, 123, 456, 789, "result1", "ce", 2020); -assert.sameValue(result1.calendar.toString(), "gregory", "non-ISO calendar in argument overrides ISO calendar in receiver"); +assert.sameValue(result1.calendarId, "gregory", "non-ISO calendar in argument overrides ISO calendar in receiver"); const result2 = gregorypdt.withPlainDate("2020-11-13[u-ca=iso8601]"); TemporalHelpers.assertPlainDateTime(result2, 2020, 11, "M11", 13, 3, 24, 30, 123, 456, 789, "result2", "ce", 2020); -assert.sameValue(result2.calendar.toString(), "gregory", "non-ISO calendar in receiver overrides ISO calendar in argument"); +assert.sameValue(result2.calendarId, "gregory", "non-ISO calendar in receiver overrides ISO calendar in argument"); assert.throws(RangeError, () => gregorypdt.withPlainDate("2020-11-13[u-ca=japanese]"), "throws if both `this` and `other` have a non-ISO calendar"); diff --git a/JSTests/test262/test/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-string-iso-calendar.js b/JSTests/test262/test/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-string-iso-calendar.js index d86925d1b80a..a23fb83aa3b6 100644 --- a/JSTests/test262/test/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-string-iso-calendar.js +++ b/JSTests/test262/test/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-string-iso-calendar.js @@ -16,7 +16,23 @@ const cal = { year() { return 2008; }, month() { return 9; }, monthCode() { return "M09"; }, - day() { return 6; } + day() { return 6; }, + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + inLeapYear() {}, + mergeFields() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, }; const dt = new Temporal.PlainDateTime(1995, 12, 7, 3, 24, 30, 0, 0, 0, cal); const shifted = dt.withPlainDate("2010-11-12"); @@ -30,7 +46,7 @@ TemporalHelpers.assertPlainDateTime( ); assert.sameValue( - shifted.calendar, + shifted.getCalendar(), cal, "calendar is unchanged if input has ISO calendar (2)" ); diff --git a/JSTests/test262/test/intl402/Temporal/PlainMonthDay/from/reference-date-noniso-calendar.js b/JSTests/test262/test/intl402/Temporal/PlainMonthDay/from/reference-date-noniso-calendar.js new file mode 100644 index 000000000000..e13691bb2b6a --- /dev/null +++ b/JSTests/test262/test/intl402/Temporal/PlainMonthDay/from/reference-date-noniso-calendar.js @@ -0,0 +1,17 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday.from +description: Verify that the result of ToTemporalMonthDay preserves year information for Non-ISO calendars. +info: | + sec-temporal.plainmonthday.from step 3: + 3. Return ? ToTemporalMonthDay(_item_, _options_). + sec-temporal-totemporalmonthday step 11.: + 11. Set result to ? CreateTemporalMonthDay(_result_.[[Month]], _result_.[[Day]], _calendar_, _result_.[[Year]]). +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const pmd = Temporal.PlainMonthDay.from("2023-01-01[u-ca=hebrew]") +TemporalHelpers.assertPlainMonthDay(pmd, "M04", 8); // 2023-01-01 corresponds to 8 Tevet in Hebrew Calendar. diff --git a/JSTests/test262/test/intl402/Temporal/PlainMonthDay/prototype/toLocaleString/calendar-mismatch.js b/JSTests/test262/test/intl402/Temporal/PlainMonthDay/prototype/toLocaleString/calendar-mismatch.js new file mode 100644 index 000000000000..40de8ba551ec --- /dev/null +++ b/JSTests/test262/test/intl402/Temporal/PlainMonthDay/prototype/toLocaleString/calendar-mismatch.js @@ -0,0 +1,27 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday.prototype.tolocalestring +description: Calendar must match the locale calendar if not "iso8601" +features: [Temporal, Intl-enumeration] +---*/ + +const localeCalendar = new Intl.DateTimeFormat().resolvedOptions().calendar; +assert.notSameValue(localeCalendar, "iso8601", "no locale has the ISO calendar"); + +const sameCalendarInstance = Temporal.PlainMonthDay.from({ monthCode: "M01", day: 1, calendar: localeCalendar }); +const result = sameCalendarInstance.toLocaleString(); +assert.sameValue(typeof result, "string", "toLocaleString() succeeds when instance has the same calendar as locale"); + +// Pick a different calendar that is not ISO and not the locale's calendar +const calendars = new Set(Intl.supportedValuesOf("calendar")); +calendars.delete("iso8601"); +calendars.delete(localeCalendar); +const differentCalendar = calendars.values().next().value; + +const differentCalendarInstance = Temporal.PlainMonthDay.from({ monthCode: "M01", day: 1, calendar: differentCalendar }); +assert.throws(RangeError, () => differentCalendarInstance.toLocaleString(), "calendar mismatch"); + +const isoInstance = Temporal.PlainMonthDay.from({ monthCode: "M01", day: 1, calendar: "iso8601" }); +assert.throws(RangeError, () => isoInstance.toLocaleString(), "calendar mismatch even when instance has the ISO calendar") diff --git a/JSTests/test262/test/intl402/Temporal/PlainMonthDay/prototype/toLocaleString/timezone-getoffsetnanosecondsfor-not-callable.js b/JSTests/test262/test/intl402/Temporal/PlainMonthDay/prototype/toLocaleString/timezone-getoffsetnanosecondsfor-not-callable.js deleted file mode 100644 index 73dfc26b9d68..000000000000 --- a/JSTests/test262/test/intl402/Temporal/PlainMonthDay/prototype/toLocaleString/timezone-getoffsetnanosecondsfor-not-callable.js +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.plainmonthday.prototype.tolocalestring -description: TypeError thrown if timeZone.getOffsetNanosecondsFor is not callable -features: [BigInt, Symbol, Temporal, arrow-function] ----*/ - -const instance = new Temporal.PlainMonthDay(5, 2); -Temporal.TimeZone.prototype.getPossibleInstantsFor = function () { - return []; -}; - -[undefined, null, true, Math.PI, 'string', Symbol('sym'), 42n, {}].forEach((notCallable) => { - Temporal.TimeZone.prototype.getOffsetNanosecondsFor = notCallable; - assert.throws( - TypeError, - () => instance.toLocaleString(undefined, { calendar: "iso8601" }), - `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError` - ); -}); diff --git a/JSTests/test262/test/intl402/Temporal/PlainTime/prototype/toLocaleString/timezone-getoffsetnanosecondsfor-not-callable.js b/JSTests/test262/test/intl402/Temporal/PlainTime/prototype/toLocaleString/timezone-getoffsetnanosecondsfor-not-callable.js deleted file mode 100644 index 0abec4a9c812..000000000000 --- a/JSTests/test262/test/intl402/Temporal/PlainTime/prototype/toLocaleString/timezone-getoffsetnanosecondsfor-not-callable.js +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.plaintime.prototype.tolocalestring -description: TypeError thrown if timeZone.getOffsetNanosecondsFor is not callable -features: [BigInt, Symbol, Temporal, arrow-function] ----*/ - -const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); -Temporal.TimeZone.prototype.getPossibleInstantsFor = function () { - return []; -}; - -[undefined, null, true, Math.PI, 'string', Symbol('sym'), 42n, {}].forEach((notCallable) => { - Temporal.TimeZone.prototype.getOffsetNanosecondsFor = notCallable; - assert.throws( - TypeError, - () => instance.toLocaleString(), - `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError` - ); -}); diff --git a/JSTests/test262/test/intl402/Temporal/PlainTime/prototype/toZonedDateTime/timezone-string-datetime.js b/JSTests/test262/test/intl402/Temporal/PlainTime/prototype/toZonedDateTime/timezone-string-datetime.js index 77ce858e95eb..6aa2ebf8ca67 100644 --- a/JSTests/test262/test/intl402/Temporal/PlainTime/prototype/toZonedDateTime/timezone-string-datetime.js +++ b/JSTests/test262/test/intl402/Temporal/PlainTime/prototype/toZonedDateTime/timezone-string-datetime.js @@ -3,7 +3,7 @@ /*--- esid: sec-temporal.plaintime.prototype.tozoneddatetime -description: Conversion of ISO date-time strings to Temporal.TimeZone instances (with Intl time zones) +description: Conversion of ISO date-time strings to Temporal.TimeZone instances (with IANA time zones) features: [Temporal] ---*/ @@ -11,18 +11,12 @@ const instance = new Temporal.PlainTime(); let timeZone = "2021-08-19T17:30[America/Vancouver]"; const result1 = instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone }); -assert.sameValue(result1.timeZone.id, "America/Vancouver", "date-time + IANA annotation is the IANA time zone"); -const result2 = instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone: { timeZone } }); -assert.sameValue(result2.timeZone.id, "America/Vancouver", "date-time + IANA annotation is the IANA time zone (string in property bag)"); +assert.sameValue(result1.timeZoneId, "America/Vancouver", "date-time + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30Z[America/Vancouver]"; -const result3 = instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone }); -assert.sameValue(result3.timeZone.id, "America/Vancouver", "date-time + Z + IANA annotation is the IANA time zone"); -const result4 = instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone: { timeZone } }); -assert.sameValue(result4.timeZone.id, "America/Vancouver", "date-time + Z + IANA annotation is the IANA time zone (string in property bag)"); +const result2 = instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone }); +assert.sameValue(result2.timeZoneId, "America/Vancouver", "date-time + Z + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30-07:00[America/Vancouver]"; -const result5 = instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone }); -assert.sameValue(result5.timeZone.id, "America/Vancouver", "date-time + offset + IANA annotation is the IANA time zone"); -const result6 = instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone: { timeZone } }); -assert.sameValue(result6.timeZone.id, "America/Vancouver", "date-time + offset + IANA annotation is the IANA time zone (string in property bag)"); +const result3 = instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone }); +assert.sameValue(result3.timeZoneId, "America/Vancouver", "date-time + offset + IANA annotation is the IANA time zone"); diff --git a/JSTests/test262/test/intl402/Temporal/PlainYearMonth/prototype/toLocaleString/calendar-mismatch.js b/JSTests/test262/test/intl402/Temporal/PlainYearMonth/prototype/toLocaleString/calendar-mismatch.js new file mode 100644 index 000000000000..6785efd36254 --- /dev/null +++ b/JSTests/test262/test/intl402/Temporal/PlainYearMonth/prototype/toLocaleString/calendar-mismatch.js @@ -0,0 +1,27 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.tolocalestring +description: Calendar must match the locale calendar +features: [Temporal, Intl-enumeration] +---*/ + +const localeCalendar = new Intl.DateTimeFormat().resolvedOptions().calendar; +assert.notSameValue(localeCalendar, "iso8601", "no locale has the ISO calendar"); + +const sameCalendarInstance = new Temporal.PlainDate(2000, 1, 1, localeCalendar).toPlainYearMonth(); +const result = sameCalendarInstance.toLocaleString(); +assert.sameValue(typeof result, "string", "toLocaleString() succeeds when instance has the same calendar as locale"); + +// Pick a different calendar that is not ISO and not the locale's calendar +const calendars = new Set(Intl.supportedValuesOf("calendar")); +calendars.delete("iso8601"); +calendars.delete(localeCalendar); +const differentCalendar = calendars.values().next().value; + +const differentCalendarInstance = new Temporal.PlainDate(2000, 1, 1, differentCalendar).toPlainYearMonth(); +assert.throws(RangeError, () => differentCalendarInstance.toLocaleString(), "calendar mismatch"); + +const isoInstance = new Temporal.PlainDate(2000, 1, 1, "iso8601").toPlainYearMonth(); +assert.throws(RangeError, () => isoInstance.toLocaleString(), "calendar mismatch even when instance has the ISO calendar") diff --git a/JSTests/test262/test/intl402/Temporal/PlainYearMonth/prototype/toLocaleString/timezone-getoffsetnanosecondsfor-not-callable.js b/JSTests/test262/test/intl402/Temporal/PlainYearMonth/prototype/toLocaleString/timezone-getoffsetnanosecondsfor-not-callable.js deleted file mode 100644 index 4cbde6696168..000000000000 --- a/JSTests/test262/test/intl402/Temporal/PlainYearMonth/prototype/toLocaleString/timezone-getoffsetnanosecondsfor-not-callable.js +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.plainyearmonth.prototype.tolocalestring -description: TypeError thrown if timeZone.getOffsetNanosecondsFor is not callable -features: [BigInt, Symbol, Temporal, arrow-function] ----*/ - -const instance = new Temporal.PlainYearMonth(2000, 5); -Temporal.TimeZone.prototype.getPossibleInstantsFor = function () { - return []; -}; - -[undefined, null, true, Math.PI, 'string', Symbol('sym'), 42n, {}].forEach((notCallable) => { - Temporal.TimeZone.prototype.getOffsetNanosecondsFor = notCallable; - assert.throws( - TypeError, - () => instance.toLocaleString(undefined, { calendar: "iso8601" }), - `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError` - ); -}); diff --git a/JSTests/test262/test/intl402/Temporal/TimeZone/from/argument-object.js b/JSTests/test262/test/intl402/Temporal/TimeZone/from/argument-object.js index 7991c341bda7..235c25f285b5 100644 --- a/JSTests/test262/test/intl402/Temporal/TimeZone/from/argument-object.js +++ b/JSTests/test262/test/intl402/Temporal/TimeZone/from/argument-object.js @@ -31,15 +31,6 @@ for (const thisValue of thisValues) { const zdt = new Temporal.ZonedDateTime(0n, "Africa/Cairo"); const fromZdt = Temporal.TimeZone.from.call(thisValue, zdt); - assert.sameValue(fromZdt, zdt.timeZone); + assert.notSameValue(fromZdt, zdt.getTimeZone(), "from() creates a new object for a string slot value"); assert.sameValue(fromZdt.id, "Africa/Cairo"); - - const tz = new Temporal.TimeZone("Africa/Cairo"); - const fromPropertyBagObject = Temporal.TimeZone.from.call(thisValue, { timeZone: tz }); - assert.sameValue(fromPropertyBagObject, tz); - assert.sameValue(fromPropertyBagObject.id, "Africa/Cairo"); - - const fromPropertyBagString = Temporal.TimeZone.from.call(thisValue, { timeZone: "Africa/Cairo" }); - assert(fromPropertyBagString instanceof Temporal.TimeZone); - assert.sameValue(fromPropertyBagString.id, "Africa/Cairo"); } diff --git a/JSTests/test262/test/intl402/Temporal/TimeZone/from/timezone-string-datetime.js b/JSTests/test262/test/intl402/Temporal/TimeZone/from/timezone-string-datetime.js index 579e79c4c1c0..64ba3e649cae 100644 --- a/JSTests/test262/test/intl402/Temporal/TimeZone/from/timezone-string-datetime.js +++ b/JSTests/test262/test/intl402/Temporal/TimeZone/from/timezone-string-datetime.js @@ -3,24 +3,18 @@ /*--- esid: sec-temporal.timezone.from -description: Conversion of ISO date-time strings to Temporal.TimeZone instances (with Intl time zones) +description: Conversion of ISO date-time strings to Temporal.TimeZone instances (with IANA time zones) features: [Temporal] ---*/ let timeZone = "2021-08-19T17:30[America/Vancouver]"; const result1 = Temporal.TimeZone.from(timeZone); assert.sameValue(result1.id, "America/Vancouver", "date-time + IANA annotation is the IANA time zone"); -const result2 = Temporal.TimeZone.from({ timeZone }); -assert.sameValue(result2.id, "America/Vancouver", "date-time + IANA annotation is the IANA time zone (string in property bag)"); timeZone = "2021-08-19T17:30Z[America/Vancouver]"; -const result3 = Temporal.TimeZone.from(timeZone); -assert.sameValue(result3.id, "America/Vancouver", "date-time + Z + IANA annotation is the IANA time zone"); -const result4 = Temporal.TimeZone.from({ timeZone }); -assert.sameValue(result4.id, "America/Vancouver", "date-time + Z + IANA annotation is the IANA time zone (string in property bag)"); +const result2 = Temporal.TimeZone.from(timeZone); +assert.sameValue(result2.id, "America/Vancouver", "date-time + Z + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30-07:00[America/Vancouver]"; -const result5 = Temporal.TimeZone.from(timeZone); -assert.sameValue(result5.id, "America/Vancouver", "date-time + offset + IANA annotation is the IANA time zone"); -const result6 = Temporal.TimeZone.from({ timeZone }); -assert.sameValue(result6.id, "America/Vancouver", "date-time + offset + IANA annotation is the IANA time zone (string in property bag)"); +const result3 = Temporal.TimeZone.from(timeZone); +assert.sameValue(result3.id, "America/Vancouver", "date-time + offset + IANA annotation is the IANA time zone"); diff --git a/JSTests/test262/test/intl402/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/nanoseconds-subtracted-or-added-at-dst-transition.js b/JSTests/test262/test/intl402/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/nanoseconds-subtracted-or-added-at-dst-transition.js index 422b170d3efa..268924e79e25 100644 --- a/JSTests/test262/test/intl402/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/nanoseconds-subtracted-or-added-at-dst-transition.js +++ b/JSTests/test262/test/intl402/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/nanoseconds-subtracted-or-added-at-dst-transition.js @@ -5,7 +5,7 @@ esid: sec-temporal.timezone.prototype.getoffsetnanosecondsfor description: > Test offset when nanoseconds are subtracted or added from DST transition. -features: [Temporal] +features: [Temporal, exponentiation] ---*/ // From : diff --git a/JSTests/test262/test/intl402/Temporal/ZonedDateTime/compare/argument-propertybag-timezone-string-datetime.js b/JSTests/test262/test/intl402/Temporal/ZonedDateTime/compare/argument-propertybag-timezone-string-datetime.js new file mode 100644 index 000000000000..149d83fae643 --- /dev/null +++ b/JSTests/test262/test/intl402/Temporal/ZonedDateTime/compare/argument-propertybag-timezone-string-datetime.js @@ -0,0 +1,28 @@ +// 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: Conversion of ISO date-time strings to Temporal.TimeZone instances (with IANA time zones) +features: [Temporal] +---*/ + +const instance = new Temporal.ZonedDateTime(1588402800_000_000_000n, "America/Vancouver") + +let timeZone = "2021-08-19T17:30[America/Vancouver]"; +const result1 = Temporal.ZonedDateTime.compare({ year: 2020, month: 5, day: 2, timeZone }, instance); +assert.sameValue(result1, 0, "date-time + IANA annotation is the IANA time zone (first argument)"); +const result2 = Temporal.ZonedDateTime.compare(instance, { year: 2020, month: 5, day: 2, timeZone }); +assert.sameValue(result1, 0, "date-time + IANA annotation is the IANA time zone (second argument)"); + +timeZone = "2021-08-19T17:30Z[America/Vancouver]"; +const result3 = Temporal.ZonedDateTime.compare({ year: 2020, month: 5, day: 2, timeZone }, instance); +assert.sameValue(result3, 0, "date-time + Z + IANA annotation is the IANA time zone (first argument)"); +const result4 = Temporal.ZonedDateTime.compare(instance, { year: 2020, month: 5, day: 2, timeZone }); +assert.sameValue(result4, 0, "date-time + Z + IANA annotation is the IANA time zone (second argument)"); + +timeZone = "2021-08-19T17:30-07:00[America/Vancouver]"; +const result5 = Temporal.ZonedDateTime.compare({ year: 2020, month: 5, day: 2, timeZone }, instance); +assert.sameValue(result5, 0, "date-time + offset + IANA annotation is the IANA time zone (first argument)"); +const result6 = Temporal.ZonedDateTime.compare(instance, { year: 2020, month: 5, day: 2, timeZone }); +assert.sameValue(result6, 0, "date-time + offset + IANA annotation is the IANA time zone (second argument)"); diff --git a/JSTests/test262/test/intl402/Temporal/ZonedDateTime/from/argument-propertybag-timezone-string-datetime.js b/JSTests/test262/test/intl402/Temporal/ZonedDateTime/from/argument-propertybag-timezone-string-datetime.js index 55738d2f2ed3..bca3f64ab7fe 100644 --- a/JSTests/test262/test/intl402/Temporal/ZonedDateTime/from/argument-propertybag-timezone-string-datetime.js +++ b/JSTests/test262/test/intl402/Temporal/ZonedDateTime/from/argument-propertybag-timezone-string-datetime.js @@ -3,24 +3,18 @@ /*--- esid: sec-temporal.zoneddatetime.from -description: Conversion of ISO date-time strings to Temporal.TimeZone instances (with Intl time zones) +description: Conversion of ISO date-time strings to Temporal.TimeZone instances (with IANA time zones) features: [Temporal] ---*/ let timeZone = "2021-08-19T17:30[America/Vancouver]"; const result1 = Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone }); -assert.sameValue(result1.timeZone.id, "America/Vancouver", "date-time + IANA annotation is the IANA time zone"); -const result2 = Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone: { timeZone } }); -assert.sameValue(result2.timeZone.id, "America/Vancouver", "date-time + IANA annotation is the IANA time zone (string in property bag)"); +assert.sameValue(result1.timeZoneId, "America/Vancouver", "date-time + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30Z[America/Vancouver]"; -const result3 = Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone }); -assert.sameValue(result3.timeZone.id, "America/Vancouver", "date-time + Z + IANA annotation is the IANA time zone"); -const result4 = Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone: { timeZone } }); -assert.sameValue(result4.timeZone.id, "America/Vancouver", "date-time + Z + IANA annotation is the IANA time zone (string in property bag)"); +const result2 = Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone }); +assert.sameValue(result2.timeZoneId, "America/Vancouver", "date-time + Z + IANA annotation is the IANA time zone"); timeZone = "2021-08-19T17:30-07:00[America/Vancouver]"; -const result5 = Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone }); -assert.sameValue(result5.timeZone.id, "America/Vancouver", "date-time + offset + IANA annotation is the IANA time zone"); -const result6 = Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone: { timeZone } }); -assert.sameValue(result6.timeZone.id, "America/Vancouver", "date-time + offset + IANA annotation is the IANA time zone (string in property bag)"); +const result3 = Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone }); +assert.sameValue(result3.timeZoneId, "America/Vancouver", "date-time + offset + IANA annotation is the IANA time zone"); diff --git a/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-string-datetime.js b/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-string-datetime.js index fa4b61c7762d..1869a17b06a2 100644 --- a/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-string-datetime.js +++ b/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-string-datetime.js @@ -3,7 +3,7 @@ /*--- esid: sec-temporal.zoneddatetime.prototype.equals -description: Conversion of ISO date-time strings to Temporal.TimeZone instances (with Intl time zones) +description: Conversion of ISO date-time strings to Temporal.TimeZone instances (with IANA time zones) features: [Temporal] ---*/ @@ -11,12 +11,9 @@ const expectedTimeZone = "America/Vancouver"; const instance = new Temporal.ZonedDateTime(0n, expectedTimeZone); let timeZone = "2021-08-19T17:30[America/Vancouver]"; assert(instance.equals({ year: 1969, month: 12, day: 31, hour: 16, timeZone }), "date-time + IANA annotation is the IANA time zone"); -assert(instance.equals({ year: 1969, month: 12, day: 31, hour: 16, timeZone: { timeZone } }), "date-time + IANA annotation is the IANA time zone (string in property bag)"); timeZone = "2021-08-19T17:30Z[America/Vancouver]"; assert(instance.equals({ year: 1969, month: 12, day: 31, hour: 16, timeZone }), "date-time + Z + IANA annotation is the IANA time zone"); -assert(instance.equals({ year: 1969, month: 12, day: 31, hour: 16, timeZone: { timeZone } }), "date-time + Z + IANA annotation is the IANA time zone (string in property bag)"); timeZone = "2021-08-19T17:30-07:00[America/Vancouver]"; assert(instance.equals({ year: 1969, month: 12, day: 31, hour: 16, timeZone }), "date-time + offset + IANA annotation is the IANA time zone"); -assert(instance.equals({ year: 1969, month: 12, day: 31, hour: 16, timeZone: { timeZone } }), "date-time + offset + IANA annotation is the IANA time zone (string in property bag)"); diff --git a/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-string-datetime.js b/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-string-datetime.js index 474e8b3b299d..9b2bfe7f7968 100644 --- a/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-string-datetime.js +++ b/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-string-datetime.js @@ -3,7 +3,7 @@ /*--- esid: sec-temporal.zoneddatetime.prototype.since -description: Conversion of ISO date-time strings to Temporal.TimeZone instances (with Intl time zones) +description: Conversion of ISO date-time strings to Temporal.TimeZone instances (with IANA time zones) features: [Temporal] ---*/ @@ -11,12 +11,9 @@ const expectedTimeZone = "America/Vancouver"; const instance = new Temporal.ZonedDateTime(0n, expectedTimeZone); let timeZone = "2021-08-19T17:30[America/Vancouver]"; instance.since({ year: 2020, month: 5, day: 2, timeZone }); -instance.since({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }); timeZone = "2021-08-19T17:30Z[America/Vancouver]"; instance.since({ year: 2020, month: 5, day: 2, timeZone }); -instance.since({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }); timeZone = "2021-08-19T17:30-07:00[America/Vancouver]"; instance.since({ year: 2020, month: 5, day: 2, timeZone }); -instance.since({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }); diff --git a/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/toLocaleString/calendar-mismatch.js b/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/toLocaleString/calendar-mismatch.js new file mode 100644 index 000000000000..1cb43bb4a238 --- /dev/null +++ b/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/toLocaleString/calendar-mismatch.js @@ -0,0 +1,27 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.tolocalestring +description: Calendar must match the locale calendar if not "iso8601" +features: [Temporal, Intl-enumeration] +---*/ + +const localeCalendar = new Intl.DateTimeFormat().resolvedOptions().calendar; +assert.notSameValue(localeCalendar, "iso8601", "no locale has the ISO calendar"); + +const sameCalendarInstance = new Temporal.ZonedDateTime(0n, "UTC", localeCalendar); +const result = sameCalendarInstance.toLocaleString(); +assert.sameValue(typeof result, "string", "toLocaleString() succeeds when instance has the same calendar as locale"); + +const isoInstance = new Temporal.ZonedDateTime(0n, "UTC", "iso8601"); +assert.sameValue(isoInstance.toLocaleString(), result, "toLocaleString() succeeds when instance has the ISO calendar") + +// Pick a different calendar that is not ISO and not the locale's calendar +const calendars = new Set(Intl.supportedValuesOf("calendar")); +calendars.delete("iso8601"); +calendars.delete(localeCalendar); +const differentCalendar = calendars.values().next().value; + +const differentCalendarInstance = new Temporal.ZonedDateTime(0n, "UTC", differentCalendar); +assert.throws(RangeError, () => differentCalendarInstance.toLocaleString(), "calendar mismatch"); diff --git a/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/toLocaleString/custom-time-zone-name-not-supported.js b/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/toLocaleString/custom-time-zone-name-not-supported.js new file mode 100644 index 000000000000..6c34b4b14bad --- /dev/null +++ b/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/toLocaleString/custom-time-zone-name-not-supported.js @@ -0,0 +1,17 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.tolocalestring +description: > + Custom time zones with unofficial names are not supported for locale formatting +features: [Temporal] +---*/ + +const timeZone = { + id: "Etc/Custom_Zone", + getPossibleInstantsFor() {}, + getOffsetNanosecondsFor() {}, +}; +const datetime = new Temporal.ZonedDateTime(0n, timeZone); +assert.throws(RangeError, () => datetime.toLocaleString(), "Custom time zones with non-IANA identifiers not supported in Intl"); diff --git a/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/toLocaleString/locales-undefined.js b/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/toLocaleString/locales-undefined.js index 8ed6549fdff4..560f8bd3e7a5 100644 --- a/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/toLocaleString/locales-undefined.js +++ b/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/toLocaleString/locales-undefined.js @@ -8,8 +8,17 @@ features: [BigInt, Temporal] ---*/ const datetime = new Temporal.ZonedDateTime(957270896_987_650_000n, "UTC"); -const defaultFormatter = new Intl.DateTimeFormat([], Object.create(null)); -const expected = defaultFormatter.format(datetime); +const defaultFormatter = new Intl.DateTimeFormat([], { + year: "numeric", + month: "numeric", + day: "numeric", + hour: "numeric", + minute: "numeric", + second: "numeric", + timeZoneName: "short", + timeZone: "UTC", +}); +const expected = defaultFormatter.format(datetime.toInstant()); const actualExplicit = datetime.toLocaleString(undefined); assert.sameValue(actualExplicit, expected, "default locale is determined by Intl.DateTimeFormat"); diff --git a/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/toLocaleString/offset-time-zone-not-supported.js b/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/toLocaleString/offset-time-zone-not-supported.js new file mode 100644 index 000000000000..032019140d03 --- /dev/null +++ b/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/toLocaleString/offset-time-zone-not-supported.js @@ -0,0 +1,11 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.tolocalestring +description: Offset time zones are not supported yet by Intl +features: [Temporal] +---*/ + +const datetime = new Temporal.ZonedDateTime(0n, "+00:00"); +assert.throws(RangeError, () => datetime.toLocaleString(), "Intl.DateTimeFormat does not yet specify what to do with offset time zones"); diff --git a/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/toLocaleString/options-timeZone.js b/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/toLocaleString/options-timeZone.js new file mode 100644 index 000000000000..76dde5ae3673 --- /dev/null +++ b/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/toLocaleString/options-timeZone.js @@ -0,0 +1,15 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.tolocalestring +description: > + Options must not have a timeZone property, even if it agrees with the + instance's time zone +features: [Temporal] +---*/ + +const datetime = new Temporal.ZonedDateTime(0n, "UTC"); + +assert.throws(TypeError, () => datetime.toLocaleString("en-US", { timeZone: "Europe/Vienna" }), "timeZone option disallowed"); +assert.throws(TypeError, () => datetime.toLocaleString("en-US", { timeZone: "UTC" }), "timeZone option disallowed even if it agrees with instance's time zone"); diff --git a/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/toLocaleString/options-timeZoneName-affects-instance-time-zone.js b/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/toLocaleString/options-timeZoneName-affects-instance-time-zone.js new file mode 100644 index 000000000000..27cf3ba26ff3 --- /dev/null +++ b/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/toLocaleString/options-timeZoneName-affects-instance-time-zone.js @@ -0,0 +1,16 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.tolocalestring +description: timeZoneName option affects formatting of the instance's time zone +locale: [en-US] +features: [Temporal] +---*/ + +const datetime = new Temporal.ZonedDateTime(0n, "Europe/Vienna"); + +const resultShort = datetime.toLocaleString("en-US", { timeZoneName: "short" }); +const resultLong = datetime.toLocaleString("en-US", { timeZoneName: "long" }); +assert.notSameValue(resultShort, resultLong, "formats with different timeZoneName options should be different"); +assert(resultLong.includes("Central European Standard Time"), "time zone name can be written out in full"); diff --git a/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/toLocaleString/options-undefined.js b/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/toLocaleString/options-undefined.js index 64e3f7881dfb..b1c0a5b15444 100644 --- a/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/toLocaleString/options-undefined.js +++ b/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/toLocaleString/options-undefined.js @@ -8,8 +8,17 @@ features: [BigInt, Temporal] ---*/ const datetime = new Temporal.ZonedDateTime(957270896_987_650_000n, "UTC"); -const defaultFormatter = new Intl.DateTimeFormat('en', Object.create(null)); -const expected = defaultFormatter.format(datetime); +const defaultFormatter = new Intl.DateTimeFormat('en', { + year: "numeric", + month: "numeric", + day: "numeric", + hour: "numeric", + minute: "numeric", + second: "numeric", + timeZoneName: "short", + timeZone: "UTC", +}); +const expected = defaultFormatter.format(datetime.toInstant()); const actualExplicit = datetime.toLocaleString('en', undefined); assert.sameValue(actualExplicit, expected, "default locale is determined by Intl.DateTimeFormat"); diff --git a/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/toLocaleString/time-zone-canonicalized.js b/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/toLocaleString/time-zone-canonicalized.js new file mode 100644 index 000000000000..b1cc8b53b6dc --- /dev/null +++ b/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/toLocaleString/time-zone-canonicalized.js @@ -0,0 +1,24 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.tolocalestring +description: Custom time zone names are canonicalized +features: [Temporal] +---*/ + +const timeZone1 = { + id: "Asia/Kolkata", + getPossibleInstantsFor() {}, + getOffsetNanosecondsFor() {}, +}; +const datetime1 = new Temporal.ZonedDateTime(0n, timeZone1); + +const timeZone2 = { + id: "Asia/Calcutta", + getPossibleInstantsFor() {}, + getOffsetNanosecondsFor() {}, +}; +const datetime2 = new Temporal.ZonedDateTime(0n, timeZone2); + +assert.sameValue(datetime1.toLocaleString(), datetime2.toLocaleString(), "Time zone names are canonicalized before passing to DateTimeFormat"); diff --git a/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/until/argument-propertybag-timezone-string-datetime.js b/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/until/argument-propertybag-timezone-string-datetime.js index 978d7307d55a..5d3def2fb3ab 100644 --- a/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/until/argument-propertybag-timezone-string-datetime.js +++ b/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/until/argument-propertybag-timezone-string-datetime.js @@ -3,7 +3,7 @@ /*--- esid: sec-temporal.zoneddatetime.prototype.until -description: Conversion of ISO date-time strings to Temporal.TimeZone instances (with Intl time zones) +description: Conversion of ISO date-time strings to Temporal.TimeZone instances (with IANA time zones) features: [Temporal] ---*/ @@ -11,12 +11,9 @@ const expectedTimeZone = "America/Vancouver"; const instance = new Temporal.ZonedDateTime(0n, expectedTimeZone); let timeZone = "2021-08-19T17:30[America/Vancouver]"; instance.until({ year: 2020, month: 5, day: 2, timeZone }); -instance.until({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }); timeZone = "2021-08-19T17:30Z[America/Vancouver]"; instance.until({ year: 2020, month: 5, day: 2, timeZone }); -instance.until({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }); timeZone = "2021-08-19T17:30-07:00[America/Vancouver]"; instance.until({ year: 2020, month: 5, day: 2, timeZone }); -instance.until({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }); diff --git a/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/withCalendar/calendar-case-insensitive.js b/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/withCalendar/calendar-case-insensitive.js index ef0fc6bb7a49..dd8d0ee48a6e 100644 --- a/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/withCalendar/calendar-case-insensitive.js +++ b/JSTests/test262/test/intl402/Temporal/ZonedDateTime/prototype/withCalendar/calendar-case-insensitive.js @@ -7,8 +7,30 @@ description: Calendar names are case-insensitive features: [Temporal] ---*/ -const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", { id: "replace-me" }); +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "replace-me", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}); const arg = "jApAnEsE";; const result = instance.withCalendar(arg); -assert.sameValue(result.calendar.id, "japanese", "Calendar is case-insensitive"); +assert.sameValue(result.calendarId, "japanese", "Calendar is case-insensitive"); diff --git a/JSTests/test262/test/intl402/fallback-locales-are-supported.js b/JSTests/test262/test/intl402/fallback-locales-are-supported.js index da91780b80bc..5d289461a15b 100644 --- a/JSTests/test262/test/intl402/fallback-locales-are-supported.js +++ b/JSTests/test262/test/intl402/fallback-locales-are-supported.js @@ -8,6 +8,7 @@ description: > supported locales. author: Norbert Lindenberg includes: [testIntl.js] +features: [Array.prototype.includes] ---*/ testWithIntlConstructors(function (Constructor) { diff --git a/JSTests/test262/test/language/expressions/assignmenttargettype/direct-updateexpression-star-star-exponentiationexpression-0.js b/JSTests/test262/test/language/expressions/assignmenttargettype/direct-updateexpression-star-star-exponentiationexpression-0.js index 2b534ff56b1b..4bf6b37018f1 100644 --- a/JSTests/test262/test/language/expressions/assignmenttargettype/direct-updateexpression-star-star-exponentiationexpression-0.js +++ b/JSTests/test262/test/language/expressions/assignmenttargettype/direct-updateexpression-star-star-exponentiationexpression-0.js @@ -3,6 +3,7 @@ // - src/assignment-target-type/invalid/direct.template /*--- description: Static Semantics AssignmentTargetType, Return invalid. (Direct assignment) +features: [exponentiation] flags: [generated] negative: phase: parse diff --git a/JSTests/test262/test/language/expressions/assignmenttargettype/direct-updateexpression-star-star-exponentiationexpression-1.js b/JSTests/test262/test/language/expressions/assignmenttargettype/direct-updateexpression-star-star-exponentiationexpression-1.js index 0f1b0caadc7a..2f4eb8e7584f 100644 --- a/JSTests/test262/test/language/expressions/assignmenttargettype/direct-updateexpression-star-star-exponentiationexpression-1.js +++ b/JSTests/test262/test/language/expressions/assignmenttargettype/direct-updateexpression-star-star-exponentiationexpression-1.js @@ -3,6 +3,7 @@ // - src/assignment-target-type/invalid/direct.template /*--- description: Static Semantics AssignmentTargetType, Return invalid. (Direct assignment) +features: [exponentiation] flags: [generated] negative: phase: parse diff --git a/JSTests/test262/test/language/expressions/assignmenttargettype/direct-updateexpression-star-star-exponentiationexpression-2.js b/JSTests/test262/test/language/expressions/assignmenttargettype/direct-updateexpression-star-star-exponentiationexpression-2.js index 9be01baaaf2a..bf20a283508b 100644 --- a/JSTests/test262/test/language/expressions/assignmenttargettype/direct-updateexpression-star-star-exponentiationexpression-2.js +++ b/JSTests/test262/test/language/expressions/assignmenttargettype/direct-updateexpression-star-star-exponentiationexpression-2.js @@ -3,6 +3,7 @@ // - src/assignment-target-type/invalid/direct.template /*--- description: Static Semantics AssignmentTargetType, Return invalid. (Direct assignment) +features: [exponentiation] flags: [generated] negative: phase: parse diff --git a/JSTests/test262/test/language/expressions/assignmenttargettype/parenthesized-updateexpression-star-star-exponentiationexpression-0.js b/JSTests/test262/test/language/expressions/assignmenttargettype/parenthesized-updateexpression-star-star-exponentiationexpression-0.js index dfa2d5ca6398..9bdf63166cfb 100644 --- a/JSTests/test262/test/language/expressions/assignmenttargettype/parenthesized-updateexpression-star-star-exponentiationexpression-0.js +++ b/JSTests/test262/test/language/expressions/assignmenttargettype/parenthesized-updateexpression-star-star-exponentiationexpression-0.js @@ -4,6 +4,7 @@ /*--- description: Static Semantics AssignmentTargetType, Return invalid. (ParenthesizedExpression) esid: sec-grouping-operator-static-semantics-assignmenttargettype +features: [exponentiation] flags: [generated] negative: phase: parse diff --git a/JSTests/test262/test/language/expressions/assignmenttargettype/parenthesized-updateexpression-star-star-exponentiationexpression-1.js b/JSTests/test262/test/language/expressions/assignmenttargettype/parenthesized-updateexpression-star-star-exponentiationexpression-1.js index b6b530e85fb8..fc9fb628cbff 100644 --- a/JSTests/test262/test/language/expressions/assignmenttargettype/parenthesized-updateexpression-star-star-exponentiationexpression-1.js +++ b/JSTests/test262/test/language/expressions/assignmenttargettype/parenthesized-updateexpression-star-star-exponentiationexpression-1.js @@ -4,6 +4,7 @@ /*--- description: Static Semantics AssignmentTargetType, Return invalid. (ParenthesizedExpression) esid: sec-grouping-operator-static-semantics-assignmenttargettype +features: [exponentiation] flags: [generated] negative: phase: parse diff --git a/JSTests/test262/test/language/expressions/assignmenttargettype/parenthesized-updateexpression-star-star-exponentiationexpression-2.js b/JSTests/test262/test/language/expressions/assignmenttargettype/parenthesized-updateexpression-star-star-exponentiationexpression-2.js index aa648bb582eb..937a37b5a283 100644 --- a/JSTests/test262/test/language/expressions/assignmenttargettype/parenthesized-updateexpression-star-star-exponentiationexpression-2.js +++ b/JSTests/test262/test/language/expressions/assignmenttargettype/parenthesized-updateexpression-star-star-exponentiationexpression-2.js @@ -4,6 +4,7 @@ /*--- description: Static Semantics AssignmentTargetType, Return invalid. (ParenthesizedExpression) esid: sec-grouping-operator-static-semantics-assignmenttargettype +features: [exponentiation] flags: [generated] negative: phase: parse diff --git a/JSTests/test262/test/language/expressions/class/cpn-class-expr-accessors-computed-property-name-from-exponetiation-expression.js b/JSTests/test262/test/language/expressions/class/cpn-class-expr-accessors-computed-property-name-from-exponetiation-expression.js index f76f26089863..a227e2224446 100644 --- a/JSTests/test262/test/language/expressions/class/cpn-class-expr-accessors-computed-property-name-from-exponetiation-expression.js +++ b/JSTests/test262/test/language/expressions/class/cpn-class-expr-accessors-computed-property-name-from-exponetiation-expression.js @@ -4,7 +4,7 @@ /*--- description: Computed property name from exponentiation expression (ComputedPropertyName in ClassExpression) esid: prod-ComputedPropertyName -features: [computed-property-names] +features: [computed-property-names, exponentiation] flags: [generated] info: | ClassExpression: diff --git a/JSTests/test262/test/language/expressions/class/cpn-class-expr-accessors-computed-property-name-from-math.js b/JSTests/test262/test/language/expressions/class/cpn-class-expr-accessors-computed-property-name-from-math.js index 8257361e39f9..2caf8f9ace67 100644 --- a/JSTests/test262/test/language/expressions/class/cpn-class-expr-accessors-computed-property-name-from-math.js +++ b/JSTests/test262/test/language/expressions/class/cpn-class-expr-accessors-computed-property-name-from-math.js @@ -4,7 +4,7 @@ /*--- description: Computed property name from math (ComputedPropertyName in ClassExpression) esid: prod-ComputedPropertyName -features: [computed-property-names] +features: [computed-property-names, exponentiation] flags: [generated] info: | ClassExpression: diff --git a/JSTests/test262/test/language/expressions/class/cpn-class-expr-computed-property-name-from-exponetiation-expression.js b/JSTests/test262/test/language/expressions/class/cpn-class-expr-computed-property-name-from-exponetiation-expression.js index f1dab7637c8a..d4bf478540a4 100644 --- a/JSTests/test262/test/language/expressions/class/cpn-class-expr-computed-property-name-from-exponetiation-expression.js +++ b/JSTests/test262/test/language/expressions/class/cpn-class-expr-computed-property-name-from-exponetiation-expression.js @@ -4,7 +4,7 @@ /*--- description: Computed property name from exponentiation expression (ComputedPropertyName in ClassExpression) esid: prod-ComputedPropertyName -features: [computed-property-names] +features: [computed-property-names, exponentiation] flags: [generated] info: | ClassExpression: diff --git a/JSTests/test262/test/language/expressions/class/cpn-class-expr-computed-property-name-from-math.js b/JSTests/test262/test/language/expressions/class/cpn-class-expr-computed-property-name-from-math.js index f93877258285..bbeac1afaa3e 100644 --- a/JSTests/test262/test/language/expressions/class/cpn-class-expr-computed-property-name-from-math.js +++ b/JSTests/test262/test/language/expressions/class/cpn-class-expr-computed-property-name-from-math.js @@ -4,7 +4,7 @@ /*--- description: Computed property name from math (ComputedPropertyName in ClassExpression) esid: prod-ComputedPropertyName -features: [computed-property-names] +features: [computed-property-names, exponentiation] flags: [generated] info: | ClassExpression: diff --git a/JSTests/test262/test/language/expressions/class/cpn-class-expr-fields-computed-property-name-from-exponetiation-expression.js b/JSTests/test262/test/language/expressions/class/cpn-class-expr-fields-computed-property-name-from-exponetiation-expression.js index db184fef6eac..e88a5e62252c 100644 --- a/JSTests/test262/test/language/expressions/class/cpn-class-expr-fields-computed-property-name-from-exponetiation-expression.js +++ b/JSTests/test262/test/language/expressions/class/cpn-class-expr-fields-computed-property-name-from-exponetiation-expression.js @@ -4,7 +4,7 @@ /*--- description: Computed property name from exponentiation expression (ComputedPropertyName in ClassExpression) esid: prod-ComputedPropertyName -features: [computed-property-names, class-fields-public, class-static-fields-public] +features: [computed-property-names, exponentiation, class-fields-public, class-static-fields-public] flags: [generated] info: | ClassExpression: diff --git a/JSTests/test262/test/language/expressions/class/cpn-class-expr-fields-computed-property-name-from-math.js b/JSTests/test262/test/language/expressions/class/cpn-class-expr-fields-computed-property-name-from-math.js index 24bb837b8505..afa864183acf 100644 --- a/JSTests/test262/test/language/expressions/class/cpn-class-expr-fields-computed-property-name-from-math.js +++ b/JSTests/test262/test/language/expressions/class/cpn-class-expr-fields-computed-property-name-from-math.js @@ -4,7 +4,7 @@ /*--- description: Computed property name from math (ComputedPropertyName in ClassExpression) esid: prod-ComputedPropertyName -features: [computed-property-names, class-fields-public, class-static-fields-public] +features: [computed-property-names, exponentiation, class-fields-public, class-static-fields-public] flags: [generated] info: | ClassExpression: diff --git a/JSTests/test262/test/language/expressions/class/cpn-class-expr-fields-methods-computed-property-name-from-exponetiation-expression.js b/JSTests/test262/test/language/expressions/class/cpn-class-expr-fields-methods-computed-property-name-from-exponetiation-expression.js index ef13282ffd34..0ca711152ed8 100644 --- a/JSTests/test262/test/language/expressions/class/cpn-class-expr-fields-methods-computed-property-name-from-exponetiation-expression.js +++ b/JSTests/test262/test/language/expressions/class/cpn-class-expr-fields-methods-computed-property-name-from-exponetiation-expression.js @@ -4,7 +4,7 @@ /*--- description: Computed property name from exponentiation expression (ComputedPropertyName in ClassExpression) esid: prod-ComputedPropertyName -features: [computed-property-names, class-fields-public, class-static-fields-public] +features: [computed-property-names, exponentiation, class-fields-public, class-static-fields-public] flags: [generated] info: | ClassExpression: diff --git a/JSTests/test262/test/language/expressions/class/cpn-class-expr-fields-methods-computed-property-name-from-math.js b/JSTests/test262/test/language/expressions/class/cpn-class-expr-fields-methods-computed-property-name-from-math.js index 1f2e2171b31a..8b9b82d18c9e 100644 --- a/JSTests/test262/test/language/expressions/class/cpn-class-expr-fields-methods-computed-property-name-from-math.js +++ b/JSTests/test262/test/language/expressions/class/cpn-class-expr-fields-methods-computed-property-name-from-math.js @@ -4,7 +4,7 @@ /*--- description: Computed property name from math (ComputedPropertyName in ClassExpression) esid: prod-ComputedPropertyName -features: [computed-property-names, class-fields-public, class-static-fields-public] +features: [computed-property-names, exponentiation, class-fields-public, class-static-fields-public] flags: [generated] info: | ClassExpression: diff --git a/JSTests/test262/test/language/expressions/class/decorator/syntax/class-valid/decorator-member-expr-private-identifier.js b/JSTests/test262/test/language/expressions/class/decorator/syntax/class-valid/decorator-member-expr-private-identifier.js index a20d81200af1..f6d11ca73d9f 100644 --- a/JSTests/test262/test/language/expressions/class/decorator/syntax/class-valid/decorator-member-expr-private-identifier.js +++ b/JSTests/test262/test/language/expressions/class/decorator/syntax/class-valid/decorator-member-expr-private-identifier.js @@ -22,7 +22,9 @@ info: | DecoratorMemberExpression[Yield, Await] : - PrivateIdentifier + IdentifierReference[?Yield, ?Await] + DecoratorMemberExpression[?Yield, ?Await] . IdentifierName + DecoratorMemberExpression[?Yield, ?Await] . PrivateIdentifier PrivateIdentifier :: # IdentifierName @@ -41,13 +43,13 @@ var C = class { static #await() {} static { - var C = @#$ - @#_ - @#\u{6F} - @#\u2118 - @#ZW_\u200C_NJ - @#ZW_\u200D_J - @#yield - @#await class {} + var C = @C.#$ + @C.#_ + @C.#\u{6F} + @C.#\u2118 + @C.#ZW_\u200C_NJ + @C.#ZW_\u200D_J + @C.#yield + @C.#await class {} } }; diff --git a/JSTests/test262/test/language/expressions/class/decorator/syntax/valid/decorator-call-expr-identifier-reference-yield.js b/JSTests/test262/test/language/expressions/class/decorator/syntax/valid/decorator-call-expr-identifier-reference-yield.js index 4ed6f5b8b740..8187c606a9af 100644 --- a/JSTests/test262/test/language/expressions/class/decorator/syntax/valid/decorator-call-expr-identifier-reference-yield.js +++ b/JSTests/test262/test/language/expressions/class/decorator/syntax/valid/decorator-call-expr-identifier-reference-yield.js @@ -26,8 +26,8 @@ info: | DecoratorMemberExpression[Yield, Await] : IdentifierReference[?Yield, ?Await] - PrivateIdentifier DecoratorMemberExpression[?Yield, ?Await] . IdentifierName + DecoratorMemberExpression[?Yield, ?Await] . PrivateIdentifier IdentifierReference[Yield, Await] : [~Yield] yield diff --git a/JSTests/test262/test/language/expressions/class/decorator/syntax/valid/decorator-call-expr-identifier-reference.js b/JSTests/test262/test/language/expressions/class/decorator/syntax/valid/decorator-call-expr-identifier-reference.js index fffdb0404958..12f9b1eb4bab 100644 --- a/JSTests/test262/test/language/expressions/class/decorator/syntax/valid/decorator-call-expr-identifier-reference.js +++ b/JSTests/test262/test/language/expressions/class/decorator/syntax/valid/decorator-call-expr-identifier-reference.js @@ -26,8 +26,8 @@ info: | DecoratorMemberExpression[Yield, Await] : IdentifierReference[?Yield, ?Await] - PrivateIdentifier DecoratorMemberExpression[?Yield, ?Await] . IdentifierName + DecoratorMemberExpression[?Yield, ?Await] . PrivateIdentifier IdentifierReference[Yield, Await] : Identifier diff --git a/JSTests/test262/test/language/expressions/class/decorator/syntax/valid/decorator-member-expr-decorator-member-expr.js b/JSTests/test262/test/language/expressions/class/decorator/syntax/valid/decorator-member-expr-decorator-member-expr.js index 5b0804260558..d8e255109cc3 100644 --- a/JSTests/test262/test/language/expressions/class/decorator/syntax/valid/decorator-member-expr-decorator-member-expr.js +++ b/JSTests/test262/test/language/expressions/class/decorator/syntax/valid/decorator-member-expr-decorator-member-expr.js @@ -23,8 +23,8 @@ info: | DecoratorMemberExpression[Yield, Await] : IdentifierReference[?Yield, ?Await] - PrivateIdentifier DecoratorMemberExpression[?Yield, ?Await] . IdentifierName + DecoratorMemberExpression[?Yield, ?Await] . PrivateIdentifier ---*/ let ns = { diff --git a/JSTests/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-exp.js b/JSTests/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-exp.js index 964813959643..b27ea18c0fee 100644 --- a/JSTests/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-exp.js +++ b/JSTests/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-exp.js @@ -4,7 +4,7 @@ /*--- description: Compound exponentiation assignment with target being a private reference (to an accessor property with getter and setter) esid: sec-assignment-operators-runtime-semantics-evaluation -features: [class-fields-private] +features: [exponentiation, class-fields-private] flags: [generated] info: | sec-assignment-operators-runtime-semantics-evaluation diff --git a/JSTests/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-data-property-exp.js b/JSTests/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-data-property-exp.js index e62385acfb1f..85bf0f2a7eed 100644 --- a/JSTests/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-data-property-exp.js +++ b/JSTests/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-data-property-exp.js @@ -4,7 +4,7 @@ /*--- description: Compound exponentiation assignment with target being a private reference (to a field) esid: sec-assignment-operators-runtime-semantics-evaluation -features: [class-fields-private] +features: [exponentiation, class-fields-private] flags: [generated] info: | sec-assignment-operators-runtime-semantics-evaluation diff --git a/JSTests/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-method-exp.js b/JSTests/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-method-exp.js index 25036c1d8626..5d6ade31df29 100644 --- a/JSTests/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-method-exp.js +++ b/JSTests/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-method-exp.js @@ -4,7 +4,7 @@ /*--- description: Compound exponentiation assignment with target being a private reference (to a private method) esid: sec-assignment-operators-runtime-semantics-evaluation -features: [class-fields-private] +features: [exponentiation, class-fields-private] flags: [generated] info: | sec-assignment-operators-runtime-semantics-evaluation diff --git a/JSTests/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-readonly-accessor-property-exp.js b/JSTests/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-readonly-accessor-property-exp.js index b0e17bb8e73f..72a5f8fbfdbc 100644 --- a/JSTests/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-readonly-accessor-property-exp.js +++ b/JSTests/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-readonly-accessor-property-exp.js @@ -4,7 +4,7 @@ /*--- description: Compound exponentiation assignment with target being a private reference (to an accessor property with getter) esid: sec-assignment-operators-runtime-semantics-evaluation -features: [class-fields-private] +features: [exponentiation, class-fields-private] flags: [generated] info: | sec-assignment-operators-runtime-semantics-evaluation diff --git a/JSTests/test262/test/language/expressions/dynamic-import/syntax/invalid/invalid-assignmenttargettype-syntax-error-17-lhs-assignment-operator-assignment-expression.js b/JSTests/test262/test/language/expressions/dynamic-import/syntax/invalid/invalid-assignmenttargettype-syntax-error-17-lhs-assignment-operator-assignment-expression.js index d27455ea3f9b..2ddc94f6f668 100644 --- a/JSTests/test262/test/language/expressions/dynamic-import/syntax/invalid/invalid-assignmenttargettype-syntax-error-17-lhs-assignment-operator-assignment-expression.js +++ b/JSTests/test262/test/language/expressions/dynamic-import/syntax/invalid/invalid-assignmenttargettype-syntax-error-17-lhs-assignment-operator-assignment-expression.js @@ -40,7 +40,7 @@ info: | negative: phase: parse type: SyntaxError -features: [dynamic-import] +features: [dynamic-import, exponentiation] ---*/ $DONOTEVALUATE(); diff --git a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A1.js b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A1.js index 02e2049cdffb..5f1ea2008c6d 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A1.js +++ b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A1.js @@ -4,6 +4,7 @@ /*--- esid: sec-applying-the-exp-operator description: If exponent is NaN, the result is NaN. +features: [exponentiation] ---*/ var exponent = NaN; diff --git a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A11.js b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A11.js index feffb65d98f0..293f985d41cc 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A11.js +++ b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A11.js @@ -4,6 +4,7 @@ /*--- esid: sec-applying-the-exp-operator description: If base is +∞ and exponent > 0, the result is +∞. +features: [exponentiation] ---*/ diff --git a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A12.js b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A12.js index d9f3084b57e2..c3617f1d1436 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A12.js +++ b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A12.js @@ -4,6 +4,7 @@ /*--- esid: sec-applying-the-exp-operator description: If base is +∞ and exponent < 0, the result is +0. +features: [exponentiation] ---*/ diff --git a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A13.js b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A13.js index 4d955e55b455..2ae3ad3d054d 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A13.js +++ b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A13.js @@ -4,6 +4,7 @@ /*--- esid: sec-applying-the-exp-operator description: If base is −∞ and exponent > 0 and exponent is an odd integer, the result is −∞. +features: [exponentiation] ---*/ diff --git a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A14.js b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A14.js index 8637ecca2694..77b016d96621 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A14.js +++ b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A14.js @@ -4,6 +4,7 @@ /*--- esid: sec-applying-the-exp-operator description: If base is −∞ and exponent > 0 and exponent is not an odd integer, the result is +∞. +features: [exponentiation] ---*/ diff --git a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A15.js b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A15.js index e4ec599d6b2e..7260e078e031 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A15.js +++ b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A15.js @@ -4,6 +4,7 @@ /*--- esid: sec-applying-the-exp-operator description: If base is −∞ and exponent < 0 and exponent is an odd integer, the result is −0. +features: [exponentiation] ---*/ diff --git a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A16.js b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A16.js index ecfc9e21a441..29fb080f9aa9 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A16.js +++ b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A16.js @@ -4,6 +4,7 @@ /*--- esid: sec-applying-the-exp-operator description: If base is −∞ and exponent < 0 and exponent is not an odd integer, the result is +0. +features: [exponentiation] ---*/ diff --git a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A17.js b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A17.js index 5764dacd1ae4..d04058da216c 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A17.js +++ b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A17.js @@ -4,6 +4,7 @@ /*--- esid: sec-applying-the-exp-operator description: If base is +0 and exponent > 0, the result is +0. +features: [exponentiation] ---*/ diff --git a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A18.js b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A18.js index f3ae5c7f270e..0d48cf328247 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A18.js +++ b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A18.js @@ -4,6 +4,7 @@ /*--- esid: sec-applying-the-exp-operator description: If base is +0 and exponent < 0, the result is +∞. +features: [exponentiation] ---*/ diff --git a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A19.js b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A19.js index d56b8a0daa75..7c9934c87d7a 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A19.js +++ b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A19.js @@ -4,6 +4,7 @@ /*--- esid: sec-applying-the-exp-operator description: If base is −0 and exponent > 0 and exponent is an odd integer, the result is −0. +features: [exponentiation] ---*/ diff --git a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A2.js b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A2.js index 5eaf70151ad2..1c94a7fa514a 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A2.js +++ b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A2.js @@ -5,6 +5,7 @@ esid: sec-applying-the-exp-operator description: > If exponent is +0, the result is 1, even if base is NaN. +features: [exponentiation] ---*/ diff --git a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A20.js b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A20.js index 93ae818e2b61..518ac4a9757b 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A20.js +++ b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A20.js @@ -4,6 +4,7 @@ /*--- esid: sec-applying-the-exp-operator description: If base is −0 and exponent > 0 and exponent is not an odd integer, the result is +0. +features: [exponentiation] ---*/ diff --git a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A21.js b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A21.js index 361295d3c7af..b236eb201c00 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A21.js +++ b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A21.js @@ -4,6 +4,7 @@ /*--- esid: sec-applying-the-exp-operator description: If base is −0 and exponent < 0 and exponent is an odd integer, the result is −∞. +features: [exponentiation] ---*/ diff --git a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A22.js b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A22.js index 17786cebac49..c1bc09b81ee8 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A22.js +++ b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A22.js @@ -4,6 +4,7 @@ /*--- esid: sec-applying-the-exp-operator description: If base is −0 and exponent < 0 and exponent is not an odd integer, the result is +∞. +features: [exponentiation] ---*/ diff --git a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A23.js b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A23.js index c2010f3ee3db..836fddb66b02 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A23.js +++ b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A23.js @@ -4,6 +4,7 @@ /*--- esid: sec-applying-the-exp-operator description: If base < 0 and base is finite and exponent is finite and exponent is not an integer, the result is NaN. +features: [exponentiation] ---*/ diff --git a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A3.js b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A3.js index 629df3221b5a..24dc972c1ef3 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A3.js +++ b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A3.js @@ -5,6 +5,7 @@ esid: sec-applying-the-exp-operator description: > If exponent is −0, the result is 1, even if base is NaN. +features: [exponentiation] ---*/ diff --git a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A4.js b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A4.js index f7af9993227f..bf73c0de559d 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A4.js +++ b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A4.js @@ -4,6 +4,7 @@ /*--- esid: sec-applying-the-exp-operator description: If base is NaN and exponent is nonzero, the result is NaN. +features: [exponentiation] ---*/ diff --git a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A5.js b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A5.js index f0b0fd7674a0..7deb3cf0cec1 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A5.js +++ b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A5.js @@ -4,6 +4,7 @@ /*--- esid: sec-applying-the-exp-operator description: If abs(base) > 1 and exponent is +∞, the result is +∞. +features: [exponentiation] ---*/ diff --git a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A6.js b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A6.js index 06c39324338b..36c973093b7f 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A6.js +++ b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A6.js @@ -4,6 +4,7 @@ /*--- esid: sec-applying-the-exp-operator description: If abs(base) > 1 and exponent is −∞, the result is +0. +features: [exponentiation] ---*/ diff --git a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A7.js b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A7.js index 5420f64f8947..bc7c7aa0bf77 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A7.js +++ b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A7.js @@ -4,6 +4,7 @@ /*--- esid: sec-applying-the-exp-operator description: If abs(base) is 1 and exponent is +∞, the result is NaN. +features: [exponentiation] ---*/ diff --git a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A8.js b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A8.js index 0e3dcc3679f3..68521e6902be 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A8.js +++ b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A8.js @@ -4,6 +4,7 @@ /*--- esid: sec-applying-the-exp-operator description: If abs(base) is 1 and exponent is −∞, the result is NaN. +features: [exponentiation] ---*/ diff --git a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A9.js b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A9.js index 6eee820d5b61..0a37bf930d86 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A9.js +++ b/JSTests/test262/test/language/expressions/exponentiation/applying-the-exp-operator_A9.js @@ -4,7 +4,7 @@ /*--- esid: sec-applying-the-exp-operator description: If abs(base) < 1 and exponent is +∞, the result is +0. - +features: [exponentiation] ---*/ diff --git a/JSTests/test262/test/language/expressions/exponentiation/bigint-and-number.js b/JSTests/test262/test/language/expressions/exponentiation/bigint-and-number.js index 769bb4c91755..3c32d5b17f6b 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/bigint-and-number.js +++ b/JSTests/test262/test/language/expressions/exponentiation/bigint-and-number.js @@ -3,7 +3,7 @@ /*--- esid: sec-exp-operator-runtime-semantics-evaluation description: Mixing BigInt and Number produces a TypeError for exponentiation operator -features: [BigInt] +features: [BigInt, exponentiation] info: | Let base be ? ToNumeric(leftValue). Let exponent be ? ToNumeric(rightValue). diff --git a/JSTests/test262/test/language/expressions/exponentiation/bigint-arithmetic.js b/JSTests/test262/test/language/expressions/exponentiation/bigint-arithmetic.js index 2ccbce791d2e..2ab0d90b0855 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/bigint-arithmetic.js +++ b/JSTests/test262/test/language/expressions/exponentiation/bigint-arithmetic.js @@ -3,7 +3,7 @@ /*--- esid: sec-exp-operator-runtime-semantics-evaluation description: BigInt exponentiation arithmetic -features: [BigInt] +features: [BigInt, exponentiation] ---*/ assert.sameValue( 0x123n ** 0x123n, diff --git a/JSTests/test262/test/language/expressions/exponentiation/bigint-errors.js b/JSTests/test262/test/language/expressions/exponentiation/bigint-errors.js index e563bc6528cb..a18aec253b4f 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/bigint-errors.js +++ b/JSTests/test262/test/language/expressions/exponentiation/bigint-errors.js @@ -3,7 +3,7 @@ /*--- description: exponentiation operator ToNumeric with BigInt operands esid: sec-exp-operator-runtime-semantics-evaluation -features: [BigInt, Symbol, Symbol.toPrimitive, computed-property-names] +features: [BigInt, Symbol, Symbol.toPrimitive, computed-property-names, exponentiation] ---*/ assert.throws(TypeError, function() { Symbol('1') ** 0n; diff --git a/JSTests/test262/test/language/expressions/exponentiation/bigint-negative-exponent-throws.js b/JSTests/test262/test/language/expressions/exponentiation/bigint-negative-exponent-throws.js index 8e3b32c539b4..ae49cb2b290a 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/bigint-negative-exponent-throws.js +++ b/JSTests/test262/test/language/expressions/exponentiation/bigint-negative-exponent-throws.js @@ -13,7 +13,7 @@ info: | 1. If exponent < 0, throw a RangeError exception. ... -features: [BigInt] +features: [BigInt, exponentiation] ---*/ assert.throws(RangeError, function() { 1n ** -1n; diff --git a/JSTests/test262/test/language/expressions/exponentiation/bigint-toprimitive.js b/JSTests/test262/test/language/expressions/exponentiation/bigint-toprimitive.js index 9cae71e6fc3c..09c19c8a1b68 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/bigint-toprimitive.js +++ b/JSTests/test262/test/language/expressions/exponentiation/bigint-toprimitive.js @@ -3,7 +3,7 @@ /*--- description: exponentiation operator ToNumeric with BigInt operands esid: sec-exp-operator-runtime-semantics-evaluation -features: [BigInt, Symbol.toPrimitive, computed-property-names] +features: [BigInt, Symbol.toPrimitive, computed-property-names, exponentiation] ---*/ function err() { throw new Test262Error(); diff --git a/JSTests/test262/test/language/expressions/exponentiation/bigint-wrapped-values.js b/JSTests/test262/test/language/expressions/exponentiation/bigint-wrapped-values.js index a5ba5070c378..13fd85202cf3 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/bigint-wrapped-values.js +++ b/JSTests/test262/test/language/expressions/exponentiation/bigint-wrapped-values.js @@ -3,7 +3,7 @@ /*--- description: exponentiation operator ToNumeric with BigInt operands esid: sec-exp-operator-runtime-semantics-evaluation -features: [BigInt, Symbol.toPrimitive, computed-property-names] +features: [BigInt, Symbol.toPrimitive, computed-property-names, exponentiation] ---*/ assert.sameValue(Object(2n) ** 1n, 2n, 'The result of (Object(2n) ** 1n) is 2n'); assert.sameValue(1n ** Object(2n), 1n, 'The result of (1n ** Object(2n)) is 1n'); diff --git a/JSTests/test262/test/language/expressions/exponentiation/bigint-zero-base-zero-exponent.js b/JSTests/test262/test/language/expressions/exponentiation/bigint-zero-base-zero-exponent.js index 425c46ff1efb..6c7218c53a4e 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/bigint-zero-base-zero-exponent.js +++ b/JSTests/test262/test/language/expressions/exponentiation/bigint-zero-base-zero-exponent.js @@ -15,6 +15,6 @@ info: | 2. If base is 0n and exponent is 0n, return 1n. 3. Return a BigInt representing the mathematical value of base raised to the power exponent. ... -features: [BigInt] +features: [BigInt, exponentiation] ---*/ assert.sameValue(0n ** 0n, 1n, 'The result of (0n ** 0n) is 1n'); diff --git a/JSTests/test262/test/language/expressions/exponentiation/exp-assignment-operator.js b/JSTests/test262/test/language/expressions/exponentiation/exp-assignment-operator.js index b00d15b8103f..e1907de3aae6 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/exp-assignment-operator.js +++ b/JSTests/test262/test/language/expressions/exponentiation/exp-assignment-operator.js @@ -17,7 +17,7 @@ info: | 6. Let r be the result of applying op to lval and rval as if evaluating the expression lval op rval. 7. Perform ? PutValue(lref, r). 8. Return r. - +features: [exponentiation] ---*/ var base = -3; diff --git a/JSTests/test262/test/language/expressions/exponentiation/exp-operator-evaluation-order.js b/JSTests/test262/test/language/expressions/exponentiation/exp-operator-evaluation-order.js index eeef5863308b..c1464ab324e0 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/exp-operator-evaluation-order.js +++ b/JSTests/test262/test/language/expressions/exponentiation/exp-operator-evaluation-order.js @@ -16,6 +16,7 @@ info: | 5. Let base be ? ToNumber(leftValue). 6. Let exponent be ? ToNumber(rightValue). 7. Return the result of Applying the ** operator with base and exponent as specified in 12.7.3.4. +features: [exponentiation] ---*/ var capture = []; diff --git a/JSTests/test262/test/language/expressions/exponentiation/exp-operator-precedence-unary-expression-semantics.js b/JSTests/test262/test/language/expressions/exponentiation/exp-operator-precedence-unary-expression-semantics.js index 03723c4d4669..7c4b030538c2 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/exp-operator-precedence-unary-expression-semantics.js +++ b/JSTests/test262/test/language/expressions/exponentiation/exp-operator-precedence-unary-expression-semantics.js @@ -19,6 +19,7 @@ info: | `-` UnaryExpression `~` UnaryExpression `!` UnaryExpression +features: [exponentiation] ---*/ assert.sameValue(-(3 ** 2), -9, "-(3 ** 2) === -9"); diff --git a/JSTests/test262/test/language/expressions/exponentiation/exp-operator-precedence-update-expression-semantics.js b/JSTests/test262/test/language/expressions/exponentiation/exp-operator-precedence-update-expression-semantics.js index a87f92217f9f..f728c0bf2405 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/exp-operator-precedence-update-expression-semantics.js +++ b/JSTests/test262/test/language/expressions/exponentiation/exp-operator-precedence-update-expression-semantics.js @@ -15,6 +15,7 @@ info: | LeftHandSideExpression `--` `++` UnaryExpression `--` UnaryExpression +features: [exponentiation] ---*/ var base = 4; diff --git a/JSTests/test262/test/language/expressions/exponentiation/exp-operator-syntax-error-bitnot-unary-expression-base.js b/JSTests/test262/test/language/expressions/exponentiation/exp-operator-syntax-error-bitnot-unary-expression-base.js index 5ccb8438b6de..dcccd7bbf4bb 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/exp-operator-syntax-error-bitnot-unary-expression-base.js +++ b/JSTests/test262/test/language/expressions/exponentiation/exp-operator-syntax-error-bitnot-unary-expression-base.js @@ -14,6 +14,7 @@ info: | ... `~` UnaryExpression ... +features: [exponentiation] negative: phase: parse diff --git a/JSTests/test262/test/language/expressions/exponentiation/exp-operator-syntax-error-delete-unary-expression-base.js b/JSTests/test262/test/language/expressions/exponentiation/exp-operator-syntax-error-delete-unary-expression-base.js index 6e112053e7ba..95b7003b119e 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/exp-operator-syntax-error-delete-unary-expression-base.js +++ b/JSTests/test262/test/language/expressions/exponentiation/exp-operator-syntax-error-delete-unary-expression-base.js @@ -14,6 +14,7 @@ info: | ... `delete` UnaryExpression ... +features: [exponentiation] negative: phase: parse diff --git a/JSTests/test262/test/language/expressions/exponentiation/exp-operator-syntax-error-logical-not-unary-expression-base.js b/JSTests/test262/test/language/expressions/exponentiation/exp-operator-syntax-error-logical-not-unary-expression-base.js index b453969e347a..82f12d1701f6 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/exp-operator-syntax-error-logical-not-unary-expression-base.js +++ b/JSTests/test262/test/language/expressions/exponentiation/exp-operator-syntax-error-logical-not-unary-expression-base.js @@ -14,6 +14,7 @@ info: | ... `!` UnaryExpression ... +features: [exponentiation] negative: phase: parse diff --git a/JSTests/test262/test/language/expressions/exponentiation/exp-operator-syntax-error-negate-unary-expression-base.js b/JSTests/test262/test/language/expressions/exponentiation/exp-operator-syntax-error-negate-unary-expression-base.js index 992e7925f0a6..372ec1d503fe 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/exp-operator-syntax-error-negate-unary-expression-base.js +++ b/JSTests/test262/test/language/expressions/exponentiation/exp-operator-syntax-error-negate-unary-expression-base.js @@ -14,6 +14,7 @@ info: | ... `-` UnaryExpression ... +features: [exponentiation] negative: phase: parse diff --git a/JSTests/test262/test/language/expressions/exponentiation/exp-operator-syntax-error-plus-unary-expression-base.js b/JSTests/test262/test/language/expressions/exponentiation/exp-operator-syntax-error-plus-unary-expression-base.js index c475d138a14e..b959e00852fa 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/exp-operator-syntax-error-plus-unary-expression-base.js +++ b/JSTests/test262/test/language/expressions/exponentiation/exp-operator-syntax-error-plus-unary-expression-base.js @@ -14,6 +14,7 @@ info: | ... `+` UnaryExpression ... +features: [exponentiation] negative: phase: parse diff --git a/JSTests/test262/test/language/expressions/exponentiation/exp-operator-syntax-error-typeof-unary-expression-base.js b/JSTests/test262/test/language/expressions/exponentiation/exp-operator-syntax-error-typeof-unary-expression-base.js index 2193981d695a..3d901e969be0 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/exp-operator-syntax-error-typeof-unary-expression-base.js +++ b/JSTests/test262/test/language/expressions/exponentiation/exp-operator-syntax-error-typeof-unary-expression-base.js @@ -14,6 +14,7 @@ info: | ... `typeof` UnaryExpression ... +features: [exponentiation] negative: phase: parse diff --git a/JSTests/test262/test/language/expressions/exponentiation/exp-operator-syntax-error-void-unary-expression-base.js b/JSTests/test262/test/language/expressions/exponentiation/exp-operator-syntax-error-void-unary-expression-base.js index bf5ffc94c311..ef515afe36b8 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/exp-operator-syntax-error-void-unary-expression-base.js +++ b/JSTests/test262/test/language/expressions/exponentiation/exp-operator-syntax-error-void-unary-expression-base.js @@ -14,6 +14,7 @@ info: | ... `void` UnaryExpression ... +features: [exponentiation] negative: phase: parse diff --git a/JSTests/test262/test/language/expressions/exponentiation/exp-operator.js b/JSTests/test262/test/language/expressions/exponentiation/exp-operator.js index 7b46edcac953..fdf3c8fa2464 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/exp-operator.js +++ b/JSTests/test262/test/language/expressions/exponentiation/exp-operator.js @@ -6,6 +6,7 @@ author: Rick Waldron esid: sec-exp-operator description: > Performs exponential calculation on operands. Same algorithm as %MathPow%(base, exponent) +features: [exponentiation] ---*/ var exponent = 2; diff --git a/JSTests/test262/test/language/expressions/exponentiation/int32_min-exponent.js b/JSTests/test262/test/language/expressions/exponentiation/int32_min-exponent.js index 556c8885c6a4..0d91d53f8bd2 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/int32_min-exponent.js +++ b/JSTests/test262/test/language/expressions/exponentiation/int32_min-exponent.js @@ -6,6 +6,7 @@ esid: sec-applying-the-exp-operator description: > Using -(2**31) as exponent with the exponentiation operator should behave as expected. +features: [exponentiation] ---*/ const INT32_MIN = -2147483648; diff --git a/JSTests/test262/test/language/expressions/exponentiation/order-of-evaluation.js b/JSTests/test262/test/language/expressions/exponentiation/order-of-evaluation.js index 4a933c63771b..91c5e953f9ff 100644 --- a/JSTests/test262/test/language/expressions/exponentiation/order-of-evaluation.js +++ b/JSTests/test262/test/language/expressions/exponentiation/order-of-evaluation.js @@ -3,7 +3,7 @@ /*--- esid: sec-exp-operator-runtime-semantics-evaluation description: Type coercion order of operations for exponentiation operator -features: [Symbol] +features: [Symbol, exponentiation] info: | Evaluate lhs Evaluate rhs diff --git a/JSTests/test262/test/language/expressions/object/cpn-obj-lit-computed-property-name-from-exponetiation-expression.js b/JSTests/test262/test/language/expressions/object/cpn-obj-lit-computed-property-name-from-exponetiation-expression.js index a3a51ba5ecb5..301d48ac4a6b 100644 --- a/JSTests/test262/test/language/expressions/object/cpn-obj-lit-computed-property-name-from-exponetiation-expression.js +++ b/JSTests/test262/test/language/expressions/object/cpn-obj-lit-computed-property-name-from-exponetiation-expression.js @@ -4,7 +4,7 @@ /*--- description: Computed property name from exponentiation expression (ComputedPropertyName in ObjectLiteral) esid: prod-ComputedPropertyName -features: [computed-property-names] +features: [computed-property-names, exponentiation] flags: [generated] info: | ObjectLiteral: diff --git a/JSTests/test262/test/language/expressions/object/cpn-obj-lit-computed-property-name-from-math.js b/JSTests/test262/test/language/expressions/object/cpn-obj-lit-computed-property-name-from-math.js index f3218082c0a1..b00930e79e6f 100644 --- a/JSTests/test262/test/language/expressions/object/cpn-obj-lit-computed-property-name-from-math.js +++ b/JSTests/test262/test/language/expressions/object/cpn-obj-lit-computed-property-name-from-math.js @@ -4,7 +4,7 @@ /*--- description: Computed property name from math (ComputedPropertyName in ObjectLiteral) esid: prod-ComputedPropertyName -features: [computed-property-names] +features: [computed-property-names, exponentiation] flags: [generated] info: | ObjectLiteral: diff --git a/JSTests/test262/test/language/expressions/postfix-decrement/this.js b/JSTests/test262/test/language/expressions/postfix-decrement/this.js new file mode 100644 index 000000000000..972be0030af2 --- /dev/null +++ b/JSTests/test262/test/language/expressions/postfix-decrement/this.js @@ -0,0 +1,27 @@ +// Copyright (C) 2023 Veera Sivarajan. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-update-expressions-static-semantics-early-errors +description: > + It is an early Syntax Error if AssignmentTargetType of LeftHandSideExpression is not simple. (this) +info: | + sec-static-semantics-assignmenttargettype + + PrimaryExpression: this + + Return invalid. + + sec-update-expressions-static-semantics-early-errors + + UpdateExpression: LeftHandSideExpression -- + + It is an early Syntax Error if AssignmentTargetType of LeftHandSideExpression is not simple. +negative: + phase: parse + type: SyntaxError +---*/ + +$DONOTEVALUATE(); + +this--; diff --git a/JSTests/test262/test/language/expressions/postfix-increment/this.js b/JSTests/test262/test/language/expressions/postfix-increment/this.js new file mode 100644 index 000000000000..41270d93bc79 --- /dev/null +++ b/JSTests/test262/test/language/expressions/postfix-increment/this.js @@ -0,0 +1,27 @@ +// Copyright (C) 2023 Veera Sivarajan. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-update-expressions-static-semantics-early-errors +description: > + It is an early Syntax Error if AssignmentTargetType of LeftHandSideExpression is not simple. (this) +info: | + sec-static-semantics-assignmenttargettype + + PrimaryExpression: this + + Return invalid. + + sec-update-expressions-static-semantics-early-errors + + UpdateExpression: LeftHandSideExpression ++ + + It is an early Syntax Error if AssignmentTargetType of LeftHandSideExpression is not simple. +negative: + phase: parse + type: SyntaxError +---*/ + +$DONOTEVALUATE(); + +this++; diff --git a/JSTests/test262/test/language/expressions/prefix-decrement/this.js b/JSTests/test262/test/language/expressions/prefix-decrement/this.js new file mode 100644 index 000000000000..b0861d9ccc2f --- /dev/null +++ b/JSTests/test262/test/language/expressions/prefix-decrement/this.js @@ -0,0 +1,27 @@ +// Copyright (C) 2023 Veera Sivarajan. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-update-expressions-static-semantics-early-errors +description: > + It is an early Syntax Error if AssignmentTargetType of UnaryExpression is not simple. (this) +info: | + sec-static-semantics-assignmenttargettype + + PrimaryExpression: this + + Return invalid. + + sec-update-expressions-static-semantics-early-errors + + UpdateExpression: -- UnaryExpression + + It is an early Syntax Error if AssignmentTargetType of UnaryExpression is not simple. +negative: + phase: parse + type: SyntaxError +---*/ + +$DONOTEVALUATE(); + +--this; diff --git a/JSTests/test262/test/language/expressions/prefix-increment/this.js b/JSTests/test262/test/language/expressions/prefix-increment/this.js new file mode 100644 index 000000000000..625b38f34ade --- /dev/null +++ b/JSTests/test262/test/language/expressions/prefix-increment/this.js @@ -0,0 +1,27 @@ +// Copyright (C) 2023 Veera Sivarajan. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-update-expressions-static-semantics-early-errors +description: > + It is an early Syntax Error if AssignmentTargetType of UnaryExpression is not simple. (this) +info: | + sec-static-semantics-assignmenttargettype + + PrimaryExpression: this + + Return invalid. + + sec-update-expressions-static-semantics-early-errors + + UpdateExpression: ++ UnaryExpression + + It is an early Syntax Error if AssignmentTargetType of UnaryExpression is not simple. +negative: + phase: parse + type: SyntaxError +---*/ + +$DONOTEVALUATE(); + +++this; diff --git a/JSTests/test262/test/language/module-code/instn-iee-err-ambiguous-as.js b/JSTests/test262/test/language/module-code/instn-iee-err-ambiguous-as.js index abd45c3e9115..6eed88757eb4 100644 --- a/JSTests/test262/test/language/module-code/instn-iee-err-ambiguous-as.js +++ b/JSTests/test262/test/language/module-code/instn-iee-err-ambiguous-as.js @@ -31,9 +31,11 @@ info: | SameValue(resolution.[[BindingName]], starResolution.[[BindingName]]) is false, return "ambiguous". negative: - phase: runtime + phase: resolution type: SyntaxError flags: [module] ---*/ +$DONOTEVALUATE(); + export { x as y } from './instn-iee-err-ambiguous_FIXTURE.js'; diff --git a/JSTests/test262/test/language/module-code/instn-iee-err-ambiguous.js b/JSTests/test262/test/language/module-code/instn-iee-err-ambiguous.js index 19864dd4272d..3c4a8d8174f8 100644 --- a/JSTests/test262/test/language/module-code/instn-iee-err-ambiguous.js +++ b/JSTests/test262/test/language/module-code/instn-iee-err-ambiguous.js @@ -31,9 +31,11 @@ info: | SameValue(resolution.[[BindingName]], starResolution.[[BindingName]]) is false, return "ambiguous". negative: - phase: runtime + phase: resolution type: SyntaxError flags: [module] ---*/ +$DONOTEVALUATE(); + export { x } from './instn-iee-err-ambiguous_FIXTURE.js'; diff --git a/JSTests/test262/test/language/module-code/instn-iee-err-circular-as.js b/JSTests/test262/test/language/module-code/instn-iee-err-circular-as.js index e1420c5186a8..15cab8bebb11 100644 --- a/JSTests/test262/test/language/module-code/instn-iee-err-circular-as.js +++ b/JSTests/test262/test/language/module-code/instn-iee-err-circular-as.js @@ -20,9 +20,11 @@ info: | i. Assert: this is a circular import request. ii. Return null. negative: - phase: runtime + phase: resolution type: SyntaxError flags: [module] ---*/ +$DONOTEVALUATE(); + export { x as y } from './instn-iee-err-circular_FIXTURE.js'; diff --git a/JSTests/test262/test/language/module-code/instn-iee-err-circular.js b/JSTests/test262/test/language/module-code/instn-iee-err-circular.js index ad7635183a3a..d6985c048994 100644 --- a/JSTests/test262/test/language/module-code/instn-iee-err-circular.js +++ b/JSTests/test262/test/language/module-code/instn-iee-err-circular.js @@ -20,9 +20,11 @@ info: | i. Assert: this is a circular import request. ii. Return null. negative: - phase: runtime + phase: resolution type: SyntaxError flags: [module] ---*/ +$DONOTEVALUATE(); + export { x } from './instn-iee-err-circular_FIXTURE.js'; diff --git a/JSTests/test262/test/language/module-code/instn-iee-err-dflt-thru-star-as.js b/JSTests/test262/test/language/module-code/instn-iee-err-dflt-thru-star-as.js index 6c2665aec531..b3293e0ea945 100644 --- a/JSTests/test262/test/language/module-code/instn-iee-err-dflt-thru-star-as.js +++ b/JSTests/test262/test/language/module-code/instn-iee-err-dflt-thru-star-as.js @@ -19,9 +19,11 @@ info: | b. Throw a SyntaxError exception. c. NOTE A default export cannot be provided by an export *. negative: - phase: runtime + phase: resolution type: SyntaxError flags: [module] ---*/ +$DONOTEVALUATE(); + export { default as x } from './instn-iee-err-dflt-thru-star-int_FIXTURE.js'; diff --git a/JSTests/test262/test/language/module-code/instn-iee-err-dflt-thru-star.js b/JSTests/test262/test/language/module-code/instn-iee-err-dflt-thru-star.js index 95f94ad72ae0..2db906f79976 100644 --- a/JSTests/test262/test/language/module-code/instn-iee-err-dflt-thru-star.js +++ b/JSTests/test262/test/language/module-code/instn-iee-err-dflt-thru-star.js @@ -19,9 +19,11 @@ info: | b. Throw a SyntaxError exception. c. NOTE A default export cannot be provided by an export *. negative: - phase: runtime + phase: resolution type: SyntaxError flags: [module] ---*/ +$DONOTEVALUATE(); + export { default } from './instn-iee-err-dflt-thru-star-int_FIXTURE.js'; diff --git a/JSTests/test262/test/language/module-code/instn-iee-err-not-found-as.js b/JSTests/test262/test/language/module-code/instn-iee-err-not-found-as.js index ba6d30721e48..5531649ad9d2 100644 --- a/JSTests/test262/test/language/module-code/instn-iee-err-not-found-as.js +++ b/JSTests/test262/test/language/module-code/instn-iee-err-not-found-as.js @@ -19,9 +19,11 @@ info: | [...] 11. Return starResolution. negative: - phase: runtime + phase: resolution type: SyntaxError flags: [module] ---*/ +$DONOTEVALUATE(); + export { x as y } from './instn-iee-err-not-found-empty_FIXTURE.js'; diff --git a/JSTests/test262/test/language/module-code/instn-iee-err-not-found.js b/JSTests/test262/test/language/module-code/instn-iee-err-not-found.js index 858a8337a7cd..55f9ea866fd0 100644 --- a/JSTests/test262/test/language/module-code/instn-iee-err-not-found.js +++ b/JSTests/test262/test/language/module-code/instn-iee-err-not-found.js @@ -19,9 +19,11 @@ info: | [...] 11. Return starResolution. negative: - phase: runtime + phase: resolution type: SyntaxError flags: [module] ---*/ +$DONOTEVALUATE(); + export { x } from './instn-iee-err-not-found-empty_FIXTURE.js'; diff --git a/JSTests/test262/test/language/module-code/instn-named-err-ambiguous-as.js b/JSTests/test262/test/language/module-code/instn-named-err-ambiguous-as.js index 1143776bb696..3ed04f9e936c 100644 --- a/JSTests/test262/test/language/module-code/instn-named-err-ambiguous-as.js +++ b/JSTests/test262/test/language/module-code/instn-named-err-ambiguous-as.js @@ -36,9 +36,11 @@ info: | SameValue(resolution.[[BindingName]], starResolution.[[BindingName]]) is false, return "ambiguous". negative: - phase: runtime + phase: resolution type: SyntaxError flags: [module] ---*/ +$DONOTEVALUATE(); + import { x as y } from './instn-named-err-ambiguous_FIXTURE.js'; diff --git a/JSTests/test262/test/language/module-code/instn-named-err-ambiguous.js b/JSTests/test262/test/language/module-code/instn-named-err-ambiguous.js index 415fa7ee0bd0..5f17bf476765 100644 --- a/JSTests/test262/test/language/module-code/instn-named-err-ambiguous.js +++ b/JSTests/test262/test/language/module-code/instn-named-err-ambiguous.js @@ -36,9 +36,11 @@ info: | SameValue(resolution.[[BindingName]], starResolution.[[BindingName]]) is false, return "ambiguous". negative: - phase: runtime + phase: resolution type: SyntaxError flags: [module] ---*/ +$DONOTEVALUATE(); + import { x } from './instn-named-err-ambiguous_FIXTURE.js'; diff --git a/JSTests/test262/test/language/module-code/instn-named-err-dflt-thru-star-as.js b/JSTests/test262/test/language/module-code/instn-named-err-dflt-thru-star-as.js index fda57f1ea42d..ab5ee42c107d 100644 --- a/JSTests/test262/test/language/module-code/instn-named-err-dflt-thru-star-as.js +++ b/JSTests/test262/test/language/module-code/instn-named-err-dflt-thru-star-as.js @@ -24,9 +24,11 @@ info: | b. Throw a SyntaxError exception. c. NOTE A default export cannot be provided by an export *. negative: - phase: runtime + phase: resolution type: SyntaxError flags: [module] ---*/ +$DONOTEVALUATE(); + import { default as x } from './instn-named-err-dflt-thru-star-int_FIXTURE.js'; diff --git a/JSTests/test262/test/language/module-code/instn-named-err-dflt-thru-star-dflt.js b/JSTests/test262/test/language/module-code/instn-named-err-dflt-thru-star-dflt.js index a15668ebd092..60e4c4295ef5 100644 --- a/JSTests/test262/test/language/module-code/instn-named-err-dflt-thru-star-dflt.js +++ b/JSTests/test262/test/language/module-code/instn-named-err-dflt-thru-star-dflt.js @@ -24,9 +24,11 @@ info: | b. Throw a SyntaxError exception. c. NOTE A default export cannot be provided by an export *. negative: - phase: runtime + phase: resolution type: SyntaxError flags: [module] ---*/ +$DONOTEVALUATE(); + import x from './instn-named-err-dflt-thru-star-int_FIXTURE.js'; diff --git a/JSTests/test262/test/language/module-code/instn-named-err-not-found-as.js b/JSTests/test262/test/language/module-code/instn-named-err-not-found-as.js index 09b9ec4d97cf..632e11a6dece 100644 --- a/JSTests/test262/test/language/module-code/instn-named-err-not-found-as.js +++ b/JSTests/test262/test/language/module-code/instn-named-err-not-found-as.js @@ -24,9 +24,11 @@ info: | [...] 11. Return starResolution. negative: - phase: runtime + phase: resolution type: SyntaxError flags: [module] ---*/ +$DONOTEVALUATE(); + import { x as y } from './instn-named-err-not-found-empty_FIXTURE.js'; diff --git a/JSTests/test262/test/language/module-code/instn-named-err-not-found-dflt.js b/JSTests/test262/test/language/module-code/instn-named-err-not-found-dflt.js index 768bafef5076..482ef11f6507 100644 --- a/JSTests/test262/test/language/module-code/instn-named-err-not-found-dflt.js +++ b/JSTests/test262/test/language/module-code/instn-named-err-not-found-dflt.js @@ -24,9 +24,11 @@ info: | [...] 11. Return starResolution. negative: - phase: runtime + phase: resolution type: SyntaxError flags: [module] ---*/ +$DONOTEVALUATE(); + import x from './instn-named-err-not-found-empty_FIXTURE.js'; diff --git a/JSTests/test262/test/language/module-code/instn-named-err-not-found.js b/JSTests/test262/test/language/module-code/instn-named-err-not-found.js index 2ff6e5286c59..83c905103d1b 100644 --- a/JSTests/test262/test/language/module-code/instn-named-err-not-found.js +++ b/JSTests/test262/test/language/module-code/instn-named-err-not-found.js @@ -24,9 +24,11 @@ info: | [...] 11. Return starResolution. negative: - phase: runtime + phase: resolution type: SyntaxError flags: [module] ---*/ +$DONOTEVALUATE(); + import { x } from './instn-named-err-not-found-empty_FIXTURE.js'; diff --git a/JSTests/test262/test/language/module-code/instn-star-err-not-found.js b/JSTests/test262/test/language/module-code/instn-star-err-not-found.js index c2fbca0baea2..b6cd9f6cd5f0 100644 --- a/JSTests/test262/test/language/module-code/instn-star-err-not-found.js +++ b/JSTests/test262/test/language/module-code/instn-star-err-not-found.js @@ -23,9 +23,11 @@ info: | i. Let resolution be ? module.ResolveExport(name, « », « »). ii. If resolution is null, throw a SyntaxError exception. negative: - phase: runtime + phase: resolution type: SyntaxError flags: [module] ---*/ +$DONOTEVALUATE(); + import * as ns from './instn-star-err-not-found-faulty_FIXTURE.js'; diff --git a/JSTests/test262/test/language/statements/class/cpn-class-decl-accessors-computed-property-name-from-exponetiation-expression.js b/JSTests/test262/test/language/statements/class/cpn-class-decl-accessors-computed-property-name-from-exponetiation-expression.js index 02e36b1715fa..ff1d5a6f4bd6 100644 --- a/JSTests/test262/test/language/statements/class/cpn-class-decl-accessors-computed-property-name-from-exponetiation-expression.js +++ b/JSTests/test262/test/language/statements/class/cpn-class-decl-accessors-computed-property-name-from-exponetiation-expression.js @@ -4,7 +4,7 @@ /*--- description: Computed property name from exponentiation expression (ComputedPropertyName in ClassDeclaration) esid: prod-ComputedPropertyName -features: [computed-property-names] +features: [computed-property-names, exponentiation] flags: [generated] info: | ClassExpression: diff --git a/JSTests/test262/test/language/statements/class/cpn-class-decl-accessors-computed-property-name-from-math.js b/JSTests/test262/test/language/statements/class/cpn-class-decl-accessors-computed-property-name-from-math.js index d9d3b9f1186e..13f88ea83239 100644 --- a/JSTests/test262/test/language/statements/class/cpn-class-decl-accessors-computed-property-name-from-math.js +++ b/JSTests/test262/test/language/statements/class/cpn-class-decl-accessors-computed-property-name-from-math.js @@ -4,7 +4,7 @@ /*--- description: Computed property name from math (ComputedPropertyName in ClassDeclaration) esid: prod-ComputedPropertyName -features: [computed-property-names] +features: [computed-property-names, exponentiation] flags: [generated] info: | ClassExpression: diff --git a/JSTests/test262/test/language/statements/class/cpn-class-decl-computed-property-name-from-exponetiation-expression.js b/JSTests/test262/test/language/statements/class/cpn-class-decl-computed-property-name-from-exponetiation-expression.js index 40038346b281..fee561912a92 100644 --- a/JSTests/test262/test/language/statements/class/cpn-class-decl-computed-property-name-from-exponetiation-expression.js +++ b/JSTests/test262/test/language/statements/class/cpn-class-decl-computed-property-name-from-exponetiation-expression.js @@ -4,7 +4,7 @@ /*--- description: Computed property name from exponentiation expression (ComputedPropertyName in ClassDeclaration) esid: prod-ComputedPropertyName -features: [computed-property-names] +features: [computed-property-names, exponentiation] flags: [generated] info: | ClassExpression: diff --git a/JSTests/test262/test/language/statements/class/cpn-class-decl-computed-property-name-from-math.js b/JSTests/test262/test/language/statements/class/cpn-class-decl-computed-property-name-from-math.js index bbcbfa70c533..4594c3314349 100644 --- a/JSTests/test262/test/language/statements/class/cpn-class-decl-computed-property-name-from-math.js +++ b/JSTests/test262/test/language/statements/class/cpn-class-decl-computed-property-name-from-math.js @@ -4,7 +4,7 @@ /*--- description: Computed property name from math (ComputedPropertyName in ClassDeclaration) esid: prod-ComputedPropertyName -features: [computed-property-names] +features: [computed-property-names, exponentiation] flags: [generated] info: | ClassExpression: diff --git a/JSTests/test262/test/language/statements/class/cpn-class-decl-fields-computed-property-name-from-exponetiation-expression.js b/JSTests/test262/test/language/statements/class/cpn-class-decl-fields-computed-property-name-from-exponetiation-expression.js index a00c8dcf0b0c..b1fd2c55f01d 100644 --- a/JSTests/test262/test/language/statements/class/cpn-class-decl-fields-computed-property-name-from-exponetiation-expression.js +++ b/JSTests/test262/test/language/statements/class/cpn-class-decl-fields-computed-property-name-from-exponetiation-expression.js @@ -4,7 +4,7 @@ /*--- description: Computed property name from exponentiation expression (ComputedPropertyName in ClassExpression) esid: prod-ComputedPropertyName -features: [computed-property-names, class-fields-public, class-static-fields-public] +features: [computed-property-names, exponentiation, class-fields-public, class-static-fields-public] flags: [generated] info: | ClassExpression: diff --git a/JSTests/test262/test/language/statements/class/cpn-class-decl-fields-computed-property-name-from-math.js b/JSTests/test262/test/language/statements/class/cpn-class-decl-fields-computed-property-name-from-math.js index c512cb069d6a..2f34703a500a 100644 --- a/JSTests/test262/test/language/statements/class/cpn-class-decl-fields-computed-property-name-from-math.js +++ b/JSTests/test262/test/language/statements/class/cpn-class-decl-fields-computed-property-name-from-math.js @@ -4,7 +4,7 @@ /*--- description: Computed property name from math (ComputedPropertyName in ClassExpression) esid: prod-ComputedPropertyName -features: [computed-property-names, class-fields-public, class-static-fields-public] +features: [computed-property-names, exponentiation, class-fields-public, class-static-fields-public] flags: [generated] info: | ClassExpression: diff --git a/JSTests/test262/test/language/statements/class/cpn-class-decl-fields-methods-computed-property-name-from-exponetiation-expression.js b/JSTests/test262/test/language/statements/class/cpn-class-decl-fields-methods-computed-property-name-from-exponetiation-expression.js index 02bd62297ebd..fab8d63ab3fc 100644 --- a/JSTests/test262/test/language/statements/class/cpn-class-decl-fields-methods-computed-property-name-from-exponetiation-expression.js +++ b/JSTests/test262/test/language/statements/class/cpn-class-decl-fields-methods-computed-property-name-from-exponetiation-expression.js @@ -4,7 +4,7 @@ /*--- description: Computed property name from exponentiation expression (ComputedPropertyName in ClassExpression) esid: prod-ComputedPropertyName -features: [computed-property-names, class-fields-public, class-static-fields-public] +features: [computed-property-names, exponentiation, class-fields-public, class-static-fields-public] flags: [generated] info: | ClassExpression: diff --git a/JSTests/test262/test/language/statements/class/cpn-class-decl-fields-methods-computed-property-name-from-math.js b/JSTests/test262/test/language/statements/class/cpn-class-decl-fields-methods-computed-property-name-from-math.js index 763688bb79df..1f384d411dfc 100644 --- a/JSTests/test262/test/language/statements/class/cpn-class-decl-fields-methods-computed-property-name-from-math.js +++ b/JSTests/test262/test/language/statements/class/cpn-class-decl-fields-methods-computed-property-name-from-math.js @@ -4,7 +4,7 @@ /*--- description: Computed property name from math (ComputedPropertyName in ClassExpression) esid: prod-ComputedPropertyName -features: [computed-property-names, class-fields-public, class-static-fields-public] +features: [computed-property-names, exponentiation, class-fields-public, class-static-fields-public] flags: [generated] info: | ClassExpression: diff --git a/JSTests/test262/test/language/statements/class/decorator/syntax/class-valid/decorator-member-expr-private-identifier.js b/JSTests/test262/test/language/statements/class/decorator/syntax/class-valid/decorator-member-expr-private-identifier.js index 24af7d9e5c9a..4ffc96f4a624 100644 --- a/JSTests/test262/test/language/statements/class/decorator/syntax/class-valid/decorator-member-expr-private-identifier.js +++ b/JSTests/test262/test/language/statements/class/decorator/syntax/class-valid/decorator-member-expr-private-identifier.js @@ -23,7 +23,9 @@ info: | DecoratorMemberExpression[Yield, Await] : - PrivateIdentifier + IdentifierReference[?Yield, ?Await] + DecoratorMemberExpression[?Yield, ?Await] . IdentifierName + DecoratorMemberExpression[?Yield, ?Await] . PrivateIdentifier PrivateIdentifier :: # IdentifierName @@ -42,13 +44,13 @@ class C { static #await() {} static { - @#$ - @#_ - @#\u{6F} - @#\u2118 - @#ZW_\u200C_NJ - @#ZW_\u200D_J - @#yield - @#await class C {} + @C.#$ + @C.#_ + @C.#\u{6F} + @C.#\u2118 + @C.#ZW_\u200C_NJ + @C.#ZW_\u200D_J + @C.#yield + @C.#await class C {} } } diff --git a/JSTests/test262/test/language/statements/class/decorator/syntax/valid/class-element-decorator-call-expr-identifier-reference.js b/JSTests/test262/test/language/statements/class/decorator/syntax/valid/class-element-decorator-call-expr-identifier-reference.js index 52216da39f28..4933f3a4f6f0 100644 --- a/JSTests/test262/test/language/statements/class/decorator/syntax/valid/class-element-decorator-call-expr-identifier-reference.js +++ b/JSTests/test262/test/language/statements/class/decorator/syntax/valid/class-element-decorator-call-expr-identifier-reference.js @@ -31,8 +31,8 @@ info: | DecoratorMemberExpression[Yield, Await] : IdentifierReference[?Yield, ?Await] - PrivateIdentifier DecoratorMemberExpression[?Yield, ?Await] . IdentifierName + DecoratorMemberExpression[?Yield, ?Await] . PrivateIdentifier IdentifierReference[Yield, Await] : Identifier diff --git a/JSTests/test262/test/language/statements/class/decorator/syntax/valid/class-element-decorator-member-expr-decorator-member-expr.js b/JSTests/test262/test/language/statements/class/decorator/syntax/valid/class-element-decorator-member-expr-decorator-member-expr.js index 48c7d2b19d63..4089453a728c 100644 --- a/JSTests/test262/test/language/statements/class/decorator/syntax/valid/class-element-decorator-member-expr-decorator-member-expr.js +++ b/JSTests/test262/test/language/statements/class/decorator/syntax/valid/class-element-decorator-member-expr-decorator-member-expr.js @@ -28,8 +28,8 @@ info: | DecoratorMemberExpression[Yield, Await] : IdentifierReference[?Yield, ?Await] - PrivateIdentifier DecoratorMemberExpression[?Yield, ?Await] . IdentifierName + DecoratorMemberExpression[?Yield, ?Await] . PrivateIdentifier ---*/ let ns = { diff --git a/JSTests/test262/test/language/statements/class/decorator/syntax/valid/decorator-call-expr-identifier-reference-yield.js b/JSTests/test262/test/language/statements/class/decorator/syntax/valid/decorator-call-expr-identifier-reference-yield.js index 1d16c6877a17..ef739cb19cd5 100644 --- a/JSTests/test262/test/language/statements/class/decorator/syntax/valid/decorator-call-expr-identifier-reference-yield.js +++ b/JSTests/test262/test/language/statements/class/decorator/syntax/valid/decorator-call-expr-identifier-reference-yield.js @@ -27,8 +27,8 @@ info: | DecoratorMemberExpression[Yield, Await] : IdentifierReference[?Yield, ?Await] - PrivateIdentifier DecoratorMemberExpression[?Yield, ?Await] . IdentifierName + DecoratorMemberExpression[?Yield, ?Await] . PrivateIdentifier IdentifierReference[Yield, Await] : [~Yield] yield diff --git a/JSTests/test262/test/language/statements/class/decorator/syntax/valid/decorator-call-expr-identifier-reference.js b/JSTests/test262/test/language/statements/class/decorator/syntax/valid/decorator-call-expr-identifier-reference.js index 86b8919f747e..ce8aa27dd1a1 100644 --- a/JSTests/test262/test/language/statements/class/decorator/syntax/valid/decorator-call-expr-identifier-reference.js +++ b/JSTests/test262/test/language/statements/class/decorator/syntax/valid/decorator-call-expr-identifier-reference.js @@ -27,8 +27,8 @@ info: | DecoratorMemberExpression[Yield, Await] : IdentifierReference[?Yield, ?Await] - PrivateIdentifier DecoratorMemberExpression[?Yield, ?Await] . IdentifierName + DecoratorMemberExpression[?Yield, ?Await] . PrivateIdentifier IdentifierReference[Yield, Await] : Identifier diff --git a/JSTests/test262/test/language/statements/class/decorator/syntax/valid/decorator-member-expr-decorator-member-expr.js b/JSTests/test262/test/language/statements/class/decorator/syntax/valid/decorator-member-expr-decorator-member-expr.js index a43627049cfa..f6eaf56876cf 100644 --- a/JSTests/test262/test/language/statements/class/decorator/syntax/valid/decorator-member-expr-decorator-member-expr.js +++ b/JSTests/test262/test/language/statements/class/decorator/syntax/valid/decorator-member-expr-decorator-member-expr.js @@ -24,8 +24,8 @@ info: | DecoratorMemberExpression[Yield, Await] : IdentifierReference[?Yield, ?Await] - PrivateIdentifier DecoratorMemberExpression[?Yield, ?Await] . IdentifierName + DecoratorMemberExpression[?Yield, ?Await] . PrivateIdentifier ---*/ let ns = { diff --git a/JSTests/test262/test/staging/ArrayBuffer/resizable/includes-parameter-conversion-resizes.js b/JSTests/test262/test/staging/ArrayBuffer/resizable/includes-parameter-conversion-resizes.js index 6d513ac39d70..0e9b1beb6983 100644 --- a/JSTests/test262/test/staging/ArrayBuffer/resizable/includes-parameter-conversion-resizes.js +++ b/JSTests/test262/test/staging/ArrayBuffer/resizable/includes-parameter-conversion-resizes.js @@ -6,7 +6,7 @@ esid: sec-arraybuffer-length description: > Automatically ported from IncludesParameterConversionResizes test in V8's mjsunit test typedarray-resizablearraybuffer.js -features: [resizable-arraybuffer] +features: [resizable-arraybuffer, Array.prototype.includes] flags: [onlyStrict] ---*/ diff --git a/JSTests/test262/test/staging/ArrayBuffer/resizable/includes.js b/JSTests/test262/test/staging/ArrayBuffer/resizable/includes.js index 4ae996953eb6..a33c7ca29afc 100644 --- a/JSTests/test262/test/staging/ArrayBuffer/resizable/includes.js +++ b/JSTests/test262/test/staging/ArrayBuffer/resizable/includes.js @@ -6,7 +6,7 @@ esid: sec-arraybuffer-length description: > Automatically ported from Includes test in V8's mjsunit test typedarray-resizablearraybuffer.js -features: [resizable-arraybuffer] +features: [resizable-arraybuffer, Array.prototype.includes] flags: [onlyStrict] ---*/ diff --git a/JSTests/test262/test/staging/ArrayBuffer/resizable/sort-callback-shrinks.js b/JSTests/test262/test/staging/ArrayBuffer/resizable/sort-callback-shrinks.js index 47ef31ca1d34..0ba383480479 100644 --- a/JSTests/test262/test/staging/ArrayBuffer/resizable/sort-callback-shrinks.js +++ b/JSTests/test262/test/staging/ArrayBuffer/resizable/sort-callback-shrinks.js @@ -7,7 +7,7 @@ description: > Automatically ported from SortCallbackShrinks test in V8's mjsunit test typedarray-resizablearraybuffer.js includes: [compareArray.js] -features: [resizable-arraybuffer] +features: [resizable-arraybuffer, Array.prototype.includes] flags: [onlyStrict] ---*/ diff --git a/JSTests/test262/test/staging/Intl402/Temporal/old/date-time-format.js b/JSTests/test262/test/staging/Intl402/Temporal/old/date-time-format.js index f2410131e3ea..25e7c6bc842d 100644 --- a/JSTests/test262/test/staging/Intl402/Temporal/old/date-time-format.js +++ b/JSTests/test262/test/staging/Intl402/Temporal/old/date-time-format.js @@ -83,10 +83,6 @@ var end = new Date("1991-12-26"); assert.sameValue(us.format(Temporal.Instant.from(t1)), `11/18/1976, 9:23:30${usDayPeriodSpace}AM`); assert.sameValue(at.format(Temporal.Instant.from(t1)), "18.11.1976, 15:23:30"); -// should work for ZonedDateTime -assert.sameValue(us2.format(Temporal.ZonedDateTime.from(t1)), `11/18/1976, 2:23:30${usDayPeriodSpace}PM UTC`); -assert.sameValue(at2.format(Temporal.ZonedDateTime.from(t1)), "18.11.1976, 14:23:30 UTC"); - // should work for DateTime assert.sameValue(us.format(Temporal.PlainDateTime.from(t1)), `11/18/1976, 2:23:30${usDayPeriodSpace}PM`); assert.sameValue(at.format(Temporal.PlainDateTime.from(t1)), "18.11.1976, 14:23:30"); @@ -214,123 +210,6 @@ assert.deepEqual(at.formatToParts(Temporal.Instant.from(t2)), [ value: "56" } ]); -// should work for ZonedDateTime -assert.deepEqual(us2.formatToParts(Temporal.ZonedDateTime.from(t2)), [ - { - type: "month", - value: "2" - }, - { - type: "literal", - value: "/" - }, - { - type: "day", - value: "20" - }, - { - type: "literal", - value: "/" - }, - { - type: "year", - value: "2020" - }, - { - type: "literal", - value: ", " - }, - { - type: "hour", - value: "3" - }, - { - type: "literal", - value: ":" - }, - { - type: "minute", - value: "44" - }, - { - type: "literal", - value: ":" - }, - { - type: "second", - value: "56" - }, - { - type: "literal", - value: usDayPeriodSpace - }, - { - type: "dayPeriod", - value: "PM" - }, - { - type: "literal", - value: " " - }, - { - type: "timeZoneName", - value: "EST" - } -]); -assert.deepEqual(at2.formatToParts(Temporal.ZonedDateTime.from(t2)), [ - { - type: "day", - value: "20" - }, - { - type: "literal", - value: "." - }, - { - type: "month", - value: "2" - }, - { - type: "literal", - value: "." - }, - { - type: "year", - value: "2020" - }, - { - type: "literal", - value: ", " - }, - { - type: "hour", - value: "15" - }, - { - type: "literal", - value: ":" - }, - { - type: "minute", - value: "44" - }, - { - type: "literal", - value: ":" - }, - { - type: "second", - value: "56" - }, - { - type: "literal", - value: " " - }, - { - type: "timeZoneName", - value: "GMT-5" - } -]); // should work for DateTime assert.deepEqual(us.formatToParts(Temporal.PlainDateTime.from(t2)), [ { @@ -650,15 +529,6 @@ assert.sameValue( `18.11.1976, 15:23:30${deDateRangeSeparator}20.2.2020, 21:44:56` ); -// should work for ZonedDateTime -var zdt1 = Temporal.ZonedDateTime.from(t1); -var zdt2 = Temporal.ZonedDateTime.from(t2).withTimeZone(zdt1.timeZone); -assert.sameValue( - us2.formatRange(zdt1, zdt2), - `11/18/1976, 2:23:30${usDayPeriodSpace}PM UTC${usDateRangeSeparator}2/20/2020, 8:44:56${usDayPeriodSpace}PM UTC` -); -assert.sameValue(at2.formatRange(zdt1, zdt2), `18.11.1976, 14:23:30 UTC${deDateRangeSeparator}20.2.2020, 20:44:56 UTC`); - // should work for DateTime assert.sameValue( us.formatRange(Temporal.PlainDateTime.from(t1), Temporal.PlainDateTime.from(t2)), @@ -725,9 +595,6 @@ assert.throws(RangeError, () => us.formatRange(Temporal.PlainDate.from(t1), Temporal.PlainDate.from(t2).withCalendar("japanese")) ); -// throws for two ZonedDateTimes with different time zones -assert.throws(RangeError, () => us2.formatRange(Temporal.ZonedDateTime.from(t1), Temporal.ZonedDateTime.from(t2))); - // formatRangeToParts // should work for Instant assert.deepEqual(us.formatRangeToParts(Temporal.Instant.from(t1), Temporal.Instant.from(t2)), [ @@ -984,304 +851,6 @@ assert.deepEqual(at.formatRangeToParts(Temporal.Instant.from(t1), Temporal.Insta source: "endRange" } ]); - -// should work for ZonedDateTime -var zdt1 = Temporal.ZonedDateTime.from(t1); -var zdt2 = Temporal.ZonedDateTime.from(t2).withTimeZone(zdt1.timeZone); -assert.deepEqual(us2.formatRangeToParts(zdt1, zdt2), [ - { - type: "month", - value: "11", - source: "startRange" - }, - { - type: "literal", - value: "/", - source: "startRange" - }, - { - type: "day", - value: "18", - source: "startRange" - }, - { - type: "literal", - value: "/", - source: "startRange" - }, - { - type: "year", - value: "1976", - source: "startRange" - }, - { - type: "literal", - value: ", ", - source: "startRange" - }, - { - type: "hour", - value: "2", - source: "startRange" - }, - { - type: "literal", - value: ":", - source: "startRange" - }, - { - type: "minute", - value: "23", - source: "startRange" - }, - { - type: "literal", - value: ":", - source: "startRange" - }, - { - type: "second", - value: "30", - source: "startRange" - }, - { - type: "literal", - value: usDayPeriodSpace, - source: "startRange" - }, - { - type: "dayPeriod", - value: "PM", - source: "startRange" - }, - { - type: "literal", - value: " ", - source: "startRange" - }, - { - type: "timeZoneName", - value: "UTC", - source: "startRange" - }, - { - type: "literal", - value: usDateRangeSeparator, - source: "shared" - }, - { - type: "month", - value: "2", - source: "endRange" - }, - { - type: "literal", - value: "/", - source: "endRange" - }, - { - type: "day", - value: "20", - source: "endRange" - }, - { - type: "literal", - value: "/", - source: "endRange" - }, - { - type: "year", - value: "2020", - source: "endRange" - }, - { - type: "literal", - value: ", ", - source: "endRange" - }, - { - type: "hour", - value: "8", - source: "endRange" - }, - { - type: "literal", - value: ":", - source: "endRange" - }, - { - type: "minute", - value: "44", - source: "endRange" - }, - { - type: "literal", - value: ":", - source: "endRange" - }, - { - type: "second", - value: "56", - source: "endRange" - }, - { - type: "literal", - value: usDayPeriodSpace, - source: "endRange" - }, - { - type: "dayPeriod", - value: "PM", - source: "endRange" - }, - { - type: "literal", - value: " ", - source: "endRange" - }, - { - type: "timeZoneName", - value: "UTC", - source: "endRange" - } -]); -assert.deepEqual(at2.formatRangeToParts(zdt1, zdt2), [ - { - type: "day", - value: "18", - source: "startRange" - }, - { - type: "literal", - value: ".", - source: "startRange" - }, - { - type: "month", - value: "11", - source: "startRange" - }, - { - type: "literal", - value: ".", - source: "startRange" - }, - { - type: "year", - value: "1976", - source: "startRange" - }, - { - type: "literal", - value: ", ", - source: "startRange" - }, - { - type: "hour", - value: "14", - source: "startRange" - }, - { - type: "literal", - value: ":", - source: "startRange" - }, - { - type: "minute", - value: "23", - source: "startRange" - }, - { - type: "literal", - value: ":", - source: "startRange" - }, - { - type: "second", - value: "30", - source: "startRange" - }, - { - type: "literal", - value: " ", - source: "startRange" - }, - { - type: "timeZoneName", - value: "UTC", - source: "startRange" - }, - { - type: "literal", - value: deDateRangeSeparator, - source: "shared" - }, - { - type: "day", - value: "20", - source: "endRange" - }, - { - type: "literal", - value: ".", - source: "endRange" - }, - { - type: "month", - value: "2", - source: "endRange" - }, - { - type: "literal", - value: ".", - source: "endRange" - }, - { - type: "year", - value: "2020", - source: "endRange" - }, - { - type: "literal", - value: ", ", - source: "endRange" - }, - { - type: "hour", - value: "20", - source: "endRange" - }, - { - type: "literal", - value: ":", - source: "endRange" - }, - { - type: "minute", - value: "44", - source: "endRange" - }, - { - type: "literal", - value: ":", - source: "endRange" - }, - { - type: "second", - value: "56", - source: "endRange" - }, - { - type: "literal", - value: " ", - source: "endRange" - }, - { - type: "timeZoneName", - value: "UTC", - source: "endRange" - } -]); // should work for DateTime assert.deepEqual(us.formatRangeToParts(Temporal.PlainDateTime.from(t1), Temporal.PlainDateTime.from(t2)), [ { @@ -2094,7 +1663,3 @@ assert.throws(RangeError, () => assert.throws(RangeError, () => at.formatRangeToParts(Temporal.PlainDate.from(t1), Temporal.PlainDate.from(t2).withCalendar("japanese")) ); -// throws for two ZonedDateTimes with different time zones -assert.throws(RangeError, () => - us2.formatRangeToParts(Temporal.ZonedDateTime.from(t1), Temporal.ZonedDateTime.from(t2)) -); diff --git a/JSTests/test262/test/staging/Intl402/Temporal/old/date-toLocaleString.js b/JSTests/test262/test/staging/Intl402/Temporal/old/date-toLocaleString.js index 282b22850e5a..8b90b223cc63 100644 --- a/JSTests/test262/test/staging/Intl402/Temporal/old/date-toLocaleString.js +++ b/JSTests/test262/test/staging/Intl402/Temporal/old/date-toLocaleString.js @@ -31,28 +31,3 @@ assert.sameValue(date.toLocaleString("en-US", { timeZoneName: "long" }), "11/18/ assert.sameValue(date.toLocaleString("en-US", { hour: "numeric" }), "11/18/1976"); assert.sameValue(date.toLocaleString("en-US", { minute: "numeric" }), "11/18/1976"); assert.sameValue(date.toLocaleString("en-US", { second: "numeric" }), "11/18/1976"); - -// works when the object's calendar is the same as the locale's calendar -var d = Temporal.PlainDate.from({ - era: "showa", - eraYear: 51, - month: 11, - day: 18, - calendar: "japanese" -}); -var result = d.toLocaleString("en-US-u-ca-japanese"); -assert(result === "11/18/51" || result === "11/18/51 S"); - -// adopts the locale's calendar when the object's calendar is ISO -var d = Temporal.PlainDate.from("1976-11-18"); -var result = d.toLocaleString("en-US-u-ca-japanese"); -assert(result === "11/18/51" || result === "11/18/51 S"); - -// throws when the calendars are different and not ISO -var d = Temporal.PlainDate.from({ - year: 1976, - month: 11, - day: 18, - calendar: "gregory" -}); -assert.throws(RangeError, () => d.toLocaleString("en-US-u-ca-japanese")); diff --git a/JSTests/test262/test/staging/Intl402/Temporal/old/datetime-toLocaleString.js b/JSTests/test262/test/staging/Intl402/Temporal/old/datetime-toLocaleString.js index 65a7bcdbefc2..c5889e0ecbbc 100644 --- a/JSTests/test262/test/staging/Intl402/Temporal/old/datetime-toLocaleString.js +++ b/JSTests/test262/test/staging/Intl402/Temporal/old/datetime-toLocaleString.js @@ -49,34 +49,3 @@ assert.sameValue( `${dstStart.toLocaleString("en-US", { timeZone: "America/Los_Angeles" })}`, `3/8/2020, 3:30:00${usDayPeriodSpace}AM` ); - -// works when the object's calendar is the same as the locale's calendar -var dt = Temporal.PlainDateTime.from({ - era: "showa", - eraYear: 51, - month: 11, - day: 18, - hour: 15, - minute: 23, - second: 30, - calendar: "japanese" -}); -var result = dt.toLocaleString("en-US-u-ca-japanese"); -assert(result === `11/18/51, 3:23:30${usDayPeriodSpace}PM` || result === `11/18/51 S, 3:23:30${usDayPeriodSpace}PM`); - -// adopts the locale's calendar when the object's calendar is ISO -var dt = Temporal.PlainDateTime.from("1976-11-18T15:23:30"); -var result = dt.toLocaleString("en-US-u-ca-japanese"); -assert(result === `11/18/51, 3:23:30${usDayPeriodSpace}PM` || result === `11/18/51 S, 3:23:30${usDayPeriodSpace}PM`); - -// throws when the calendars are different and not ISO -var dt = Temporal.PlainDateTime.from({ - year: 1976, - month: 11, - day: 18, - hour: 15, - minute: 23, - second: 30, - calendar: "gregory" -}); -assert.throws(RangeError, () => dt.toLocaleString("en-US-u-ca-japanese")); diff --git a/JSTests/test262/test/staging/Intl402/Temporal/old/japanese-era.js b/JSTests/test262/test/staging/Intl402/Temporal/old/japanese-era.js index 12cea521f285..17d2572cf4c0 100644 --- a/JSTests/test262/test/staging/Intl402/Temporal/old/japanese-era.js +++ b/JSTests/test262/test/staging/Intl402/Temporal/old/japanese-era.js @@ -69,6 +69,7 @@ var date = Temporal.PlainDate.from({ assert.sameValue(`${ date }`, "2019-01-01[u-ca=japanese]"); assert.sameValue(date.era, "heisei"); assert.sameValue(date.eraYear, 31); + date = Temporal.PlainDate.from({ era: "heisei", eraYear: 1, @@ -89,6 +90,7 @@ date = Temporal.PlainDate.from({ assert.sameValue(`${ date }`, "1926-01-01[u-ca=japanese]"); assert.sameValue(date.era, "taisho"); assert.sameValue(date.eraYear, 15); + date = Temporal.PlainDate.from({ era: "taisho", eraYear: 1, @@ -99,6 +101,7 @@ date = Temporal.PlainDate.from({ assert.sameValue(`${ date }`, "1912-01-01[u-ca=japanese]"); assert.sameValue(date.era, "meiji"); assert.sameValue(date.eraYear, 45); + date = Temporal.PlainDate.from({ era: "meiji", eraYear: 1, @@ -109,10 +112,26 @@ date = Temporal.PlainDate.from({ assert.sameValue(`${ date }`, "1868-01-01[u-ca=japanese]"); assert.sameValue(date.era, "ce"); assert.sameValue(date.eraYear, 1868); -assert.throws(RangeError, () => Temporal.PlainDate.from({ + +// Verify that CE and BCE eras (before Meiji) are recognized +date = Temporal.PlainDate.from({ + era: "ce", + eraYear: 1000, + month: 1, + day: 1, + calendar: "japanese" +}); +assert.sameValue(`${date}`, "1000-01-01[u-ca=japanese]"); +assert.sameValue(date.era, "ce"); +assert.sameValue(date.eraYear, 1000); + +date = Temporal.PlainDate.from({ era: "bce", eraYear: 1, month: 1, day: 1, calendar: "japanese" -})); +}); +assert.sameValue(`${date}`, "0000-01-01[u-ca=japanese]"); +assert.sameValue(date.era, "bce"); +assert.sameValue(date.eraYear, 1); diff --git a/JSTests/test262/test/staging/Intl402/Temporal/old/monthday-toLocaleString.js b/JSTests/test262/test/staging/Intl402/Temporal/old/monthday-toLocaleString.js index d064ef2736d1..8b2102307452 100644 --- a/JSTests/test262/test/staging/Intl402/Temporal/old/monthday-toLocaleString.js +++ b/JSTests/test262/test/staging/Intl402/Temporal/old/monthday-toLocaleString.js @@ -26,18 +26,3 @@ assert.sameValue(monthday.toLocaleString("en-US", { hour: "numeric" }), "11/18") assert.sameValue(monthday.toLocaleString("en-US", { minute: "numeric" }), "11/18"); assert.sameValue(monthday.toLocaleString("en-US", { second: "numeric" }), "11/18"); assert.sameValue(monthday.toLocaleString("en-US", { weekday: "long" }), "11/18"); - -// works when the object's calendar is the same as the locale's calendar -var md = Temporal.PlainMonthDay.from({ - monthCode: "M11", - day: 18, - calendar: "japanese" -}); -assert.sameValue(`${ md.toLocaleString("en-US-u-ca-japanese") }`, "11/18"); - -// throws when the calendar is not equal to the locale calendar -var mdISO = Temporal.PlainMonthDay.from({ - month: 11, - day: 18 -}); -assert.throws(RangeError, () => mdISO.toLocaleString("en-US-u-ca-japanese")); diff --git a/JSTests/test262/test/staging/Intl402/Temporal/old/non-iso-calendars.js b/JSTests/test262/test/staging/Intl402/Temporal/old/non-iso-calendars.js index e5ba2ac73b39..b72092ed8ba8 100644 --- a/JSTests/test262/test/staging/Intl402/Temporal/old/non-iso-calendars.js +++ b/JSTests/test262/test/staging/Intl402/Temporal/old/non-iso-calendars.js @@ -4,7 +4,7 @@ /*--- esid: sec-temporal-intl description: Non-ISO Calendars -features: [Temporal] +features: [Temporal, Array.prototype.includes] ---*/ var testChineseData = new Date("2001-02-01T00:00Z").toLocaleString("en-US-u-ca-chinese", { @@ -46,7 +46,39 @@ var year2000Content = getLocalizedDates("2000-01-01T00:00Z"); var year1Content = getLocalizedDates("0001-01-01T00:00Z"); var year2000Snapshot = "iso8601: 1/1/2000\n" + "buddhist: 1/1/2543 BE\n" + "chinese: 11/25/1999\n" + "coptic: 4/22/1716 ERA1\n" + "dangi: 11/25/1999\n" + "ethioaa: 4/22/7492 ERA0\n" + "ethiopic: 4/22/1992 ERA1\n" + "gregory: 1/1/2000\n" + "hebrew: 23 Tevet 5760\n" + "indian: 10/11/1921 Saka\n" + "islamic: 9/25/1420 AH\n" + "islamic-umalqura: 9/24/1420 AH\n" + "islamic-tbla: 9/25/1420 AH\n" + "islamic-civil: 9/24/1420 AH\n" + "islamic-rgsa: 9/25/1420 AH\n" + "islamicc: 9/24/1420 AH\n" + "japanese: 1/1/12 H\n" + "persian: 10/11/1378 AP\n" + "roc: 1/1/89 Minguo"; assert.sameValue(year2000Content, year2000Snapshot); -var year1Snapshot = "iso8601: 1/1/1\n" + "buddhist: 1/3/544 BE\n" + "chinese: 11/21/0\n" + "coptic: 5/8/284 ERA0\n" + "dangi: 11/21/0\n" + "ethioaa: 5/8/5493 ERA0\n" + "ethiopic: 5/8/5493 ERA0\n" + "gregory: 1/1/1\n" + "hebrew: 18 Tevet 3761\n" + "indian: 10/11/-78 Saka\n" + "islamic: 5/20/-640 AH\n" + "islamic-umalqura: 5/18/-640 AH\n" + "islamic-tbla: 5/19/-640 AH\n" + "islamic-civil: 5/18/-640 AH\n" + "islamic-rgsa: 5/20/-640 AH\n" + "islamicc: 5/18/-640 AH\n" + "japanese: 1/3/-643 Taika (645\u2013650)\n" + "persian: 10/11/-621 AP\n" + "roc: 1/3/1911 B.R.O.C."; + +// Several calendars based on the Gregorian calendar use Julian dates (not +// proleptic Gregorian dates) before the Gregorian switchover in Oct 1582. See +// https://bugs.chromium.org/p/chromium/issues/detail?id=1173158. The code below +// allows these tests to pass regardless of the bug, while still remaining +// sensitive to other bugs that may crop up. +const yearOneMonthDay = new Map( + ["iso8601", "gregory", "roc", "buddhist", "japanese"].map(calendar => { + hasGregorianSwitchoverBug = new Date("+001001-01-01T00:00Z") + .toLocaleDateString(`en-US-u-ca-${calendar}`, { timeZone: "UTC" }) + .startsWith("12"); + return [calendar, hasGregorianSwitchoverBug ? "1/3" : "1/1"] + })); +var year1Snapshot = + `iso8601: ${yearOneMonthDay.get("iso8601")}/1\n` + + `buddhist: ${yearOneMonthDay.get("buddhist")}/544 BE\n` + + "chinese: 11/21/0\n" + + "coptic: 5/8/284 ERA0\n" + + "dangi: 11/21/0\n" + + "ethioaa: 5/8/5493 ERA0\n" + + "ethiopic: 5/8/5493 ERA0\n" + + `gregory: ${yearOneMonthDay.get("gregory")}/1\n` + + "hebrew: 18 Tevet 3761\n" + + "indian: 10/11/-78 Saka\n" + + "islamic: 5/20/-640 AH\n" + + "islamic-umalqura: 5/18/-640 AH\n" + + "islamic-tbla: 5/19/-640 AH\n" + + "islamic-civil: 5/18/-640 AH\n" + + "islamic-rgsa: 5/20/-640 AH\n" + + "islamicc: 5/18/-640 AH\n" + + `japanese: ${yearOneMonthDay.get("japanese")}/-643 Taika (645\u2013650)\n` + + "persian: 10/11/-621 AP\n" + + `roc: ${yearOneMonthDay.get("roc")}/1911 B.R.O.C.`; assert.sameValue(year1Content, year1Snapshot); var fromWithCases = { iso8601: { diff --git a/JSTests/test262/test/staging/Intl402/Temporal/old/yearmonth-toLocaleString.js b/JSTests/test262/test/staging/Intl402/Temporal/old/yearmonth-toLocaleString.js index 8e8a1d3146df..fc80d3bcacd1 100644 --- a/JSTests/test262/test/staging/Intl402/Temporal/old/yearmonth-toLocaleString.js +++ b/JSTests/test262/test/staging/Intl402/Temporal/old/yearmonth-toLocaleString.js @@ -37,20 +37,3 @@ assert.sameValue(yearmonth.toLocaleString("en-US", { hour: "numeric" }), "11/197 assert.sameValue(yearmonth.toLocaleString("en-US", { minute: "numeric" }), "11/1976"); assert.sameValue(yearmonth.toLocaleString("en-US", { second: "numeric" }), "11/1976"); assert.sameValue(yearmonth.toLocaleString("en-US", { weekday: "long" }), "11/1976"); - -// works when the object's calendar is the same as the locale's calendar -var ym = Temporal.PlainYearMonth.from({ - era: "showa", - eraYear: 51, - month: 11, - calendar: "japanese" -}); -var result = ym.toLocaleString("en-US-u-ca-japanese"); -assert(result === "11/51" || result === "11/51 S"); - -// throws when the calendar is not equal to the locale calendar -var ymISO = Temporal.PlainYearMonth.from({ - year: 1976, - month: 11 -}); -assert.throws(RangeError, () => ymISO.toLocaleString("en-US-u-ca-japanese")); diff --git a/JSTests/test262/test/staging/Intl402/Temporal/old/zoneddatetime-toLocaleString.js b/JSTests/test262/test/staging/Intl402/Temporal/old/zoneddatetime-toLocaleString.js deleted file mode 100644 index b96dfeebc9a8..000000000000 --- a/JSTests/test262/test/staging/Intl402/Temporal/old/zoneddatetime-toLocaleString.js +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (C) 2018 Bloomberg LP. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal-zoneddatetime-objects -description: zoneddatetime.toLocaleString() -features: [Temporal] ----*/ - -// Tolerate implementation variance by expecting consistency without being prescriptive. -// TODO: can we change tests to be less reliant on CLDR formats while still testing that -// Temporal and Intl are behaving as expected? -const usDayPeriodSpace = - new Intl.DateTimeFormat("en-US", { timeStyle: "short" }) - .formatToParts(0) - .find((part, i, parts) => part.type === "literal" && parts[i + 1].type === "dayPeriod")?.value || ""; - -function maybeGetWeekdayOnlyFormat() { - const fmt = new Intl.DateTimeFormat("en-US", { weekday: "long", timeZone: "Europe/Vienna" }); - if ( - ["era", "year", "month", "day", "hour", "minute", "second", "timeZoneName"].some( - (prop) => prop in fmt.resolvedOptions() - ) - ) { - // no weekday-only format available - return null; - } - return fmt; -} - -var zdt = Temporal.ZonedDateTime.from("1976-11-18T15:23:30+01:00[Europe/Vienna]"); -assert.sameValue(zdt.toLocaleString("en-US"), `11/18/1976, 3:23:30${usDayPeriodSpace}PM GMT+1`); -assert.sameValue(zdt.toLocaleString("de-AT"), "18.11.1976, 15:23:30 MEZ"); - -const fmt = maybeGetWeekdayOnlyFormat(); -// uses only the options in resolvedOptions -if (fmt) assert.sameValue(fmt.format(zdt), "Thursday"); -// can override the style of the time zone name -assert.sameValue( - zdt.toLocaleString("en-US", { timeZoneName: "long" }), - `11/18/1976, 3:23:30${usDayPeriodSpace}PM Central European Standard Time` -); - -// works if the time zone given in options agrees with the object's time zone -assert.sameValue( - zdt.toLocaleString("en-US", { timeZone: "Europe/Vienna" }), - `11/18/1976, 3:23:30${usDayPeriodSpace}PM GMT+1` -); - -// throws if the time zone given in options disagrees with the object's time zone -assert.throws(RangeError, () => zdt.toLocaleString("en-US", { timeZone: "America/New_York" })); - -// works when the object's calendar is the same as the locale's calendar -var zdt = new Temporal.ZonedDateTime(0n, "UTC", "japanese"); -var result = zdt.toLocaleString("en-US-u-ca-japanese"); -assert( - result === `1/1/45, 12:00:00${usDayPeriodSpace}AM UTC` || result === `1/1/45 S, 12:00:00${usDayPeriodSpace}AM UTC` -); - -// adopts the locale's calendar when the object's calendar is ISO -var zdt = Temporal.ZonedDateTime.from("1976-11-18T15:23:30+00:00[UTC]"); -var result = zdt.toLocaleString("en-US-u-ca-japanese"); -assert( - result === `11/18/51, 3:23:30${usDayPeriodSpace}PM UTC` || result === `11/18/51 S, 3:23:30${usDayPeriodSpace}PM UTC` -); - -// throws when the calendars are different and not ISO -var zdt = new Temporal.ZonedDateTime(0n, "UTC", "gregory"); -assert.throws(RangeError, () => zdt.toLocaleString("en-US-u-ca-japanese")); diff --git a/JSTests/test262/test/staging/JSON/json-parse-with-source-snapshot.js b/JSTests/test262/test/staging/JSON/json-parse-with-source-snapshot.js new file mode 100644 index 000000000000..2a9692204c29 --- /dev/null +++ b/JSTests/test262/test/staging/JSON/json-parse-with-source-snapshot.js @@ -0,0 +1,94 @@ +// Copyright (C) 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: V8 mjsunit test for JSON.parse with source snapshotting +includes: [deepEqual.js] +features: [json-parse-with-source] +---*/ + +const replacements = [42, + ['foo'], + {foo:'bar'}, + 'foo']; + +function TestArrayForwardModify(replacement) { + let alreadyReplaced = false; + let expectedKeys = ['0','1','']; + // lol who designed reviver semantics + if (typeof replacement === 'object') { + expectedKeys.splice(1, 0, ...Object.keys(replacement)); + } + const o = JSON.parse('[1, 2]', function (k, v, { source }) { + assert.sameValue(expectedKeys.shift(), k); + if (k === '0') { + if (!alreadyReplaced) { + this[1] = replacement; + alreadyReplaced = true; + } + } else if (k !== '') { + assert.sameValue(undefined, source); + } + return this[k]; + }); + assert.sameValue(0, expectedKeys.length); + assert.deepEqual([1, replacement], o); +} + +function TestObjectForwardModify(replacement) { + let alreadyReplaced = false; + let expectedKeys = ['p','q','']; + if (typeof replacement === 'object') { + expectedKeys.splice(1, 0, ...Object.keys(replacement)); + } + const o = JSON.parse('{"p":1, "q":2}', function (k, v, { source }) { + assert.sameValue(expectedKeys.shift(), k); + if (k === 'p') { + if (!alreadyReplaced) { + this.q = replacement; + alreadyReplaced = true; + } + } else if (k !== '') { + assert.sameValue(undefined, source); + } + return this[k]; + }); + assert.sameValue(0, expectedKeys.length); + assert.deepEqual({p:1, q:replacement}, o); +} + +for (const r of replacements) { + TestArrayForwardModify(r); + TestObjectForwardModify(r); +} + +(function TestArrayAppend() { + let log = []; + const o = JSON.parse('[1,[]]', function (k, v, { source }) { + log.push([k, v, source]); + if (v === 1) { + this[1].push('barf'); + } + return this[k]; + }); + assert.deepEqual([['0', 1, '1'], + ['0', 'barf', undefined], + ['1', ['barf'], undefined], + ['', [1, ['barf']], undefined]], + log); +})(); + +(function TestObjectAddProperty() { + let log = []; + const o = JSON.parse('{"p":1,"q":{}}', function (k, v, { source }) { + log.push([k, v, source]); + if (v === 1) { + this.q.added = 'barf'; + } + return this[k]; + }); + assert.deepEqual([['p', 1, '1'], + ['added', 'barf', undefined], + ['q', {added:'barf'}, undefined], + ['', {p:1, q:{added:'barf'}}, undefined]], + log); +})(); diff --git a/JSTests/test262/test/staging/JSON/json-parse-with-source.js b/JSTests/test262/test/staging/JSON/json-parse-with-source.js new file mode 100644 index 000000000000..ff998e636400 --- /dev/null +++ b/JSTests/test262/test/staging/JSON/json-parse-with-source.js @@ -0,0 +1,289 @@ +// Copyright (C) 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: V8 mjsunit test for JSON.parse with source +includes: [deepEqual.js] +features: [json-parse-with-source] +---*/ + +(function TestBigInt() { + const tooBigForNumber = BigInt(Number.MAX_SAFE_INTEGER) + 2n; + const intToBigInt = (key, val, { source }) => + typeof val === 'number' && val % 1 === 0 ? BigInt(source) : val; + const roundTripped = JSON.parse(String(tooBigForNumber), intToBigInt); + assert.sameValue(tooBigForNumber, roundTripped); + + const bigIntToRawJSON = (key, val) => + typeof val === 'bigint' ? JSON.rawJSON(val) : val; + const embedded = JSON.stringify({ tooBigForNumber }, bigIntToRawJSON); + assert.sameValue('{"tooBigForNumber":9007199254740993}', embedded); +})(); + +function GenerateParseReviverFunction(texts) { + let i = 0; + return function (key, value, context) { + assert(typeof context === 'object'); + assert.sameValue(Object.prototype, Object.getPrototypeOf(context)); + // The json value is a primitive value, it's context only has a source property. + if (texts[i] !== undefined) { + const descriptor = Object.getOwnPropertyDescriptor(context, 'source'); + assert(descriptor.configurable); + assert(descriptor.enumerable); + assert(descriptor.writable); + assert.sameValue(undefined, descriptor.get); + assert.sameValue(undefined, descriptor.set); + assert.sameValue(texts[i++], descriptor.value); + + assert.deepEqual(['source'], Object.getOwnPropertyNames(context)); + assert.deepEqual([], Object.getOwnPropertySymbols(context)); + } else { + // The json value is JSArray or JSObject, it's context has no property. + assert(!Object.hasOwn(context, 'source')); + assert.deepEqual([], Object.getOwnPropertyNames(context)); + assert.deepEqual([], Object.getOwnPropertySymbols(context)); + i++; + } + return value; + }; +} + +(function TestNumber() { + assert.sameValue(1, JSON.parse('1', GenerateParseReviverFunction(['1']))); + assert.sameValue(1.1, JSON.parse('1.1', GenerateParseReviverFunction(['1.1']))); + assert.sameValue(-1, JSON.parse('-1', GenerateParseReviverFunction(['-1']))); + assert.sameValue( + -1.1, + JSON.parse('-1.1', GenerateParseReviverFunction(['-1.1'])) + ); + assert.sameValue( + 11, + JSON.parse('1.1e1', GenerateParseReviverFunction(['1.1e1'])) + ); + assert.sameValue( + 11, + JSON.parse('1.1e+1', GenerateParseReviverFunction(['1.1e+1'])) + ); + assert.sameValue( + 0.11, + JSON.parse('1.1e-1', GenerateParseReviverFunction(['1.1e-1'])) + ); + assert.sameValue( + 11, + JSON.parse('1.1E1', GenerateParseReviverFunction(['1.1E1'])) + ); + assert.sameValue( + 11, + JSON.parse('1.1E+1', GenerateParseReviverFunction(['1.1E+1'])) + ); + assert.sameValue( + 0.11, + JSON.parse('1.1E-1', GenerateParseReviverFunction(['1.1E-1'])) + ); + + assert.sameValue('1', JSON.stringify(JSON.rawJSON(1))); + assert.sameValue('1.1', JSON.stringify(JSON.rawJSON(1.1))); + assert.sameValue('-1', JSON.stringify(JSON.rawJSON(-1))); + assert.sameValue('-1.1', JSON.stringify(JSON.rawJSON(-1.1))); + assert.sameValue('11', JSON.stringify(JSON.rawJSON(1.1e1))); + assert.sameValue('0.11', JSON.stringify(JSON.rawJSON(1.1e-1))); +})(); + +(function TestBasic() { + assert.sameValue( + null, + JSON.parse('null', GenerateParseReviverFunction(['null'])) + ); + assert.sameValue( + true, + JSON.parse('true', GenerateParseReviverFunction(['true'])) + ); + assert.sameValue( + false, + JSON.parse('false', GenerateParseReviverFunction(['false'])) + ); + assert.sameValue( + 'foo', + JSON.parse('"foo"', GenerateParseReviverFunction(['"foo"'])) + ); + + assert.sameValue('null', JSON.stringify(JSON.rawJSON(null))); + assert.sameValue('true', JSON.stringify(JSON.rawJSON(true))); + assert.sameValue('false', JSON.stringify(JSON.rawJSON(false))); + assert.sameValue('"foo"', JSON.stringify(JSON.rawJSON('"foo"'))); +})(); + +(function TestObject() { + assert.deepEqual( + {}, + JSON.parse('{}', GenerateParseReviverFunction([])) + ); + assert.deepEqual( + { 42: 37 }, + JSON.parse('{"42":37}', GenerateParseReviverFunction(['37'])) + ); + assert.deepEqual( + { x: 1, y: 2 }, + JSON.parse('{"x": 1, "y": 2}', GenerateParseReviverFunction(['1', '2'])) + ); + // undefined means the json value is JSObject or JSArray and the passed + // context to the reviver function has no source property. + assert.deepEqual( + { x: [1, 2], y: [2, 3] }, + JSON.parse( + '{"x": [1,2], "y": [2,3]}', + GenerateParseReviverFunction(['1', '2', undefined, '2', '3', undefined]) + ) + ); + assert.deepEqual( + { x: { x: 1, y: 2 } }, + JSON.parse( + '{"x": {"x": 1, "y": 2}}', + GenerateParseReviverFunction(['1', '2', undefined, undefined]) + ) + ); + + assert.sameValue('{"42":37}', JSON.stringify({ 42: JSON.rawJSON(37) })); + assert.sameValue( + '{"x":1,"y":2}', + JSON.stringify({ x: JSON.rawJSON(1), y: JSON.rawJSON(2) }) + ); + assert.sameValue( + '{"x":{"x":1,"y":2}}', + JSON.stringify({ x: { x: JSON.rawJSON(1), y: JSON.rawJSON(2) } }) + ); +})(); + +(function TestArray() { + assert.deepEqual([1], JSON.parse('[1.0]', GenerateParseReviverFunction(['1.0']))); + assert.deepEqual( + [1.1], + JSON.parse('[1.1]', GenerateParseReviverFunction(['1.1'])) + ); + assert.deepEqual([], JSON.parse('[]', GenerateParseReviverFunction([]))); + assert.deepEqual( + [1, '2', true, null, { x: 1, y: 1 }], + JSON.parse( + '[1, "2", true, null, {"x": 1, "y": 1}]', + GenerateParseReviverFunction(['1', '"2"', 'true', 'null', '1', '1']) + ) + ); + + assert.sameValue('[1,1.1]', JSON.stringify([JSON.rawJSON(1), JSON.rawJSON(1.1)])); + assert.sameValue( + '["1",true,null,false]', + JSON.stringify([ + JSON.rawJSON('"1"'), + JSON.rawJSON(true), + JSON.rawJSON(null), + JSON.rawJSON(false), + ]) + ); + assert.sameValue( + '[{"x":1,"y":1}]', + JSON.stringify([{ x: JSON.rawJSON(1), y: JSON.rawJSON(1) }]) + ); +})(); + +function assertIsRawJson(rawJson, expectedRawJsonValue) { + assert.sameValue(null, Object.getPrototypeOf(rawJson)); + assert(Object.hasOwn(rawJson, 'rawJSON')); + assert.deepEqual(['rawJSON'], Object.getOwnPropertyNames(rawJson)); + assert.deepEqual([], Object.getOwnPropertySymbols(rawJson)); + assert.sameValue(expectedRawJsonValue, rawJson.rawJSON); +} + +(function TestRawJson() { + assertIsRawJson(JSON.rawJSON(1), '1'); + assertIsRawJson(JSON.rawJSON(null), 'null'); + assertIsRawJson(JSON.rawJSON(true), 'true'); + assertIsRawJson(JSON.rawJSON(false), 'false'); + assertIsRawJson(JSON.rawJSON('"foo"'), '"foo"'); + + assert.throws(TypeError, () => { + JSON.rawJSON(Symbol('123')); + }); + + assert.throws(SyntaxError, () => { + JSON.rawJSON(undefined); + }); + + assert.throws(SyntaxError, () => { + JSON.rawJSON({}); + }); + + assert.throws(SyntaxError, () => { + JSON.rawJSON([]); + }); + + const ILLEGAL_END_CHARS = ['\n', '\t', '\r', ' ']; + for (const char of ILLEGAL_END_CHARS) { + assert.throws(SyntaxError, () => { + JSON.rawJSON(`${char}123`); + }); + assert.throws(SyntaxError, () => { + JSON.rawJSON(`123${char}`); + }); + } + + assert.throws(SyntaxError, () => { + JSON.rawJSON(''); + }); + + const values = [1, 1.1, null, false, true, '123']; + for (const value of values) { + assert(!JSON.isRawJSON(value)); + assert(JSON.isRawJSON(JSON.rawJSON(value))); + } + assert(!JSON.isRawJSON(undefined)); + assert(!JSON.isRawJSON(Symbol('123'))); + assert(!JSON.isRawJSON([])); + assert(!JSON.isRawJSON({ rawJSON: '123' })); +})(); + +(function TestReviverModifyJsonValue() { + { + let reviverCallIndex = 0; + const expectedKeys = ['a', 'b', 'c', '']; + const reviver = function(key, value, {source}) { + assert.sameValue(expectedKeys[reviverCallIndex++], key); + if (key == 'a') { + this.b = 2; + assert.sameValue('0', source); + } else if (key == 'b') { + this.c = 3; + assert.sameValue(2, value); + assert.sameValue(undefined, source); + } else if (key == 'c') { + assert.sameValue(3, value); + assert.sameValue(undefined, source); + } + return value; + } + assert.deepEqual({a: 0, b: 2, c: 3}, JSON.parse('{"a": 0, "b": 1, "c": [1, 2]}', reviver)); + } + { + let reviverCallIndex = 0; + const expectedKeys = ['0', '1', '2', '3', '']; + const reviver = function(key, value, {source}) { + assert.sameValue(expectedKeys[reviverCallIndex++], key); + if (key == '0') { + this[1] = 3; + assert.sameValue(1, value); + assert.sameValue('1', source); + } else if (key == '1') { + this[2] = 4; + assert.sameValue(3, value); + assert.sameValue(undefined, source); + } else if(key == '2') { + this[3] = 5; + assert.sameValue(4, value); + assert.sameValue(undefined, source); + } else if(key == '5'){ + assert.sameValue(5, value); + assert.sameValue(undefined, source); + } + return value; + } + assert.deepEqual([1, 3, 4, 5], JSON.parse('[1, 2, 3, {"a": 1}]', reviver)); + } +})(); diff --git a/JSTests/test262/test/staging/Temporal/Instant/old/toZonedDateTime.js b/JSTests/test262/test/staging/Temporal/Instant/old/toZonedDateTime.js index 2569beaf0f6b..96fa9b5b5a37 100644 --- a/JSTests/test262/test/staging/Temporal/Instant/old/toZonedDateTime.js +++ b/JSTests/test262/test/staging/Temporal/Instant/old/toZonedDateTime.js @@ -15,7 +15,29 @@ assert.throws(TypeError, () => inst.toZonedDateTime()); // throws with a string parameter assert.throws(TypeError, () => inst.toZonedDateTime("UTC")); -var fakeGregorian = { toString() { return "gregory"; }}; +var fakeGregorian = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "gregory", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; // time zone parameter UTC var timeZone = Temporal.TimeZone.from("UTC"); diff --git a/JSTests/test262/test/staging/Temporal/Regex/old/plaindate.js b/JSTests/test262/test/staging/Temporal/Regex/old/plaindate.js index 30c23a84f9f2..b726f0e0e73a 100644 --- a/JSTests/test262/test/staging/Temporal/Regex/old/plaindate.js +++ b/JSTests/test262/test/staging/Temporal/Regex/old/plaindate.js @@ -13,7 +13,7 @@ function test(isoString, components) { assert.sameValue(date.year, y); assert.sameValue(date.month, m); assert.sameValue(date.day, d); - assert.sameValue(date.calendar.id, cid); + assert.sameValue(date.calendarId, cid); } function generateTest(dateTimeString, zoneString) { var components = [ diff --git a/JSTests/test262/test/staging/Temporal/Regex/old/plaindatetime.js b/JSTests/test262/test/staging/Temporal/Regex/old/plaindatetime.js index 5771476f8de9..5526082d398c 100644 --- a/JSTests/test262/test/staging/Temporal/Regex/old/plaindatetime.js +++ b/JSTests/test262/test/staging/Temporal/Regex/old/plaindatetime.js @@ -19,7 +19,7 @@ function test(isoString, components) { assert.sameValue(datetime.millisecond, ms); assert.sameValue(datetime.microsecond, µs); assert.sameValue(datetime.nanosecond, ns); - assert.sameValue(datetime.calendar.id, cid); + assert.sameValue(datetime.calendarId, cid); } function generateTest(dateTimeString, zoneString) { var components = [ @@ -38,7 +38,7 @@ function generateTest(dateTimeString, zoneString) { test(`${ dateTimeString }:30.123456789${ zoneString }`, components); } -//valid strings +//valid strings [ "+0100[Europe/Vienna]", "+01:00[Europe/Vienna]", diff --git a/JSTests/test262/test/staging/Temporal/Regex/old/plainmonthday.js b/JSTests/test262/test/staging/Temporal/Regex/old/plainmonthday.js index 6623d912ca33..e68ef73c5649 100644 --- a/JSTests/test262/test/staging/Temporal/Regex/old/plainmonthday.js +++ b/JSTests/test262/test/staging/Temporal/Regex/old/plainmonthday.js @@ -12,7 +12,7 @@ function test(isoString, components) { var monthDay = Temporal.PlainMonthDay.from(isoString); assert.sameValue(monthDay.monthCode, `M${ m.toString().padStart(2, "0") }`); assert.sameValue(monthDay.day, d); - assert.sameValue(monthDay.calendar.id, cid); + assert.sameValue(monthDay.calendarId, cid); } function generateTest(dateTimeString, zoneString) { var components = [ diff --git a/JSTests/test262/test/staging/Temporal/Regex/old/plainyearmonth.js b/JSTests/test262/test/staging/Temporal/Regex/old/plainyearmonth.js index 1f34237d41a0..f6b1927c56a8 100644 --- a/JSTests/test262/test/staging/Temporal/Regex/old/plainyearmonth.js +++ b/JSTests/test262/test/staging/Temporal/Regex/old/plainyearmonth.js @@ -12,7 +12,7 @@ function test(isoString, components) { var yearMonth = Temporal.PlainYearMonth.from(isoString); assert.sameValue(yearMonth.year, y); assert.sameValue(yearMonth.month, m); - assert.sameValue(yearMonth.calendar.id, cid); + assert.sameValue(yearMonth.calendarId, cid); } function generateTest(dateTimeString, zoneString) { var components = [ diff --git a/JSTests/test262/test/staging/Temporal/UserCalendar/old/calendar-extra-fields.js b/JSTests/test262/test/staging/Temporal/UserCalendar/old/calendar-extra-fields.js index ee3b00628485..669bcc21d27b 100644 --- a/JSTests/test262/test/staging/Temporal/UserCalendar/old/calendar-extra-fields.js +++ b/JSTests/test262/test/staging/Temporal/UserCalendar/old/calendar-extra-fields.js @@ -4,13 +4,16 @@ /*--- esid: sec-temporal-zoneddatetime-objects description: calendar with extra fields -features: [Temporal] +features: [Temporal, Array.prototype.includes] ---*/ class SeasonCalendar extends Temporal.Calendar { constructor() { super("iso8601"); } + get id() { + return "season"; + } toString() { return "season"; } @@ -35,23 +38,25 @@ class SeasonCalendar extends Temporal.Calendar { return super.dateFromFields({ ...fields, monthCode - }, options); + }, options).withCalendar(this); } yearMonthFromFields(fields, options) { var monthCode = this._isoMonthCode(fields); delete fields.month; - return super.yearMonthFromFields({ + const { isoYear, isoMonth, isoDay } = super.yearMonthFromFields({ ...fields, monthCode - }, options); + }, options).getISOFields(); + return new Temporal.PlainYearMonth(isoYear, isoMonth, this, isoDay); } monthDayFromFields(fields, options) { var monthCode = this._isoMonthCode(fields); delete fields.month; - return super.monthDayFromFields({ + const { isoYear, isoMonth, isoDay } = super.monthDayFromFields({ ...fields, monthCode - }, options); + }, options).getISOFields(); + return new Temporal.PlainMonthDay(isoMonth, isoDay, this, isoYear); } fields(fields) { fields = fields.slice(); @@ -68,7 +73,7 @@ var monthday = new Temporal.PlainMonthDay(9, 15, calendar); var zoned = new Temporal.ZonedDateTime(1568505600000000000n, "UTC", calendar); var propDesc = { get() { - return this.calendar.season(this); + return this.getCalendar().season(this); }, configurable: true }; diff --git a/JSTests/test262/test/staging/Temporal/UserCalendar/old/calendar-non-trivial-mergefields.js b/JSTests/test262/test/staging/Temporal/UserCalendar/old/calendar-non-trivial-mergefields.js index 4a18631e075f..8c41d56b7b5a 100644 --- a/JSTests/test262/test/staging/Temporal/UserCalendar/old/calendar-non-trivial-mergefields.js +++ b/JSTests/test262/test/staging/Temporal/UserCalendar/old/calendar-non-trivial-mergefields.js @@ -4,13 +4,16 @@ /*--- esid: sec-temporal-zoneddatetime-objects description: calendar with nontrivial mergeFields implementation -features: [Temporal] +features: [Temporal, Array.prototype.includes] ---*/ class CenturyCalendar extends Temporal.Calendar { constructor() { super("iso8601"); } + get id() { + return 'century'; + } toString() { return "century"; } @@ -42,21 +45,23 @@ class CenturyCalendar extends Temporal.Calendar { return super.dateFromFields({ ...fields, year: isoYear - }, options); + }, options).withCalendar(this); } yearMonthFromFields(fields, options) { - var isoYear = this._validateFields(fields); - return super.yearMonthFromFields({ + var year = this._validateFields(fields); + const { isoYear, isoMonth, isoDay } = super.yearMonthFromFields({ ...fields, - year: isoYear - }, options); + year, + }, options).getISOFields(); + return new Temporal.PlainYearMonth(isoYear, isoMonth, this, isoDay); } monthDayFromFields(fields, options) { - var isoYear = this._validateFields(fields); - return super.monthDayFromFields({ + var year = this._validateFields(fields); + const { isoYear, isoMonth, isoDay } = super.monthDayFromFields({ ...fields, - year: isoYear - }, options); + year, + }, options).getISOFields(); + return new Temporal.PlainMonthDay(isoMonth, isoDay, this, isoYear); } fields(fields) { fields = fields.slice(); @@ -92,13 +97,13 @@ var zoned = new Temporal.ZonedDateTime(1568505600000000000n, "UTC", calendar); var propDesc = { century: { get() { - return this.calendar.century(this); + return this.getCalendar().century(this); }, configurable: true }, centuryYear: { get() { - return this.calendar.centuryYear(this); + return this.getCalendar().centuryYear(this); }, configurable: true } diff --git a/JSTests/test262/test/staging/Temporal/UserCalendar/old/trivial-protocol-implementation.js b/JSTests/test262/test/staging/Temporal/UserCalendar/old/trivial-protocol-implementation.js index 21a3d2ab4331..fcd2183ba65f 100644 --- a/JSTests/test262/test/staging/Temporal/UserCalendar/old/trivial-protocol-implementation.js +++ b/JSTests/test262/test/staging/Temporal/UserCalendar/old/trivial-protocol-implementation.js @@ -37,6 +37,7 @@ function isoToDecimal(date) { }; } var obj = { + id: 'decimal', toString() { return "decimal"; }, @@ -85,13 +86,41 @@ var obj = { var {days} = isoToDecimal(date); return days % 10 + 1; }, - mergeFields(fields, additionalFields) { - if ("month" in additionalFields || "monthCode" in additionalFields) { - let {month, monthCode, ...rest} = fields; - return {...rest, ...additionalFields}; - } - return {...fields, ...additionalFields}; -} + dateAdd() {}, // left as an exercise for the reader + dateUntil() {}, // ditto + dayOfWeek() { + throw new Error('no weeks'); + }, + dayOfYear(date) { + return isoToDecimal(date).days; + }, + daysInMonth() { + return 10; + }, + daysInWeek() { + throw new Error('no weeks'); + }, + daysInYear() { + return 100; + }, + fields(fields) { + return fields; + }, + inLeapYear() { + return false; + }, + mergeFields(fields, additional) { + return new Temporal.Calendar("iso8601").mergeFields(fields, additional) + }, + monthsInYear() { + return 10; + }, + weekOfYear() { + throw new Error('no weeks'); + }, + yearOfWeek(date) { + throw new Error('no weeks'); + }, }; var date = Temporal.PlainDate.from({ year: 184, @@ -188,12 +217,12 @@ assert.sameValue(md2.monthCode, "M01"); var tz = Temporal.TimeZone.from("UTC"); var inst = Temporal.Instant.fromEpochSeconds(0); var dt = tz.getPlainDateTimeFor(inst, obj); -assert.sameValue(dt.calendar.id, obj.id); +assert.sameValue(dt.getCalendar(), obj); // Temporal.Now.plainDateTime() var nowDateTime = Temporal.Now.plainDateTime(obj, "UTC"); -assert.sameValue(nowDateTime.calendar.id, obj.id); +assert.sameValue(nowDateTime.getCalendar(), obj); // Temporal.Now.plainDate() var nowDate = Temporal.Now.plainDate(obj, "UTC"); -assert.sameValue(nowDate.calendar.id, obj.id); +assert.sameValue(nowDate.getCalendar(), obj); diff --git a/JSTests/test262/test/staging/Temporal/UserCalendar/old/trivial-subclass.js b/JSTests/test262/test/staging/Temporal/UserCalendar/old/trivial-subclass.js index 32703b7010f0..d6ed5f78251c 100644 --- a/JSTests/test262/test/staging/Temporal/UserCalendar/old/trivial-subclass.js +++ b/JSTests/test262/test/staging/Temporal/UserCalendar/old/trivial-subclass.js @@ -25,25 +25,27 @@ class TwoBasedCalendar extends Temporal.Calendar { year, monthCode: `M${ (month - 1).toString().padStart(2, "0") }`, day - }, options); + }, options).withCalendar(this); } yearMonthFromFields(fields, options) { var {year, month, monthCode} = fields; if (month === undefined) month = +monthCode.slice(1); - return super.yearMonthFromFields({ + const { isoYear, isoMonth, isoDay } = super.yearMonthFromFields({ year, monthCode: `M${ (month - 1).toString().padStart(2, "0") }` - }, options); + }, options).getISOFields(); + return new Temporal.PlainYearMonth(isoYear, isoMonth, this, isoDay); } monthDayFromFields(fields, options) { var {month, monthCode, day} = fields; if (month === undefined) month = +monthCode.slice(1); - return super.monthDayFromFields({ + const { isoYear, isoMonth, isoDay } = super.monthDayFromFields({ monthCode: `M${ (month - 1).toString().padStart(2, "0") }`, day - }, options); + }, options).getISOFields(); + return new Temporal.PlainMonthDay(isoMonth, isoDay, this, isoYear); } month(date) { return date.getISOFields().isoMonth + 1; @@ -151,12 +153,12 @@ assert.sameValue(md2.monthCode, "M02"); var tz = Temporal.TimeZone.from("UTC"); var instant = Temporal.Instant.fromEpochSeconds(0); var dt = tz.getPlainDateTimeFor(instant, obj); -assert.sameValue(dt.calendar.id, obj.id); +assert.sameValue(dt.getCalendar(), obj); // Temporal.Now.plainDateTime() var nowDateTime = Temporal.Now.plainDateTime(obj, "UTC"); -assert.sameValue(nowDateTime.calendar.id, obj.id); +assert.sameValue(nowDateTime.getCalendar(), obj); // Temporal.Now.plainDate() var nowDate = Temporal.Now.plainDate(obj, "UTC"); -assert.sameValue(nowDate.calendar.id, obj.id); +assert.sameValue(nowDate.getCalendar(), obj); diff --git a/JSTests/test262/test/staging/Temporal/UserTimezone/old/subminute-offset.js b/JSTests/test262/test/staging/Temporal/UserTimezone/old/subminute-offset.js index 5b17b90a19f3..4d6e925aeb8a 100644 --- a/JSTests/test262/test/staging/Temporal/UserTimezone/old/subminute-offset.js +++ b/JSTests/test262/test/staging/Temporal/UserTimezone/old/subminute-offset.js @@ -50,7 +50,29 @@ assert.throws(RangeError, () => Temporal.TimeZone.from("2020-05-26T16:02:46.2511 assert.sameValue(obj.getOffsetStringFor(inst), "-00:00:01.111111111") // converts to DateTime -var fakeGregorian = { toString() { return "gregory"; }}; +var fakeGregorian = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "gregory", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; assert.sameValue(`${ obj.getPlainDateTimeFor(inst) }`, "1969-12-31T23:59:58.888888889"); assert.sameValue(`${ obj.getPlainDateTimeFor(inst, fakeGregorian) }`, "1969-12-31T23:59:58.888888889[u-ca=gregory]"); diff --git a/JSTests/test262/test/staging/Temporal/UserTimezone/old/trivial-protocol.js b/JSTests/test262/test/staging/Temporal/UserTimezone/old/trivial-protocol.js index c4059ad3b267..3c9be788ee9b 100644 --- a/JSTests/test262/test/staging/Temporal/UserTimezone/old/trivial-protocol.js +++ b/JSTests/test262/test/staging/Temporal/UserTimezone/old/trivial-protocol.js @@ -18,9 +18,7 @@ var obj = { var epochNs = MakeDate(dayNum, time); return [new Temporal.Instant(epochNs)]; }, - toString() { - return "Etc/Custom/UTC_Protocol"; - } + id: "Etc/Custom/UTC_Protocol", }; var inst = Temporal.Instant.fromEpochNanoseconds(0n); @@ -32,7 +30,29 @@ var zdt = new Temporal.ZonedDateTime(0n, obj); assert.sameValue(zdt.toString(), "1970-01-01T00:00:00+00:00[Etc/Custom/UTC_Protocol]"); // works in Temporal.Now -var fakeGregorian = { toString() { return "gregory"; }}; +var fakeGregorian = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "gregory", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; assert(Temporal.Now.plainDateTimeISO(obj) instanceof Temporal.PlainDateTime); assert(Temporal.Now.plainDateTime(fakeGregorian, obj) instanceof Temporal.PlainDateTime); assert(Temporal.Now.plainDateISO(obj) instanceof Temporal.PlainDate); diff --git a/JSTests/test262/test/staging/Temporal/UserTimezone/old/trivial-subclass.js b/JSTests/test262/test/staging/Temporal/UserTimezone/old/trivial-subclass.js index 4e1e84c0ae39..e8ae4c94a261 100644 --- a/JSTests/test262/test/staging/Temporal/UserTimezone/old/trivial-subclass.js +++ b/JSTests/test262/test/staging/Temporal/UserTimezone/old/trivial-subclass.js @@ -88,7 +88,29 @@ assert.throws(RangeError, () => Temporal.TimeZone.from("2020-05-26T16:02:46.2511 assert.sameValue(obj.getOffsetStringFor(inst), "+00:00") // converts to DateTime -var fakeGregorian = { toString() { return "gregory"; }}; +var fakeGregorian = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "gregory", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; assert.sameValue(`${ obj.getPlainDateTimeFor(inst) }`, "1970-01-01T00:00:00"); assert.sameValue(`${ obj.getPlainDateTimeFor(inst, fakeGregorian) }`, "1970-01-01T00:00:00[u-ca=gregory]"); diff --git a/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/compare.js b/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/compare.js index 209af7e262c6..05678af3d050 100644 --- a/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/compare.js +++ b/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/compare.js @@ -111,7 +111,29 @@ assert.throws(TypeError, () => Temporal.ZonedDateTime.compare(zdt1, { assert.sameValue(Temporal.ZonedDateTime.compare(zdt1, zdt1.withTimeZone("+05:30")), 0); // disregards calendar IDs if exact times and time zones are equal -var fakeJapanese = { toString() { return "japanese"; }}; +var fakeJapanese = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "japanese", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; assert.sameValue(Temporal.ZonedDateTime.compare(zdt1, zdt1.withCalendar(fakeJapanese)), 0); // compares exact time, not clock time diff --git a/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/construction-and-properties.js b/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/construction-and-properties.js index 24a486ce36b6..0f38219641fa 100644 --- a/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/construction-and-properties.js +++ b/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/construction-and-properties.js @@ -19,7 +19,7 @@ assert.sameValue(zdt.toInstant().epochSeconds, Math.floor(Date.UTC(1976, 10, 18, assert.sameValue(zdt.toInstant().epochMilliseconds, Date.UTC(1976, 10, 18, 15, 23, 30, 123), "epochMilliseconds"); // Temporal.ZonedDateTime for (1976, 11, 18, 15, 23, 30, 123, 456, 789)" - var zdt = new Temporal.ZonedDateTime(epochNanos, new Temporal.TimeZone("UTC")); + var zdt = new Temporal.ZonedDateTime(epochNanos, "UTC"); // can be constructed assert(zdt instanceof Temporal.ZonedDateTime); assert.sameValue(typeof zdt, "object"); @@ -66,11 +66,20 @@ var fakeGregorian = { daysInYear(date) { return date.withCalendar("iso8601").daysInYear; }, monthsInYear(date) { return date.withCalendar("iso8601").monthsInYear; }, inLeapYear(date) { return date.withCalendar("iso8601").inLeapYear; }, - toString() { return "gregory"; }, + id: "gregory", + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + fields() {}, + mergeFields() {}, + monthDayFromFields() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, }; var fakeVienna = { getOffsetNanosecondsFor() { return 3600_000_000_000; }, - toString() { return "Europe/Vienna"; }, + getPossibleInstantsFor(datetime) { return [datetime.toZonedDateTime("+01:00").toInstant()]; }, + id: "Europe/Vienna", } var zdt = new Temporal.ZonedDateTime(epochNanos, fakeVienna, fakeGregorian); assert(zdt instanceof Temporal.ZonedDateTime); diff --git a/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/equals.js b/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/equals.js index f6e831afc82e..b2623050eee6 100644 --- a/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/equals.js +++ b/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/equals.js @@ -8,13 +8,32 @@ features: [Temporal] ---*/ var tz = { + getOffsetNanosecondsFor() { return -5 * 3600_000_000_000; }, getPossibleInstantsFor(pdt) { return Temporal.TimeZone.from("-05:00").getPossibleInstantsFor(pdt); }, - toString() { return "America/New_York"; }, + id: "America/New_York", }; var cal = { dateFromFields(...args) { return Temporal.Calendar.from("iso8601").dateFromFields(...args); }, - toString() { return "gregory"; }, + id: "gregory", + dateAdd() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, fields(fieldNames) { return fieldNames; }, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, }; var zdt = new Temporal.ZonedDateTime(0n, tz, cal); diff --git a/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/since.js b/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/since.js index 028d4df4e6ba..627defe61383 100644 --- a/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/since.js +++ b/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/since.js @@ -87,7 +87,29 @@ assert.notSameValue(monthsDifference.months, 0); // no two different calendars var zdt1 = new Temporal.ZonedDateTime(0n, "UTC"); -var fakeJapanese = { toString() { return "japanese"; }}; +var fakeJapanese = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "japanese", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; var zdt2 = new Temporal.ZonedDateTime(0n, "UTC", fakeJapanese); assert.throws(RangeError, () => zdt1.since(zdt2)); diff --git a/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/toPlainDate.js b/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/toPlainDate.js index 4c465aebcb3a..21577e560d9f 100644 --- a/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/toPlainDate.js +++ b/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/toPlainDate.js @@ -14,9 +14,31 @@ var zdt = Temporal.Instant.from("2019-10-29T09:46:38.271986102Z").toZonedDateTim assert.sameValue(`${ zdt.toPlainDate() }`, "2019-10-29"); // preserves the calendar -const fakeGregorian = { toString() { return "gregory" }}; +const fakeGregorian = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "gregory", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; var zdt = Temporal.Instant.from("2019-10-29T09:46:38.271986102Z").toZonedDateTime({ timeZone: tz, calendar: fakeGregorian }); -assert.sameValue(zdt.toPlainDate().calendar, fakeGregorian); +assert.sameValue(zdt.toPlainDate().getCalendar(), fakeGregorian); diff --git a/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/toPlainMonthDay.js b/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/toPlainMonthDay.js index 9ae4f4e2f021..e0ca0b7c2aa1 100644 --- a/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/toPlainMonthDay.js +++ b/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/toPlainMonthDay.js @@ -15,6 +15,7 @@ assert.sameValue(`${ zdt.toPlainMonthDay() }`, "10-29"); // preserves the calendar var fakeGregorian = { + id: 'gregory', monthDayFromFields(fields) { var md = Temporal.Calendar.from("iso8601").monthDayFromFields(fields); var {isoYear, isoMonth, isoDay} = md.getISOFields(); @@ -22,11 +23,26 @@ var fakeGregorian = { }, monthCode(date) { return date.withCalendar("iso8601").monthCode; }, day(date) { return date.withCalendar("iso8601").day; }, - toString() { return "gregory"; }, + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, fields(fieldNames) { return fieldNames; }, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, }; var zdt = Temporal.Instant.from("2019-10-29T09:46:38.271986102Z").toZonedDateTime({ timeZone: tz, calendar: fakeGregorian }); -assert.sameValue(zdt.toPlainMonthDay().calendar, fakeGregorian); +assert.sameValue(zdt.toPlainMonthDay().getCalendar(), fakeGregorian); diff --git a/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/toPlainYearMonth.js b/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/toPlainYearMonth.js index 9985d0d09f6c..1b33d284f14f 100644 --- a/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/toPlainYearMonth.js +++ b/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/toPlainYearMonth.js @@ -15,6 +15,7 @@ assert.sameValue(`${ zdt.toPlainYearMonth() }`, "2019-10"); // preserves the calendar var fakeGregorian = { + id: 'gregory', yearMonthFromFields(fields) { var ym = Temporal.Calendar.from("iso8601").yearMonthFromFields(fields); var {isoYear, isoMonth, isoDay} = ym.getISOFields(); @@ -22,11 +23,26 @@ var fakeGregorian = { }, year(date) { return date.withCalendar("iso8601").year; }, monthCode(date) { return date.withCalendar("iso8601").monthCode; }, - toString() { return "gregory"; }, + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, fields(fieldNames) { return fieldNames; }, + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + yearOfWeek() {}, }; var zdt = Temporal.Instant.from("2019-10-29T09:46:38.271986102Z").toZonedDateTime({ timeZone: tz, calendar: fakeGregorian }); -assert.sameValue(zdt.toPlainYearMonth().calendar, fakeGregorian); +assert.sameValue(zdt.toPlainYearMonth().getCalendar(), fakeGregorian); diff --git a/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/toString.js b/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/toString.js index 7703f05e7b99..13c860ff56a5 100644 --- a/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/toString.js +++ b/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/toString.js @@ -9,7 +9,29 @@ features: [Temporal] ---*/ var zdt1 = Temporal.ZonedDateTime.from("1976-11-18T15:23+00:00[UTC]"); -var fakeGregorian = { toString() { return "gregory" }}; +var fakeGregorian = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "gregory", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; // shows offset if offset = auto assert.sameValue(zdt1.toString({ offset: "auto" }), "1976-11-18T15:23:00+00:00[UTC]"); diff --git a/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/until.js b/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/until.js index 876af409d2c7..67280f879a5c 100644 --- a/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/until.js +++ b/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/until.js @@ -87,7 +87,29 @@ assert.notSameValue(monthsDifference.months, 0); // no two different calendars var zdt1 = new Temporal.ZonedDateTime(0n, "UTC"); -var fakeJapanese = { toString() { return "japanese"; }}; +var fakeJapanese = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "japanese", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; var zdt2 = new Temporal.ZonedDateTime(0n, "UTC", fakeJapanese); assert.throws(RangeError, () => zdt1.until(zdt2)); diff --git a/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/withCalendar.js b/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/withCalendar.js index 4abf5568d20c..db9dec80771d 100644 --- a/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/withCalendar.js +++ b/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/withCalendar.js @@ -10,12 +10,34 @@ features: [Temporal] var zdt = Temporal.ZonedDateTime.from("2019-11-18T15:23:30.123456789-08:00[-08:00]"); // zonedDateTime.withCalendar(japanese) works -var cal = { toString() { return "japanese"; }}; +var cal = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "japanese", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; assert.sameValue(`${ zdt.withCalendar(cal) }`, "2019-11-18T15:23:30.123456789-08:00[-08:00][u-ca=japanese]"); // keeps instant and time zone the same var zdt = Temporal.ZonedDateTime.from("2019-11-18T15:23:30.123456789+01:00[+01:00][u-ca=iso8601]"); var zdt2 = zdt.withCalendar(cal); assert.sameValue(zdt.epochNanoseconds, zdt2.epochNanoseconds); -assert.sameValue(zdt2.calendar, cal); -assert.sameValue(zdt2.timeZone.id, "+01:00"); +assert.sameValue(zdt2.getCalendar(), cal); +assert.sameValue(zdt2.timeZoneId, "+01:00"); diff --git a/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/withPlainDate.js b/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/withPlainDate.js index 9131a4f706b2..74a1048631f6 100644 --- a/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/withPlainDate.js +++ b/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/withPlainDate.js @@ -27,7 +27,29 @@ assert.sameValue(`${ zdt.withPlainDate(date) }`, "2020-01-23T03:24:30-08:00[Cust assert.sameValue(`${ zdt.withPlainDate("2018-09-15") }`, "2018-09-15T03:24:30-08:00[Custom/Spring_Fall]"); // result contains a non-ISO calendar if present in the input -var fakeJapanese = { toString() { return "japanese"; }}; +var fakeJapanese = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "japanese", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; assert.sameValue(`${ zdt.withCalendar(fakeJapanese).withPlainDate("2008-09-06") }`, "2008-09-06T03:24:30-08:00[Custom/Spring_Fall][u-ca=japanese]"); // calendar is unchanged if input has ISO calendar @@ -35,7 +57,29 @@ var date = new Temporal.PlainDate(2008, 9, 6, fakeJapanese); assert.sameValue(`${ zdt.withPlainDate(date) }`, "2008-09-06T03:24:30-08:00[Custom/Spring_Fall][u-ca=japanese]"); // throws if both `this` and `other` have a non-ISO calendar -var fakeGregorian = { toString() { return "gregory"; }}; +var fakeGregorian = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "gregory", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; assert.throws(RangeError, () => zdt.withCalendar(fakeGregorian).withPlainDate(date)); // object must contain at least one correctly-spelled property diff --git a/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/withTimezone.js b/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/withTimezone.js index 56b7c54cf16b..f05c2c527749 100644 --- a/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/withTimezone.js +++ b/JSTests/test262/test/staging/Temporal/ZonedDateTime/old/withTimezone.js @@ -8,10 +8,32 @@ features: [Temporal] ---*/ // keeps instant and calendar the same -var fakeGregorian = { toString() { return "gregory"; }}; +var fakeGregorian = { + dateAdd() {}, + dateFromFields() {}, + dateUntil() {}, + day() {}, + dayOfWeek() {}, + dayOfYear() {}, + daysInMonth() {}, + daysInWeek() {}, + daysInYear() {}, + fields() {}, + id: "gregory", + inLeapYear() {}, + mergeFields() {}, + month() {}, + monthCode() {}, + monthDayFromFields() {}, + monthsInYear() {}, + weekOfYear() {}, + year() {}, + yearMonthFromFields() {}, + yearOfWeek() {}, +}; var zdt = Temporal.ZonedDateTime.from("2019-11-18T15:23:30.123456789+01:00[+01:00]").withCalendar(fakeGregorian); var zdt2 = zdt.withTimeZone("-08:00"); assert.sameValue(zdt.epochNanoseconds, zdt2.epochNanoseconds); -assert.sameValue(zdt2.calendar, fakeGregorian); -assert.sameValue(zdt2.timeZone.id, "-08:00"); +assert.sameValue(zdt2.getCalendar(), fakeGregorian); +assert.sameValue(zdt2.timeZoneId, "-08:00"); assert.notSameValue(`${ zdt.toPlainDateTime() }`, `${ zdt2.toPlainDateTime() }`); diff --git a/JSTests/test262/test262-Revision.txt b/JSTests/test262/test262-Revision.txt index cd8cd715691d..a33eb23f5fc2 100644 --- a/JSTests/test262/test262-Revision.txt +++ b/JSTests/test262/test262-Revision.txt @@ -1,2 +1,2 @@ -test262 remote url: https://github.com/tc39/test262.git -test262 revision: d216cc197269fc41eb6eca14710529c3d6650535 +test262 remote url: git@github.com:tc39/test262.git +test262 revision: 8ce9864511c1c83ba2d0b351da3390c9e33fd60e