diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2555b5a572..8331a39b73 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -290,6 +290,7 @@ Function | Purpose `assert.sameValue(actual, expected, message)` | throw a new Test262Error instance if the first two arguments are not [the same value](https://tc39.github.io/ecma262/#sec-samevalue); accepts an optional string message explaining the scenario and what should have happened `assert.notSameValue(actual, unexpected, message)` | throw a new Test262Error instance if the first two arguments are [the same value](https://tc39.github.io/ecma262/#sec-samevalue); accepts an optional string message explaining the scenario and what should have happened `assert.throws(expectedErrorConstructor, fn, message)` | throw a new Test262Error instance if the provided function does not throw an error or if the constructor of the value thrown does not match the provided constructor; accepts an optional string message explaining the scenario and what should have happened +`assert.compareArray(actual, expected, message)` | throw a new Test262Error instance if the first two arguments have differing `length` or there is an array index less than that length at which their respective elements are not [the same value](https://tc39.github.io/ecma262/#sec-samevalue); accepts an optional string message explaining the scenario and what should have happened `$DONOTEVALUATE()` | throw an exception if the code gets evaluated. This may only be used in [negative test cases for parsing errors](#handling-errors-and-negative-test-cases). `throw "Test262: This statement should not be evaluated.";` | throw an exception if the code gets evaluated. Use this if the test file has the `raw` flag and it's a negative test case for parsing error. diff --git a/features.txt b/features.txt index 4d81e7cb18..f48d5412c3 100644 --- a/features.txt +++ b/features.txt @@ -11,6 +11,10 @@ # # https://github.com/tc39/process-document +# Intl Era Monthcode +# https://github.com/tc39/proposal-intl-era-monthcode +Intl.Era-monthcode + # Intl.Locale Info # https://github.com/tc39/proposal-intl-locale-info Intl.Locale-info @@ -50,20 +54,12 @@ json-parse-with-source # https://github.com/tc39/proposal-explicit-resource-management explicit-resource-management -# Math.sumPrecise -# https://github.com/tc39/proposal-math-sum -Math.sumPrecise - # Source Phase Imports ## https://github.com/tc39/proposal-source-phase-imports source-phase-imports ## test262 special specifier source-phase-imports-module-source -# Uint8Array Base64 -# https://github.com/tc39/proposal-arraybuffer-base64 -uint8array-base64 - # Atomics.pause # https://github.com/tc39/proposal-atomics-microwait Atomics.pause @@ -184,6 +180,7 @@ json-superset let logical-assignment-operators Map +Math.sumPrecise new.target numeric-separator-literal object-rest @@ -255,6 +252,7 @@ TypedArray TypedArray.prototype.at u180e Uint8Array +uint8array-base64 Uint16Array Uint32Array Uint8ClampedArray diff --git a/harness/assert.js b/harness/assert.js index 70fb490fd9..7ced0cd0b4 100644 --- a/harness/assert.js +++ b/harness/assert.js @@ -101,6 +101,45 @@ assert.throws = function (expectedErrorConstructor, func, message) { throw new Test262Error(message); }; +function isPrimitive(value) { + return !value || (typeof value !== 'object' && typeof value !== 'function'); +} + +assert.compareArray = function (actual, expected, message) { + message = message === undefined ? '' : message; + + if (typeof message === 'symbol') { + message = message.toString(); + } + + if (isPrimitive(actual)) { + assert(false, `Actual argument [${actual}] shouldn't be primitive. ${message}`); + } else if (isPrimitive(expected)) { + assert(false, `Expected argument [${expected}] shouldn't be primitive. ${message}`); + } + var result = compareArray(actual, expected); + if (result) return; + + var format = compareArray.format; + assert(false, `Actual ${format(actual)} and expected ${format(expected)} should have the same contents. ${message}`); +}; + +function compareArray(a, b) { + if (b.length !== a.length) { + return false; + } + for (var i = 0; i < a.length; i++) { + if (!assert._isSameValue(b[i], a[i])) { + return false; + } + } + return true; +} + +compareArray.format = function (arrayLike) { + return `[${Array.prototype.map.call(arrayLike, String).join(', ')}]`; +}; + assert._formatIdentityFreeValue = function formatIdentityFreeValue(value) { switch (value === null ? 'null' : typeof value) { case 'string': diff --git a/harness/compareArray.js b/harness/compareArray.js index 2af35eeae3..dfeef3fe6b 100644 --- a/harness/compareArray.js +++ b/harness/compareArray.js @@ -2,49 +2,6 @@ // This code is governed by the BSD license found in the LICENSE file. /*--- description: | - Compare the contents of two arrays + Deprecated now that compareArray is defined in assert.js. defines: [compareArray] ---*/ - -function compareArray(a, b) { - if (b.length !== a.length) { - return false; - } - - for (var i = 0; i < a.length; i++) { - if (!compareArray.isSameValue(b[i], a[i])) { - return false; - } - } - return true; -} - -compareArray.isSameValue = function(a, b) { - if (a === 0 && b === 0) return 1 / a === 1 / b; - if (a !== a && b !== b) return true; - - return a === b; -}; - -compareArray.format = function(arrayLike) { - return `[${[].map.call(arrayLike, String).join(', ')}]`; -}; - -assert.compareArray = function(actual, expected, message) { - message = message === undefined ? '' : message; - - if (typeof message === 'symbol') { - message = message.toString(); - } - - assert(actual != null, `Actual argument shouldn't be nullish. ${message}`); - assert(expected != null, `Expected argument shouldn't be nullish. ${message}`); - var format = compareArray.format; - var result = compareArray(actual, expected); - - // The following prevents actual and expected from being iterated and evaluated - // more than once unless absolutely necessary. - if (!result) { - assert(false, `Actual ${format(actual)} and expected ${format(expected)} should have the same contents. ${message}`); - } -}; diff --git a/harness/sm/non262-Math-shell.js b/harness/sm/non262-Math-shell.js index 6d467c90f3..1afea3a1ff 100644 --- a/harness/sm/non262-Math-shell.js +++ b/harness/sm/non262-Math-shell.js @@ -1,5 +1,5 @@ /*--- -defines: [assertNear] +defines: [assertNear, ONE_PLUS_EPSILON, ONE_MINUS_EPSILON] ---*/ // The nearest representable values to +1.0. @@ -50,10 +50,20 @@ const ONE_MINUS_EPSILON = 1 - Math.pow(2, -53); // 1.0000000000000002 ENDIAN = 0; // try little-endian first if (diff(2, 4) === 0x100000) // exact wrong answer we'll get on a big-endian platform ENDIAN = 1; - assert.sameValue(diff(2,4), 0x10000000000000); - assert.sameValue(diff(0, Number.MIN_VALUE), 1); - assert.sameValue(diff(1, ONE_PLUS_EPSILON), 1); - assert.sameValue(diff(1, ONE_MINUS_EPSILON), 1); + // For test262-harness compatibility, + // avoid `assert.sameValue` while still defining functions. + // https://github.com/bocoup/test262-stream/issues/34 + const assertDiffResult = (a, b, expect, detail) => { + const result = diff(a, b); + if (result === expect) return; + throw new Error( + `Expected diff(${a}, ${b}) to be ${expect} but got ${result} [${detail}]` + ); + }; + assertDiffResult(2, 4, 0x10000000000000, "wanted 0x10000000000000"); + assertDiffResult(0, Number.MIN_VALUE, 1, "0 vs. Number.MIN_VALUE"); + assertDiffResult(1, ONE_PLUS_EPSILON, 1, "1 vs. ONE_PLUS_EPSILON"); + assertDiffResult(1, ONE_MINUS_EPSILON, 1, "1 vs. ONE_MINUS_EPSILON"); var assertNear = function assertNear(a, b, tolerance=1) { if (!Number.isFinite(b)) { diff --git a/test/built-ins/Object/assign/target-Array.js b/test/built-ins/Object/assign/target-Array.js new file mode 100644 index 0000000000..01af654d09 --- /dev/null +++ b/test/built-ins/Object/assign/target-Array.js @@ -0,0 +1,105 @@ +// Copyright 2015 Microsoft Corporation. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +esid: sec-object.assign +description: > + Object.assign with an Array Exotic Object target employs the corresponding + internal methods. +info: | + Object.assign ( _target_, ..._sources_ ) + 3.a.iii.2.b. Perform ? Set(_to_, _nextKey_, _propValue_, *true*). + + Set ( _O_, _P_, _V_, _Throw_ ) + 1. Let _success_ be ? _O_.[[Set]](_P_, _V_, _O_). + + OrdinarySet ( _O_, _P_, _V_, _Receiver_ ) + 1. Let _ownDesc_ be ? _O_.[[GetOwnProperty]](_P_). + 2. Return ? OrdinarySetWithOwnDescriptor(_O_, _P_, _V_, _Receiver_, _ownDesc_). + + OrdinarySetWithOwnDescriptor ( _O_, _P_, _V_, _Receiver_, _ownDesc_ ) + 1. If _ownDesc_ is *undefined*, then + a. Let _parent_ be ? O.[[GetPrototypeOf]](). + b. If _parent_ is not *null*, then + i. Return ? _parent_.[[Set]](_P_, _V_, _Receiver_). + c. Else, + i. Set _ownDesc_ to the PropertyDescriptor { [[Value]]: *undefined*, [[Writable]]: *true*, [[Enumerable]]: *true*, [[Configurable]]: *true* }. + 2. If IsDataDescriptor(_ownDesc_) is *true*, then + ... + c. Let _existingDescriptor_ be ? _Receiver_.[[GetOwnProperty]](_P_). + d. If _existingDescriptor_ is not *undefined*, then + ... + iii. Let _valueDesc_ be the PropertyDescriptor { [[Value]]: _V_ }. + iv. Return ? _Receiver_.[[DefineOwnProperty]](_P_, _valueDesc_). + e. Else, + i. Assert: _Receiver_ does not currently have a property _P_. + ii. Return ? CreateDataProperty(_Receiver_, _P_, _V_). + + CreateDataProperty ( _O_, _P_, _V_ ) + 1. Let _newDesc_ be the PropertyDescriptor { [[Value]]: _V_, [[Writable]]: *true*, [[Enumerable]]: *true*, [[Configurable]]: *true* }. + 2. Return ? _O_.[[DefineOwnProperty]](_P_, _newDesc_). + + Array exotic object [[DefineOwnProperty]] ( _P_, _Desc_ ) + 1. If _P_ is *"length"*, then + a. Return ? ArraySetLength(_A_, _Desc_). + 2. Else if _P_ is an array index, then + ... + k. If _index_ ≥ _length_, then + i. Set _lengthDesc_.[[Value]] to _index_ + *1*𝔽. + ii. Set _succeeded_ to ! OrdinaryDefineOwnProperty(_A_, *"length"*, _lengthDesc_). + 3. Return ? OrdinaryDefineOwnProperty(_A_, _P_, _Desc_). + + The Object Type + An **integer index** is a property name _n_ such that CanonicalNumericIndexString(_n_) returns an + integral Number in the inclusive interval from *+0*𝔽 to 𝔽(2**53 - 1). An **array index** is an + integer index _n_ such that CanonicalNumericIndexString(_n_) returns an integral Number in the + inclusive interval from *+0*𝔽 to 𝔽(2**32 - 2). +---*/ + +var target = [7, 8, 9]; +var result = Object.assign(target, [1]); +assert.sameValue(result, target); +assert.compareArray(result, [1, 8, 9], + "elements must be assigned from an array source onto an array target"); + +var sparseArraySource = []; +sparseArraySource[2] = 3; +result = Object.assign(target, sparseArraySource); +assert.sameValue(result, target); +assert.compareArray(result, [1, 8, 3], "holes in a sparse array source must not be copied"); + +var shortObjectSource = { 1: 2, length: 2 }; +shortObjectSource["-0"] = -1; +shortObjectSource["1.5"] = -2; +shortObjectSource["4294967295"] = -3; // 2**32 - 1 +result = Object.assign(target, shortObjectSource); +assert.sameValue(result, target); +assert.compareArray(result, [1, 2], + "array index properties must be copied from a non-array source"); +assert.sameValue(result["-0"], -1, + "a property with name -0 must be assigned onto an array target"); +assert.sameValue(result["1.5"], -2, + "a property with name 1.5 must be assigned onto an array target"); +assert.sameValue(result["4294967295"], -3, + "a property with name 4294967295 (2**32 - 1) must be assigned onto an array target"); + +result = Object.assign(target, { length: 1 }); +assert.sameValue(result, target); +assert.compareArray(result, [1], "assigning a short length must shrink an array target"); + +result = Object.assign(target, { 2: 0 }); +assert.sameValue(result, target); +assert.compareArray(result, [1, undefined, 0], + "assigning a high array index must grow an array target"); + +if (typeof Proxy !== 'undefined') { + var accordionSource = new Proxy({ length: 0, 1: 9 }, { + ownKeys: function() { + return ["length", "1"]; + } + }); + result = Object.assign(target, accordionSource); + assert.sameValue(result, target); + assert.compareArray(result, [undefined, 9], + "assigning a short length before a high array index must shrink and then grow an array target"); +} diff --git a/test/built-ins/Promise/withResolvers/resolvers.js b/test/built-ins/Promise/withResolvers/resolvers.js index 41dcac05e6..aa43d6603f 100644 --- a/test/built-ins/Promise/withResolvers/resolvers.js +++ b/test/built-ins/Promise/withResolvers/resolvers.js @@ -11,6 +11,8 @@ features: [promise-with-resolvers] var instance = Promise.withResolvers(); assert.sameValue(typeof instance.resolve, 'function', 'type of resolve property'); +assert.sameValue(instance.resolve.name, ""); assert.sameValue(instance.resolve.length, 1, 'length of resolve property'); assert.sameValue(typeof instance.reject, 'function', 'type of reject property'); +assert.sameValue(instance.reject.name, ""); assert.sameValue(instance.reject.length, 1, 'length of reject property'); diff --git a/test/built-ins/Temporal/Duration/compare/argument-propertybag-optional-properties.js b/test/built-ins/Temporal/Duration/compare/argument-propertybag-optional-properties.js new file mode 100644 index 0000000000..8b35ebbb12 --- /dev/null +++ b/test/built-ins/Temporal/Duration/compare/argument-propertybag-optional-properties.js @@ -0,0 +1,29 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.compare +description: > + A property bag missing optional properties is equivalent to a property bag + with all the optional properties having their default values +features: [Temporal] +---*/ + +const oneProperty = { + hours: 1, +}; +const allProperties = { + years: 0, + months: 0, + weeks: 0, + days: 0, + hours: 1, + minutes: 0, + seconds: 0, + milliseconds: 0, + microseconds: 0, + nanoseconds: 0, +}; +const resultWithout = Temporal.Duration.compare(oneProperty, oneProperty); +const resultWith = Temporal.Duration.compare(allProperties, allProperties); +assert.sameValue(resultWithout, resultWith, "results should be the same with and without optional properties"); diff --git a/test/built-ins/Temporal/Duration/compare/relativeto-propertybag-optional-properties.js b/test/built-ins/Temporal/Duration/compare/relativeto-propertybag-optional-properties.js new file mode 100644 index 0000000000..00d02d6ea5 --- /dev/null +++ b/test/built-ins/Temporal/Duration/compare/relativeto-propertybag-optional-properties.js @@ -0,0 +1,37 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.compare +description: > + A property bag missing optional properties is equivalent to a property bag + with all the optional properties having their default values +features: [Temporal] +---*/ + +const duration1 = new Temporal.Duration(1); +const duration2 = new Temporal.Duration(0, 1); + +let relativeTo = { + year: 2021, + month: 10, + day: 28, + timeZone: "UTC", +}; +const resultWithout = Temporal.Duration.compare(duration1, duration2, { relativeTo }); +relativeTo = { + year: 2021, + month: 10, + day: 28, + hour: 0, + minute: 0, + second: 0, + millisecond: 0, + microsecond: 0, + nanosecond: 0, + offset: "+00:00", + timeZone: "UTC", + calendar: "iso8601", +}; +const resultWith = Temporal.Duration.compare(duration1, duration2, { relativeTo }); +assert.sameValue(resultWithout, resultWith, "results should be the same with and without optional properties"); diff --git a/test/built-ins/Temporal/Duration/from/argument-propertybag-optional-properties.js b/test/built-ins/Temporal/Duration/from/argument-propertybag-optional-properties.js new file mode 100644 index 0000000000..60f7e1e28c --- /dev/null +++ b/test/built-ins/Temporal/Duration/from/argument-propertybag-optional-properties.js @@ -0,0 +1,30 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.from +description: > + A property bag missing optional properties is equivalent to a property bag + with all the optional properties having their default values +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const oneProperty = { + hours: 1, +}; +const allProperties = { + years: 0, + months: 0, + weeks: 0, + days: 0, + hours: 1, + minutes: 0, + seconds: 0, + milliseconds: 0, + microseconds: 0, + nanoseconds: 0, +}; +const resultWithout = Temporal.Duration.from(oneProperty); +const resultWith = Temporal.Duration.from(allProperties); +TemporalHelpers.assertDurationsEqual(resultWithout, resultWith, "results should be the same with and without optional properties"); diff --git a/test/built-ins/Temporal/Duration/prototype/add/argument-propertybag-optional-properties.js b/test/built-ins/Temporal/Duration/prototype/add/argument-propertybag-optional-properties.js new file mode 100644 index 0000000000..b07f20f76c --- /dev/null +++ b/test/built-ins/Temporal/Duration/prototype/add/argument-propertybag-optional-properties.js @@ -0,0 +1,32 @@ +// Copyright (C) 2025 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 property bag missing optional properties is equivalent to a property bag + with all the optional properties having their default values +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Duration(); + +const oneProperty = { + hours: 1, +}; +const allProperties = { + years: 0, + months: 0, + weeks: 0, + days: 0, + hours: 1, + minutes: 0, + seconds: 0, + milliseconds: 0, + microseconds: 0, + nanoseconds: 0, +}; +const resultWithout = instance.add(oneProperty); +const resultWith = instance.add(allProperties); +TemporalHelpers.assertDurationsEqual(resultWithout, resultWith, "results should be the same with and without optional properties"); diff --git a/test/built-ins/Temporal/Duration/prototype/add/float64-representable-integer.js b/test/built-ins/Temporal/Duration/prototype/add/float64-representable-integer.js new file mode 100644 index 0000000000..4d5e369804 --- /dev/null +++ b/test/built-ins/Temporal/Duration/prototype/add/float64-representable-integer.js @@ -0,0 +1,19 @@ +// Copyright (C) 2025 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: Internal representation uses float64-representable integers +features: [Temporal] +---*/ + +const d = new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, /* µs = */ Number.MAX_SAFE_INTEGER, 0); +const result = d.add({ microseconds: Number.MAX_SAFE_INTEGER - 1 }); + +// ℝ(𝔽(18014398509481981)) = 18014398509481980 +assert.sameValue(result.microseconds, 18014398509481980, + "microseconds result should have FP precision loss"); +assert.sameValue(result.toString(), "PT18014398509.48198S", + "toString() should not use more precise internal representation than the spec prescribes"); +assert.sameValue(Temporal.Duration.compare(result.add({ microseconds: 1 }), result), 0, + "subsequent add() should not use more precise internal representation than the spec prescribes"); diff --git a/test/built-ins/Temporal/Duration/prototype/round/float64-representable-integer.js b/test/built-ins/Temporal/Duration/prototype/round/float64-representable-integer.js new file mode 100644 index 0000000000..edac7f9629 --- /dev/null +++ b/test/built-ins/Temporal/Duration/prototype/round/float64-representable-integer.js @@ -0,0 +1,24 @@ +// Copyright (C) 2025 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: Internal representation uses float64-representable integers +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const d = new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, /* ms = */ 18014398509481, /* µs = */ 981, 0); +const result = d.round({ largestUnit: "microseconds" }); + +// ℝ(𝔽(18014398509481981)) = 18014398509481980 +assert.sameValue(result.microseconds, 18014398509481980, + "microseconds result should have FP precision loss"); +assert.sameValue(result.toString(), "PT18014398509.48198S", + "toString() should not use more precise internal representation than the spec prescribes"); +// Rounding bounds of 8 µs are ...976 and ...984. halfTrunc will round down if +// the µs component is ...980 and up if it is ...981 +TemporalHelpers.assertDuration( + result.round({ largestUnit: "seconds", smallestUnit: "microseconds", roundingMode: "halfTrunc", roundingIncrement: 8 }), + 0, 0, 0, 0, 0, 0, 18014398509, 481, 976, 0, + "subsequent round() should not use more precise internal representation than the spec prescribes"); diff --git a/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-calendar-wrong-type.js b/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-calendar-wrong-type.js index 2c28d1a313..3828e7db40 100644 --- a/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-calendar-wrong-type.js +++ b/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-calendar-wrong-type.js @@ -14,7 +14,7 @@ const instance = new Temporal.Duration(1, 0, 0, 0, 24); const wrongTypeTests = [ [null, "null"], [true, "boolean"], - [1, "number that doesn't convert to a valid ISO string"], + [1, "number"], [1n, "bigint"], [19970327, "large number"], [-19970327, "negative number"], @@ -32,6 +32,6 @@ for (const [calendar, description] of wrongTypeTests) { assert.throws( TypeError, () => instance.round({ largestUnit: "years", relativeTo }), - `${description} does not convert to a valid ISO string` + `${description} is not a valid calendar` ); } diff --git a/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-invalid-offset-string.js b/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-invalid-offset-string.js index ee038cd8b4..7fa9456ccf 100644 --- a/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-invalid-offset-string.js +++ b/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-invalid-offset-string.js @@ -24,6 +24,6 @@ badOffsets.forEach((offset) => { assert.throws( typeof(offset) === 'string' ? RangeError : TypeError, () => instance.round({ largestUnit: "years", relativeTo }), - `"${offset} is not a valid offset string` + `"${offset}" is not a valid offset string` ); }); diff --git a/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-optional-properties.js b/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-optional-properties.js new file mode 100644 index 0000000000..74d62d235f --- /dev/null +++ b/test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-optional-properties.js @@ -0,0 +1,38 @@ +// Copyright (C) 2025 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 property bag missing optional properties is equivalent to a property bag + with all the optional properties having their default values +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const timeZone = "UTC"; +const instance = new Temporal.Duration(1, 0, 0, 0, 24); + +let relativeTo = { + year: 2021, + month: 10, + day: 28, + timeZone, +}; +const resultWithout = instance.round({ largestUnit: "years", relativeTo }); +relativeTo = { + year: 2021, + month: 10, + day: 28, + hour: 0, + minute: 0, + second: 0, + millisecond: 0, + microsecond: 0, + nanosecond: 0, + offset: "+00:00", + timeZone, + calendar: "iso8601", +}; +const resultWith = instance.round({ largestUnit: "years", relativeTo }); +TemporalHelpers.assertDurationsEqual(resultWithout, resultWith, "results should be the same with and without optional properties"); diff --git a/test/built-ins/Temporal/Duration/prototype/round/relativeto-wrong-type.js b/test/built-ins/Temporal/Duration/prototype/round/relativeto-wrong-type.js index 22fc458dec..e13b9de6ea 100644 --- a/test/built-ins/Temporal/Duration/prototype/round/relativeto-wrong-type.js +++ b/test/built-ins/Temporal/Duration/prototype/round/relativeto-wrong-type.js @@ -17,7 +17,7 @@ const primitiveTests = [ [null, 'null'], [true, 'boolean'], ['', 'empty string'], - [1, "number that doesn't convert to a valid ISO string"], + [1, 'number'], [1n, 'bigint'] ]; diff --git a/test/built-ins/Temporal/Duration/prototype/subtract/argument-propertybag-optional-properties.js b/test/built-ins/Temporal/Duration/prototype/subtract/argument-propertybag-optional-properties.js new file mode 100644 index 0000000000..b73c49f8ac --- /dev/null +++ b/test/built-ins/Temporal/Duration/prototype/subtract/argument-propertybag-optional-properties.js @@ -0,0 +1,32 @@ +// Copyright (C) 2025 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 property bag missing optional properties is equivalent to a property bag + with all the optional properties having their default values +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Duration(); + +const oneProperty = { + hours: 1, +}; +const allProperties = { + years: 0, + months: 0, + weeks: 0, + days: 0, + hours: 1, + minutes: 0, + seconds: 0, + milliseconds: 0, + microseconds: 0, + nanoseconds: 0, +}; +const resultWithout = instance.subtract(oneProperty); +const resultWith = instance.subtract(allProperties); +TemporalHelpers.assertDurationsEqual(resultWithout, resultWith, "results should be the same with and without optional properties"); diff --git a/test/built-ins/Temporal/Duration/prototype/subtract/float64-representable-integer.js b/test/built-ins/Temporal/Duration/prototype/subtract/float64-representable-integer.js new file mode 100644 index 0000000000..681aac0050 --- /dev/null +++ b/test/built-ins/Temporal/Duration/prototype/subtract/float64-representable-integer.js @@ -0,0 +1,19 @@ +// Copyright (C) 2025 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: Internal representation uses float64-representable integers +features: [Temporal] +---*/ + +const d = new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, /* µs = */ Number.MAX_SAFE_INTEGER, 0); +const result = d.subtract({ microseconds: Number.MIN_SAFE_INTEGER + 1 }); + +// ℝ(𝔽(18014398509481981)) = 18014398509481980 +assert.sameValue(result.microseconds, 18014398509481980, + "microseconds result should have FP precision loss"); +assert.sameValue(result.toString(), "PT18014398509.48198S", + "toString() should not use more precise internal representation than the spec prescribes"); +assert.sameValue(Temporal.Duration.compare(result.subtract({ microseconds: 1 }), result), 0, + "subsequent subtract() should not use more precise internal representation than the spec prescribes"); diff --git a/test/built-ins/Temporal/Duration/prototype/toJSON/large-with-small-units.js b/test/built-ins/Temporal/Duration/prototype/toJSON/large-with-small-units.js new file mode 100644 index 0000000000..47391a67bf --- /dev/null +++ b/test/built-ins/Temporal/Duration/prototype/toJSON/large-with-small-units.js @@ -0,0 +1,38 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.tojson +description: Pairs of units with one large and one small +features: [Temporal] +---*/ + +assert.sameValue( + new Temporal.Duration(1, 0, 0, 0, 0, 0, 0, 0, 0, 1).toJSON(), + "P1YT0.000000001S", + "years with nanoseconds" +); + +assert.sameValue( + new Temporal.Duration(0, 1, 0, 0, 0, 0, 0, 0, 1).toJSON(), + "P1MT0.000001S", + "months with microseconds" +); + +assert.sameValue( + new Temporal.Duration(0, 0, 1, 0, 0, 0, 0, 1).toJSON(), + "P1WT0.001S", + "weeks with milliseconds" +); + +assert.sameValue( + new Temporal.Duration(0, 0, 0, 1, 0, 0, 1).toJSON(), + "P1DT1S", + "days with seconds" +); + +assert.sameValue( + new Temporal.Duration(0, 0, 0, 0, 1, 1).toJSON(), + "PT1H1M", + "hours with minutes" +); diff --git a/test/built-ins/Temporal/Duration/prototype/toString/large-with-small-units.js b/test/built-ins/Temporal/Duration/prototype/toString/large-with-small-units.js new file mode 100644 index 0000000000..0d147bf719 --- /dev/null +++ b/test/built-ins/Temporal/Duration/prototype/toString/large-with-small-units.js @@ -0,0 +1,38 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.tostring +description: Pairs of units with one large and one small +features: [Temporal] +---*/ + +assert.sameValue( + new Temporal.Duration(1, 0, 0, 0, 0, 0, 0, 0, 0, 1).toString(), + "P1YT0.000000001S", + "years with nanoseconds" +); + +assert.sameValue( + new Temporal.Duration(0, 1, 0, 0, 0, 0, 0, 0, 1).toString(), + "P1MT0.000001S", + "months with microseconds" +); + +assert.sameValue( + new Temporal.Duration(0, 0, 1, 0, 0, 0, 0, 1).toString(), + "P1WT0.001S", + "weeks with milliseconds" +); + +assert.sameValue( + new Temporal.Duration(0, 0, 0, 1, 0, 0, 1).toString(), + "P1DT1S", + "days with seconds" +); + +assert.sameValue( + new Temporal.Duration(0, 0, 0, 0, 1, 1).toString(), + "PT1H1M", + "hours with minutes" +); diff --git a/test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-optional-properties.js b/test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-optional-properties.js new file mode 100644 index 0000000000..6e8dc1bb03 --- /dev/null +++ b/test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-optional-properties.js @@ -0,0 +1,37 @@ +// Copyright (C) 2025 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 property bag missing optional properties is equivalent to a property bag + with all the optional properties having their default values +features: [Temporal] +---*/ + +const timeZone = "UTC"; +const instance = new Temporal.Duration(1, 0, 0, 0, 24); + +let relativeTo = { + year: 2021, + month: 10, + day: 28, + timeZone, +}; +const resultWithout = instance.total({ unit: "days", relativeTo }); +relativeTo = { + year: 2021, + month: 10, + day: 28, + hour: 0, + minute: 0, + second: 0, + millisecond: 0, + microsecond: 0, + nanosecond: 0, + offset: "+00:00", + timeZone, + calendar: "iso8601", +}; +const resultWith = instance.total({ unit: "days", relativeTo }); +assert.sameValue(resultWithout, resultWith, "results should be the same with and without optional properties"); diff --git a/test/built-ins/Temporal/Duration/prototype/total/relativeto-wrong-type.js b/test/built-ins/Temporal/Duration/prototype/total/relativeto-wrong-type.js index 29541d661e..3dae866fba 100644 --- a/test/built-ins/Temporal/Duration/prototype/total/relativeto-wrong-type.js +++ b/test/built-ins/Temporal/Duration/prototype/total/relativeto-wrong-type.js @@ -17,7 +17,7 @@ const primitiveTests = [ [null, 'null'], [true, 'boolean'], ['', 'empty string'], - [1, "number that doesn't convert to a valid ISO string"], + [1, 'number'], [1n, 'bigint'] ]; diff --git a/test/built-ins/Temporal/Instant/prototype/add/add-large-subseconds.js b/test/built-ins/Temporal/Instant/prototype/add/add-large-subseconds.js new file mode 100644 index 0000000000..0854fc3660 --- /dev/null +++ b/test/built-ins/Temporal/Instant/prototype/add/add-large-subseconds.js @@ -0,0 +1,52 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.add +description: Adding unbalanced durations with large subsecond values to an instant +features: [Temporal] +---*/ + +const i1 = new Temporal.Instant(1582966647747612578n); + +assert.sameValue(i1.add(Temporal.Duration.from({nanoseconds: Number.MAX_SAFE_INTEGER})).epochNanoseconds, + 1591973847002353569n); +assert.sameValue(i1.add(Temporal.Duration.from({nanoseconds: Number.MIN_SAFE_INTEGER})).epochNanoseconds, + 1573959448492871587n); + +assert.sameValue(i1.add(Temporal.Duration.from({microseconds: Number.MAX_SAFE_INTEGER})).epochNanoseconds, + 10590165902488603578n); +assert.sameValue(i1.add(Temporal.Duration.from({microseconds: Number.MIN_SAFE_INTEGER})).epochNanoseconds, + -7424232606993378422n); + +assert.throws(RangeError, () => i1.add(Temporal.Duration.from({milliseconds: Number.MAX_SAFE_INTEGER}))); +assert.throws(RangeError, () => i1.add(Temporal.Duration.from({milliseconds: Number.MIN_SAFE_INTEGER}))); + +assert.throws(RangeError, () => i1.add(Temporal.Duration.from({seconds: Number.MAX_SAFE_INTEGER}))); +assert.throws(RangeError, () => i1.add(Temporal.Duration.from({seconds: Number.MIN_SAFE_INTEGER}))); + +const bigNumber = 9007199254740990976; + +assert.sameValue(i1.add(Temporal.Duration.from({nanoseconds: bigNumber})).epochNanoseconds, + 10590165902488603554n); +assert.sameValue(i1.add(Temporal.Duration.from({nanoseconds: -bigNumber})).epochNanoseconds, + -7424232606993378398n); + +assert.throws(RangeError, () => i1.add(Temporal.Duration.from({milliseconds: bigNumber}))); +assert.throws(RangeError, () => i1.add(Temporal.Duration.from({milliseconds: -bigNumber}))); + +assert.throws(RangeError, () => i1.add(Temporal.Duration.from({microseconds: bigNumber}))); +assert.throws(RangeError, () => i1.add(Temporal.Duration.from({microseconds: -bigNumber}))); + +const i2 = new Temporal.Instant(0n); + +assert.sameValue(i2.add(Temporal.Duration.from({nanoseconds: bigNumber})).epochNanoseconds, + 9007199254740990976n); +assert.sameValue(i2.add(Temporal.Duration.from({nanoseconds: -bigNumber})).epochNanoseconds, + -9007199254740990976n); + +assert.throws(RangeError, () => i2.add(Temporal.Duration.from({milliseconds: bigNumber}))); +assert.throws(RangeError, () => i2.add(Temporal.Duration.from({milliseconds: -bigNumber}))); + +assert.throws(RangeError, () => i2.add(Temporal.Duration.from({microseconds: bigNumber}))); +assert.throws(RangeError, () => i2.add(Temporal.Duration.from({microseconds: -bigNumber}))); diff --git a/test/built-ins/Temporal/Instant/prototype/add/argument-propertybag-optional-properties.js b/test/built-ins/Temporal/Instant/prototype/add/argument-propertybag-optional-properties.js new file mode 100644 index 0000000000..f838316ff5 --- /dev/null +++ b/test/built-ins/Temporal/Instant/prototype/add/argument-propertybag-optional-properties.js @@ -0,0 +1,31 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.add +description: > + A property bag missing optional properties is equivalent to a property bag + with all the optional properties having their default values +features: [Temporal] +---*/ + +const instance = new Temporal.Instant(0n); + +const oneProperty = { + hours: 1, +}; +const allProperties = { + years: 0, + months: 0, + weeks: 0, + days: 0, + hours: 1, + minutes: 0, + seconds: 0, + milliseconds: 0, + microseconds: 0, + nanoseconds: 0, +}; +const resultWithout = instance.add(oneProperty); +const resultWith = instance.add(allProperties); +assert(resultWithout.equals(resultWith), "results should be the same with and without optional properties"); diff --git a/test/built-ins/Temporal/Instant/prototype/since/float64-representable-integer.js b/test/built-ins/Temporal/Instant/prototype/since/float64-representable-integer.js new file mode 100644 index 0000000000..466c62aef0 --- /dev/null +++ b/test/built-ins/Temporal/Instant/prototype/since/float64-representable-integer.js @@ -0,0 +1,20 @@ +// Copyright (C) 2025 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: Internal representation of Duration uses float64-representable integers +features: [Temporal] +---*/ + +const i1 = new Temporal.Instant(0n); +const i2 = new Temporal.Instant(18446744073_709_551_616n); +const result = i1.since(i2, { largestUnit: "microseconds" }); + +// ℝ(𝔽(-18446744073709551)) = -18446744073709552 +assert.sameValue(result.microseconds, -18446744073709552, + "microseconds result should have FP precision loss"); +assert.sameValue(result.toString(), "-PT18446744073.709552616S", + "Duration.p.toString() should not use more precise internal representation than the spec prescribes"); +assert.sameValue(Temporal.Duration.compare(result.add({ microseconds: 1 }), result), 0, + "subsequent ops on duration should not use more precise internal representation than the spec prescribes"); diff --git a/test/built-ins/Temporal/Instant/prototype/subtract/argument-propertybag-optional-properties.js b/test/built-ins/Temporal/Instant/prototype/subtract/argument-propertybag-optional-properties.js new file mode 100644 index 0000000000..798880d2fc --- /dev/null +++ b/test/built-ins/Temporal/Instant/prototype/subtract/argument-propertybag-optional-properties.js @@ -0,0 +1,31 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.subtract +description: > + A property bag missing optional properties is equivalent to a property bag + with all the optional properties having their default values +features: [Temporal] +---*/ + +const instance = new Temporal.Instant(0n); + +const oneProperty = { + hours: 1, +}; +const allProperties = { + years: 0, + months: 0, + weeks: 0, + days: 0, + hours: 1, + minutes: 0, + seconds: 0, + milliseconds: 0, + microseconds: 0, + nanoseconds: 0, +}; +const resultWithout = instance.subtract(oneProperty); +const resultWith = instance.subtract(allProperties); +assert(resultWithout.equals(resultWith), "results should be the same with and without optional properties"); diff --git a/test/built-ins/Temporal/Instant/prototype/subtract/subtract-large-subseconds.js b/test/built-ins/Temporal/Instant/prototype/subtract/subtract-large-subseconds.js new file mode 100644 index 0000000000..7b0c700fe3 --- /dev/null +++ b/test/built-ins/Temporal/Instant/prototype/subtract/subtract-large-subseconds.js @@ -0,0 +1,52 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.subtract +description: Subtracting unbalanced durations with large subsecond values from a date +features: [Temporal] +---*/ + +const i1 = new Temporal.Instant(1582966647747612578n); + +assert.sameValue(i1.subtract(Temporal.Duration.from({nanoseconds: Number.MAX_SAFE_INTEGER})).epochNanoseconds, + 1573959448492871587n); +assert.sameValue(i1.subtract(Temporal.Duration.from({nanoseconds: Number.MIN_SAFE_INTEGER})).epochNanoseconds, + 1591973847002353569n); + +assert.sameValue(i1.subtract(Temporal.Duration.from({microseconds: Number.MAX_SAFE_INTEGER})).epochNanoseconds, + -7424232606993378422n); +assert.sameValue(i1.subtract(Temporal.Duration.from({microseconds: Number.MIN_SAFE_INTEGER})).epochNanoseconds, + 10590165902488603578n); + +assert.throws(RangeError, () => i1.subtract(Temporal.Duration.from({milliseconds: Number.MAX_SAFE_INTEGER}))); +assert.throws(RangeError, () => i1.subtract(Temporal.Duration.from({milliseconds: Number.MIN_SAFE_INTEGER}))); + +assert.throws(RangeError, () => i1.subtract(Temporal.Duration.from({seconds: Number.MAX_SAFE_INTEGER}))); +assert.throws(RangeError, () => i1.subtract(Temporal.Duration.from({seconds: Number.MIN_SAFE_INTEGER}))); + +const bigNumber = 9007199254740990976; + +assert.sameValue(i1.subtract(Temporal.Duration.from({nanoseconds: bigNumber})).epochNanoseconds, + -7424232606993378398n); +assert.sameValue(i1.subtract(Temporal.Duration.from({nanoseconds: -bigNumber})).epochNanoseconds, + 10590165902488603554n); + +assert.throws(RangeError, () => i1.subtract(Temporal.Duration.from({microseconds: bigNumber}))); +assert.throws(RangeError, () => i1.subtract(Temporal.Duration.from({microseconds: -bigNumber}))); + +assert.throws(RangeError, () => i1.subtract(Temporal.Duration.from({milliseconds: bigNumber}))); +assert.throws(RangeError, () => i1.subtract(Temporal.Duration.from({milliseconds: -bigNumber}))); + +const i2 = new Temporal.Instant(0n); + +assert.sameValue(i2.subtract(Temporal.Duration.from({nanoseconds: bigNumber})).epochNanoseconds, + -9007199254740990976n); +assert.sameValue(i2.subtract(Temporal.Duration.from({nanoseconds: -bigNumber})).epochNanoseconds, + 9007199254740990976n); + +assert.throws(RangeError, () => i2.subtract(Temporal.Duration.from({microseconds: bigNumber}))); +assert.throws(RangeError, () => i2.subtract(Temporal.Duration.from({microseconds: -bigNumber}))); + +assert.throws(RangeError, () => i2.subtract(Temporal.Duration.from({milliseconds: bigNumber}))); +assert.throws(RangeError, () => i2.subtract(Temporal.Duration.from({milliseconds: -bigNumber}))); diff --git a/test/built-ins/Temporal/Instant/prototype/toString/fractionalseconddigits-negative.js b/test/built-ins/Temporal/Instant/prototype/toString/fractionalseconddigits-negative.js new file mode 100644 index 0000000000..64ca1134fb --- /dev/null +++ b/test/built-ins/Temporal/Instant/prototype/toString/fractionalseconddigits-negative.js @@ -0,0 +1,12 @@ +// Copyright (C) 2025 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: Epoch milliseconds should be rounded down before adding negative micro/nanoseconds back in +features: [BigInt, Temporal] +---*/ + +const instant = new Temporal.Instant(-1000000000000001000n); +assert.sameValue(instant.toString(), "1938-04-24T22:13:19.999999Z", + "epoch milliseconds should be rounded down to compute seconds"); diff --git a/test/built-ins/Temporal/Instant/prototype/until/float64-representable-integer.js b/test/built-ins/Temporal/Instant/prototype/until/float64-representable-integer.js new file mode 100644 index 0000000000..e7668aed89 --- /dev/null +++ b/test/built-ins/Temporal/Instant/prototype/until/float64-representable-integer.js @@ -0,0 +1,20 @@ +// Copyright (C) 2025 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: Internal representation of Duration uses float64-representable integers +features: [Temporal] +---*/ + +const i1 = new Temporal.Instant(0n); +const i2 = new Temporal.Instant(18446744073_709_551_616n); +const result = i1.until(i2, { largestUnit: "microseconds" }); + +// ℝ(𝔽(18446744073709551)) = 18446744073709552 +assert.sameValue(result.microseconds, 18446744073709552, + "microseconds result should have FP precision loss"); +assert.sameValue(result.toString(), "PT18446744073.709552616S", + "Duration.p.toString() should not use more precise internal representation than the spec prescribes"); +assert.sameValue(Temporal.Duration.compare(result.add({ microseconds: 1 }), result), 0, + "subsequent ops on duration should not use more precise internal representation than the spec prescribes"); diff --git a/test/built-ins/Temporal/PlainDate/prototype/add/argument-propertybag-optional-properties.js b/test/built-ins/Temporal/PlainDate/prototype/add/argument-propertybag-optional-properties.js new file mode 100644 index 0000000000..ebd01aa135 --- /dev/null +++ b/test/built-ins/Temporal/PlainDate/prototype/add/argument-propertybag-optional-properties.js @@ -0,0 +1,31 @@ +// Copyright (C) 2025 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: > + A property bag missing optional properties is equivalent to a property bag + with all the optional properties having their default values +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDate(1970, 1, 1); + +const oneProperty = { + hours: 1, +}; +const allProperties = { + years: 0, + months: 0, + weeks: 0, + days: 0, + hours: 1, + minutes: 0, + seconds: 0, + milliseconds: 0, + microseconds: 0, + nanoseconds: 0, +}; +const resultWithout = instance.add(oneProperty); +const resultWith = instance.add(allProperties); +assert(resultWithout.equals(resultWith), "results should be the same with and without optional properties"); diff --git a/test/built-ins/Temporal/PlainDate/prototype/add/overflow-adding-months-to-max-year.js b/test/built-ins/Temporal/PlainDate/prototype/add/overflow-adding-months-to-max-year.js new file mode 100644 index 0000000000..c839823790 --- /dev/null +++ b/test/built-ins/Temporal/PlainDate/prototype/add/overflow-adding-months-to-max-year.js @@ -0,0 +1,15 @@ +// Copyright (C) 2025 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: Adding months to maximum year should throw +features: [Temporal] +---*/ + +const maxYear = new Temporal.PlainDate(275760, 1, 1); +const duration = new Temporal.Duration(0, 5432, 5432, 0, 0, 0, 0, 0, 0, 0); +assert.throws(RangeError, () => maxYear.add(duration)); + +const minYear = new Temporal.PlainDate(-271821, 4, 19); +assert.throws(RangeError, () => minYear.add(duration.negated())); diff --git a/test/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-wrong-type.js b/test/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-wrong-type.js index cb85f0a258..77979ab739 100644 --- a/test/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-wrong-type.js +++ b/test/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-wrong-type.js @@ -5,7 +5,7 @@ esid: sec-temporal.plaindate.prototype.since description: > Appropriate error thrown when a calendar property from a property bag cannot - be converted to a calendar object + be converted to a calendar ID features: [BigInt, Symbol, Temporal] ---*/ diff --git a/test/built-ins/Temporal/PlainDate/prototype/subtract/argument-propertybag-optional-properties.js b/test/built-ins/Temporal/PlainDate/prototype/subtract/argument-propertybag-optional-properties.js new file mode 100644 index 0000000000..47c5679a61 --- /dev/null +++ b/test/built-ins/Temporal/PlainDate/prototype/subtract/argument-propertybag-optional-properties.js @@ -0,0 +1,31 @@ +// Copyright (C) 2025 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: > + A property bag missing optional properties is equivalent to a property bag + with all the optional properties having their default values +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDate(1970, 1, 1); + +const oneProperty = { + hours: 1, +}; +const allProperties = { + years: 0, + months: 0, + weeks: 0, + days: 0, + hours: 1, + minutes: 0, + seconds: 0, + milliseconds: 0, + microseconds: 0, + nanoseconds: 0, +}; +const resultWithout = instance.subtract(oneProperty); +const resultWith = instance.subtract(allProperties); +assert(resultWithout.equals(resultWith), "results should be the same with and without optional properties"); diff --git a/test/built-ins/Temporal/PlainDate/prototype/subtract/overflow-subtracting-months-from-min-year.js b/test/built-ins/Temporal/PlainDate/prototype/subtract/overflow-subtracting-months-from-min-year.js new file mode 100644 index 0000000000..818080c1b4 --- /dev/null +++ b/test/built-ins/Temporal/PlainDate/prototype/subtract/overflow-subtracting-months-from-min-year.js @@ -0,0 +1,15 @@ +// Copyright (C) 2025 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: Subtracting months from minimum year should throw +features: [Temporal] +---*/ + +const minYear = new Temporal.PlainDate(-271821, 4, 19); +const duration = new Temporal.Duration(0, 5432, 5432, 0, 0, 0, 0, 0, 0, 0); +assert.throws(RangeError, () => minYear.subtract(duration)); + +const maxYear = new Temporal.PlainDate(275760, 1, 1); +assert.throws(RangeError, () => maxYear.subtract(duration.negated())); diff --git a/test/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/argument-propertybag-optional-properties.js b/test/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/argument-propertybag-optional-properties.js new file mode 100644 index 0000000000..aed33d919d --- /dev/null +++ b/test/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/argument-propertybag-optional-properties.js @@ -0,0 +1,27 @@ +// Copyright (C) 2025 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: > + A property bag missing optional properties is equivalent to a property bag + with all the optional properties having their default values +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDate(2000, 5, 2); + +const minimumProperties = { + hour: 0, +}; +const allProperties = { + hour: 0, + minute: 0, + second: 0, + millisecond: 0, + microsecond: 0, + nanosecond: 0, +}; +const resultWithout = instance.toPlainDateTime(minimumProperties); +const resultWith = instance.toPlainDateTime(allProperties); +assert(resultWithout.equals(resultWith), "results should be the same with and without optional properties"); diff --git a/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/argument-propertybag-optional-properties.js b/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/argument-propertybag-optional-properties.js new file mode 100644 index 0000000000..4eefb886ac --- /dev/null +++ b/test/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/argument-propertybag-optional-properties.js @@ -0,0 +1,27 @@ +// Copyright (C) 2025 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 property bag missing optional properties is equivalent to a property bag + with all the optional properties having their default values +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDate(2000, 5, 2); + +const minimumProperties = { + hour: 0, +}; +const allProperties = { + hour: 0, + minute: 0, + second: 0, + millisecond: 0, + microsecond: 0, + nanosecond: 0, +}; +const resultWithout = instance.toZonedDateTime({ plainTime: minimumProperties, timeZone: "UTC" }); +const resultWith = instance.toZonedDateTime({ plainTime: allProperties, timeZone: "UTC" }); +assert(resultWithout.equals(resultWith), "results should be the same with and without optional properties"); diff --git a/test/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-optional-properties.js b/test/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-optional-properties.js new file mode 100644 index 0000000000..668846929d --- /dev/null +++ b/test/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-optional-properties.js @@ -0,0 +1,31 @@ +// Copyright (C) 2025 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 property bag missing optional properties is equivalent to a property bag + with all the optional properties having their default values +features: [Temporal] +---*/ + +const minimumProperties = { + year: 2021, + month: 10, + day: 28, +}; +const allProperties = { + year: 2021, + month: 10, + day: 28, + hour: 0, + minute: 0, + second: 0, + millisecond: 0, + microsecond: 0, + nanosecond: 0, + calendar: "iso8601", +}; +const resultWithout = Temporal.PlainDateTime.compare(minimumProperties, minimumProperties); +const resultWith = Temporal.PlainDateTime.compare(allProperties, allProperties); +assert.sameValue(resultWithout, resultWith, "results should be the same with and without optional properties"); diff --git a/test/built-ins/Temporal/PlainDateTime/from/argument-propertybag-optional-properties.js b/test/built-ins/Temporal/PlainDateTime/from/argument-propertybag-optional-properties.js new file mode 100644 index 0000000000..5edce739bf --- /dev/null +++ b/test/built-ins/Temporal/PlainDateTime/from/argument-propertybag-optional-properties.js @@ -0,0 +1,31 @@ +// Copyright (C) 2025 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 property bag missing optional properties is equivalent to a property bag + with all the optional properties having their default values +features: [Temporal] +---*/ + +const minimumProperties = { + year: 2021, + month: 10, + day: 28, +}; +const allProperties = { + year: 2021, + month: 10, + day: 28, + hour: 0, + minute: 0, + second: 0, + millisecond: 0, + microsecond: 0, + nanosecond: 0, + calendar: "iso8601", +}; +const resultWithout = Temporal.PlainDateTime.from(minimumProperties); +const resultWith = Temporal.PlainDateTime.from(allProperties); +assert(resultWithout.equals(resultWith), "results should be the same with and without optional properties"); diff --git a/test/built-ins/Temporal/PlainDateTime/prototype/add/add-large-subseconds.js b/test/built-ins/Temporal/PlainDateTime/prototype/add/add-large-subseconds.js new file mode 100644 index 0000000000..78690d06b2 --- /dev/null +++ b/test/built-ins/Temporal/PlainDateTime/prototype/add/add-large-subseconds.js @@ -0,0 +1,53 @@ +// Copyright (C) 2025 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: Adding unbalanced durations with large subsecond values to a date +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const pdt1 = new Temporal.PlainDateTime(2020, 2, 29, 0, 57, 27, 747, 612, 578); + +TemporalHelpers.assertPlainDateTime(pdt1.add(Temporal.Duration.from({nanoseconds: Number.MAX_SAFE_INTEGER})), + 2020, 6, "M06", 12, 6, 57, 27, 2, 353, 569); +TemporalHelpers.assertPlainDateTime(pdt1.add(Temporal.Duration.from({nanoseconds: Number.MIN_SAFE_INTEGER})), + 2019, 11, "M11", 16, 18, 57, 28, 492, 871, 587); + +TemporalHelpers.assertPlainDateTime(pdt1.add(Temporal.Duration.from({microseconds: Number.MAX_SAFE_INTEGER})), + 2305, 8, "M08", 4, 0, 45, 2, 488, 603, 578); +TemporalHelpers.assertPlainDateTime(pdt1.add(Temporal.Duration.from({microseconds: Number.MIN_SAFE_INTEGER})), + 1734, 9, "M09", 26, 1, 9, 53, 6, 621, 578); + +assert.throws(RangeError, () => pdt1.add(Temporal.Duration.from({milliseconds: Number.MAX_SAFE_INTEGER}))); +assert.throws(RangeError, () => pdt1.add(Temporal.Duration.from({milliseconds: Number.MIN_SAFE_INTEGER}))); + +assert.throws(RangeError, () => pdt1.add(Temporal.Duration.from({seconds: Number.MAX_SAFE_INTEGER}))); +assert.throws(RangeError, () => pdt1.add(Temporal.Duration.from({seconds: Number.MIN_SAFE_INTEGER}))); + +const bigNumber = 9007199254740990976; + +TemporalHelpers.assertPlainDateTime(pdt1.add(Temporal.Duration.from({nanoseconds: bigNumber})), + 2305, 8, "M08", 4, 0, 45, 2, 488, 603, 554); +TemporalHelpers.assertPlainDateTime(pdt1.add(Temporal.Duration.from({nanoseconds: -bigNumber})), + 1734, 9, "M09", 26, 1, 9, 53, 6, 621, 602); + +assert.throws(RangeError, () => pdt1.add(Temporal.Duration.from({microseconds: bigNumber}))); +assert.throws(RangeError, () => pdt1.add(Temporal.Duration.from({microseconds: -bigNumber}))); + +assert.throws(RangeError, () => pdt1.add(Temporal.Duration.from({milliseconds: bigNumber}))); +assert.throws(RangeError, () => pdt1.add(Temporal.Duration.from({milliseconds: -bigNumber}))); + +const pdt2 = new Temporal.PlainDateTime(0, 1, 1); + +TemporalHelpers.assertPlainDateTime(pdt2.add(Temporal.Duration.from({nanoseconds: bigNumber})), + 285, 6, "M06", 4, 23, 47, 34, 740, 990, 976); +TemporalHelpers.assertPlainDateTime(pdt2.add(Temporal.Duration.from({nanoseconds: -bigNumber})), + -286, 7, "M07", 29, 0, 12, 25, 259, 9, 24); + +assert.throws(RangeError, () => pdt2.add(Temporal.Duration.from({microseconds: bigNumber}))); +assert.throws(RangeError, () => pdt2.add(Temporal.Duration.from({microseconds: -bigNumber}))); + +assert.throws(RangeError, () => pdt2.add(Temporal.Duration.from({milliseconds: bigNumber}))); +assert.throws(RangeError, () => pdt2.add(Temporal.Duration.from({milliseconds: -bigNumber}))); diff --git a/test/built-ins/Temporal/PlainDateTime/prototype/add/argument-propertybag-optional-properties.js b/test/built-ins/Temporal/PlainDateTime/prototype/add/argument-propertybag-optional-properties.js new file mode 100644 index 0000000000..7810d83991 --- /dev/null +++ b/test/built-ins/Temporal/PlainDateTime/prototype/add/argument-propertybag-optional-properties.js @@ -0,0 +1,31 @@ +// Copyright (C) 2025 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: > + A property bag missing optional properties is equivalent to a property bag + with all the optional properties having their default values +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDateTime(1970, 1, 1); + +const oneProperty = { + hours: 1, +}; +const allProperties = { + years: 0, + months: 0, + weeks: 0, + days: 0, + hours: 1, + minutes: 0, + seconds: 0, + milliseconds: 0, + microseconds: 0, + nanoseconds: 0, +}; +const resultWithout = instance.add(oneProperty); +const resultWith = instance.add(allProperties); +assert(resultWithout.equals(resultWith), "results should be the same with and without optional properties"); diff --git a/test/built-ins/Temporal/PlainDateTime/prototype/add/overflow-adding-months-to-max-year.js b/test/built-ins/Temporal/PlainDateTime/prototype/add/overflow-adding-months-to-max-year.js new file mode 100644 index 0000000000..bfcc008281 --- /dev/null +++ b/test/built-ins/Temporal/PlainDateTime/prototype/add/overflow-adding-months-to-max-year.js @@ -0,0 +1,15 @@ +// Copyright (C) 2025 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: Adding months to maximum year should throw +features: [Temporal] +---*/ + +const maxYear = new Temporal.PlainDateTime(275760, 1, 1); +const duration = new Temporal.Duration(0, 5432, 5432, 0, 0, 0, 0, 0, 0, 0); +assert.throws(RangeError, () => maxYear.add(duration)); + +const minYear = new Temporal.PlainDateTime(-271821, 4, 19, 0, 0, 0, 0, 0, 1); +assert.throws(RangeError, () => minYear.add(duration.negated())); diff --git a/test/built-ins/Temporal/PlainDateTime/prototype/equals/argument-propertybag-optional-properties.js b/test/built-ins/Temporal/PlainDateTime/prototype/equals/argument-propertybag-optional-properties.js new file mode 100644 index 0000000000..b22c95b80d --- /dev/null +++ b/test/built-ins/Temporal/PlainDateTime/prototype/equals/argument-propertybag-optional-properties.js @@ -0,0 +1,33 @@ +// Copyright (C) 2025 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 property bag missing optional properties is equivalent to a property bag + with all the optional properties having their default values +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); + +const minimumProperties = { + year: 2021, + month: 10, + day: 28, +}; +const allProperties = { + year: 2021, + month: 10, + day: 28, + hour: 0, + minute: 0, + second: 0, + millisecond: 0, + microsecond: 0, + nanosecond: 0, + calendar: "iso8601", +}; +const resultWithout = instance.equals(minimumProperties); +const resultWith = instance.equals(allProperties); +assert.sameValue(resultWithout, resultWith, "results should be the same with and without optional properties"); diff --git a/test/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-wrong-type.js b/test/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-wrong-type.js index e98f60befc..da6726dd25 100644 --- a/test/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-wrong-type.js +++ b/test/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-wrong-type.js @@ -5,7 +5,7 @@ esid: sec-temporal.plaindatetime.prototype.since description: > Appropriate error thrown when a calendar property from a property bag cannot - be converted to a calendar object or string + be converted to a calendar ID features: [BigInt, Symbol, Temporal] ---*/ diff --git a/test/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-optional-properties.js b/test/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-optional-properties.js new file mode 100644 index 0000000000..214bbe97c0 --- /dev/null +++ b/test/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-optional-properties.js @@ -0,0 +1,34 @@ +// Copyright (C) 2025 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 property bag missing optional properties is equivalent to a property bag + with all the optional properties having their default values +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); + +const minimumProperties = { + year: 2021, + month: 10, + day: 28, +}; +const allProperties = { + year: 2021, + month: 10, + day: 28, + hour: 0, + minute: 0, + second: 0, + millisecond: 0, + microsecond: 0, + nanosecond: 0, + calendar: "iso8601", +}; +const resultWithout = instance.since(minimumProperties); +const resultWith = instance.since(allProperties); +TemporalHelpers.assertDurationsEqual(resultWithout, resultWith, "results should be the same with and without optional properties"); diff --git a/test/built-ins/Temporal/PlainDateTime/prototype/since/float64-representable-integer.js b/test/built-ins/Temporal/PlainDateTime/prototype/since/float64-representable-integer.js new file mode 100644 index 0000000000..149bee0b28 --- /dev/null +++ b/test/built-ins/Temporal/PlainDateTime/prototype/since/float64-representable-integer.js @@ -0,0 +1,20 @@ +// Copyright (C) 2025 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: Internal representation of Duration uses float64-representable integers +features: [Temporal] +---*/ + +const dt1 = new Temporal.PlainDateTime(1970, 1, 1); +const dt2 = new Temporal.PlainDateTime(2554, 7, 21, 23, 34, 33, 709, 551, 616); +const result = dt1.since(dt2, { largestUnit: "microseconds" }); + +// ℝ(𝔽(-18446744073709551)) = -18446744073709552 +assert.sameValue(result.microseconds, -18446744073709552, + "microseconds result should have FP precision loss"); +assert.sameValue(result.toString(), "-PT18446744073.709552616S", + "Duration.p.toString() should not use more precise internal representation than the spec prescribes"); +assert.sameValue(Temporal.Duration.compare(result.add({ microseconds: 1 }), result), 0, + "subsequent ops on duration should not use more precise internal representation than the spec prescribes"); diff --git a/test/built-ins/Temporal/PlainDateTime/prototype/subtract/argument-propertybag-optional-properties.js b/test/built-ins/Temporal/PlainDateTime/prototype/subtract/argument-propertybag-optional-properties.js new file mode 100644 index 0000000000..020d84b4f7 --- /dev/null +++ b/test/built-ins/Temporal/PlainDateTime/prototype/subtract/argument-propertybag-optional-properties.js @@ -0,0 +1,31 @@ +// Copyright (C) 2025 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: > + A property bag missing optional properties is equivalent to a property bag + with all the optional properties having their default values +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDateTime(1970, 1, 1); + +const oneProperty = { + hours: 1, +}; +const allProperties = { + years: 0, + months: 0, + weeks: 0, + days: 0, + hours: 1, + minutes: 0, + seconds: 0, + milliseconds: 0, + microseconds: 0, + nanoseconds: 0, +}; +const resultWithout = instance.subtract(oneProperty); +const resultWith = instance.subtract(allProperties); +assert(resultWithout.equals(resultWith), "results should be the same with and without optional properties"); diff --git a/test/built-ins/Temporal/PlainDateTime/prototype/subtract/overflow-subtracting-months-from-min-year.js b/test/built-ins/Temporal/PlainDateTime/prototype/subtract/overflow-subtracting-months-from-min-year.js new file mode 100644 index 0000000000..93fd563731 --- /dev/null +++ b/test/built-ins/Temporal/PlainDateTime/prototype/subtract/overflow-subtracting-months-from-min-year.js @@ -0,0 +1,15 @@ +// Copyright (C) 2025 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: Subtracting months from minimum year should throw +features: [Temporal] +---*/ + +const minYear = new Temporal.PlainDateTime(-271821, 4, 19, 0, 0, 0, 0, 0, 1); +const duration = new Temporal.Duration(0, 5432, 5432, 0, 0, 0, 0, 0, 0, 0); +assert.throws(RangeError, () => minYear.subtract(duration)); + +const maxYear = new Temporal.PlainDateTime(275760, 1, 1); +assert.throws(RangeError, () => maxYear.subtract(duration.negated())); diff --git a/test/built-ins/Temporal/PlainDateTime/prototype/subtract/subtract-large-subseconds.js b/test/built-ins/Temporal/PlainDateTime/prototype/subtract/subtract-large-subseconds.js new file mode 100644 index 0000000000..7d0f705391 --- /dev/null +++ b/test/built-ins/Temporal/PlainDateTime/prototype/subtract/subtract-large-subseconds.js @@ -0,0 +1,53 @@ +// Copyright (C) 2025 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: Subtracting unbalanced durations with large subsecond values from a date +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const pdt1 = new Temporal.PlainDateTime(2020, 2, 29, 0, 57, 27, 747, 612, 578); + +TemporalHelpers.assertPlainDateTime(pdt1.subtract(Temporal.Duration.from({nanoseconds: Number.MAX_SAFE_INTEGER})), + 2019, 11, "M11", 16, 18, 57, 28, 492, 871, 587); +TemporalHelpers.assertPlainDateTime(pdt1.subtract(Temporal.Duration.from({nanoseconds: Number.MIN_SAFE_INTEGER})), + 2020, 6, "M06", 12, 6, 57, 27, 2, 353, 569); + +TemporalHelpers.assertPlainDateTime(pdt1.subtract(Temporal.Duration.from({microseconds: Number.MAX_SAFE_INTEGER})), + 1734, 9, "M09", 26, 1, 9, 53, 6, 621, 578); +TemporalHelpers.assertPlainDateTime(pdt1.subtract(Temporal.Duration.from({microseconds: Number.MIN_SAFE_INTEGER})), + 2305, 8, "M08", 4, 0, 45, 2, 488, 603, 578); + +assert.throws(RangeError, () => pdt1.subtract(Temporal.Duration.from({milliseconds: Number.MAX_SAFE_INTEGER}))); +assert.throws(RangeError, () => pdt1.subtract(Temporal.Duration.from({milliseconds: Number.MIN_SAFE_INTEGER}))); + +assert.throws(RangeError, () => pdt1.subtract(Temporal.Duration.from({seconds: Number.MAX_SAFE_INTEGER}))); +assert.throws(RangeError, () => pdt1.subtract(Temporal.Duration.from({seconds: Number.MIN_SAFE_INTEGER}))); + +const bigNumber = 9007199254740990976; + +TemporalHelpers.assertPlainDateTime(pdt1.subtract(Temporal.Duration.from({nanoseconds: bigNumber})), + 1734, 9, "M09", 26, 1, 9, 53, 6, 621, 602); +TemporalHelpers.assertPlainDateTime(pdt1.subtract(Temporal.Duration.from({nanoseconds: -bigNumber})), + 2305, 8, "M08", 4, 0, 45, 2, 488, 603, 554); + +assert.throws(RangeError, () => pdt1.subtract(Temporal.Duration.from({microseconds: bigNumber}))); +assert.throws(RangeError, () => pdt1.subtract(Temporal.Duration.from({microseconds: -bigNumber}))); + +assert.throws(RangeError, () => pdt1.subtract(Temporal.Duration.from({milliseconds: bigNumber}))); +assert.throws(RangeError, () => pdt1.subtract(Temporal.Duration.from({milliseconds: -bigNumber}))); + +const pdt2 = new Temporal.PlainDateTime(0, 1, 1); + +TemporalHelpers.assertPlainDateTime(pdt2.subtract(Temporal.Duration.from({nanoseconds: bigNumber})), + -286, 7, "M07", 29, 0, 12, 25, 259, 9, 24); +TemporalHelpers.assertPlainDateTime(pdt2.subtract(Temporal.Duration.from({nanoseconds: -bigNumber})), + 285, 6, "M06", 4, 23, 47, 34, 740, 990, 976); + +assert.throws(RangeError, () => pdt2.subtract(Temporal.Duration.from({microseconds: bigNumber}))); +assert.throws(RangeError, () => pdt2.subtract(Temporal.Duration.from({microseconds: -bigNumber}))); + +assert.throws(RangeError, () => pdt2.subtract(Temporal.Duration.from({milliseconds: bigNumber}))); +assert.throws(RangeError, () => pdt2.subtract(Temporal.Duration.from({milliseconds: -bigNumber}))); diff --git a/test/built-ins/Temporal/PlainDateTime/prototype/toString/fractionalseconddigits-negative.js b/test/built-ins/Temporal/PlainDateTime/prototype/toString/fractionalseconddigits-negative.js new file mode 100644 index 0000000000..34fbf2332b --- /dev/null +++ b/test/built-ins/Temporal/PlainDateTime/prototype/toString/fractionalseconddigits-negative.js @@ -0,0 +1,12 @@ +// Copyright (C) 2025 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: Epoch milliseconds should be rounded down before adding negative micro/nanoseconds back in +features: [Temporal] +---*/ + +const pdt = new Temporal.PlainDateTime(1938, 4, 24, 22, 13, 19, 999, 999); +assert.sameValue(pdt.toString(), "1938-04-24T22:13:19.999999", + "epoch milliseconds should be rounded down to compute seconds"); diff --git a/test/built-ins/Temporal/PlainDateTime/prototype/until/argument-propertybag-optional-properties.js b/test/built-ins/Temporal/PlainDateTime/prototype/until/argument-propertybag-optional-properties.js new file mode 100644 index 0000000000..39ff460d78 --- /dev/null +++ b/test/built-ins/Temporal/PlainDateTime/prototype/until/argument-propertybag-optional-properties.js @@ -0,0 +1,34 @@ +// Copyright (C) 2025 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 property bag missing optional properties is equivalent to a property bag + with all the optional properties having their default values +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); + +const minimumProperties = { + year: 2021, + month: 10, + day: 28, +}; +const allProperties = { + year: 2021, + month: 10, + day: 28, + hour: 0, + minute: 0, + second: 0, + millisecond: 0, + microsecond: 0, + nanosecond: 0, + calendar: "iso8601", +}; +const resultWithout = instance.until(minimumProperties); +const resultWith = instance.until(allProperties); +TemporalHelpers.assertDurationsEqual(resultWithout, resultWith, "results should be the same with and without optional properties"); diff --git a/test/built-ins/Temporal/PlainDateTime/prototype/until/float64-representable-integer.js b/test/built-ins/Temporal/PlainDateTime/prototype/until/float64-representable-integer.js new file mode 100644 index 0000000000..6e9424817c --- /dev/null +++ b/test/built-ins/Temporal/PlainDateTime/prototype/until/float64-representable-integer.js @@ -0,0 +1,20 @@ +// Copyright (C) 2025 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: Internal representation of Duration uses float64-representable integers +features: [Temporal] +---*/ + +const dt1 = new Temporal.PlainDateTime(1970, 1, 1); +const dt2 = new Temporal.PlainDateTime(2554, 7, 21, 23, 34, 33, 709, 551, 616); +const result = dt1.until(dt2, { largestUnit: "microseconds" }); + +// ℝ(𝔽(18446744073709551)) = 18446744073709552 +assert.sameValue(result.microseconds, 18446744073709552, + "microseconds result should have FP precision loss"); +assert.sameValue(result.toString(), "PT18446744073.709552616S", + "Duration.p.toString() should not use more precise internal representation than the spec prescribes"); +assert.sameValue(Temporal.Duration.compare(result.add({ microseconds: 1 }), result), 0, + "subsequent ops on duration should not use more precise internal representation than the spec prescribes"); diff --git a/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-wrong-type.js b/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-wrong-type.js index 2eb77a2b2d..9668217ab3 100644 --- a/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-wrong-type.js +++ b/test/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-wrong-type.js @@ -14,7 +14,7 @@ const instance = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, const wrongTypeTests = [ [null, "null"], [true, "boolean"], - [1, "number that doesn't convert to a valid ISO string"], + [1, "number"], [1n, "bigint"], [19970327, "large number"], [-19970327, "negative number"], @@ -28,6 +28,6 @@ for (const [arg, description] of wrongTypeTests) { assert.throws( TypeError, () => instance.withCalendar(arg), - `${description} does not convert to a valid ISO string` + `${description} is not a valid calendar` ); } diff --git a/test/built-ins/Temporal/PlainDateTime/prototype/withPlainTime/argument-propertybag-optional-properties.js b/test/built-ins/Temporal/PlainDateTime/prototype/withPlainTime/argument-propertybag-optional-properties.js new file mode 100644 index 0000000000..4ab3380f0d --- /dev/null +++ b/test/built-ins/Temporal/PlainDateTime/prototype/withPlainTime/argument-propertybag-optional-properties.js @@ -0,0 +1,27 @@ +// Copyright (C) 2025 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: > + A property bag missing optional properties is equivalent to a property bag + with all the optional properties having their default values +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); + +const minimumProperties = { + hour: 0, +}; +const allProperties = { + hour: 0, + minute: 0, + second: 0, + millisecond: 0, + microsecond: 0, + nanosecond: 0, +}; +const resultWithout = instance.withPlainTime(minimumProperties); +const resultWith = instance.withPlainTime(allProperties); +assert(resultWithout.equals(resultWith), "results should be the same with and without optional properties"); diff --git a/test/built-ins/Temporal/PlainMonthDay/from/monthcode-invalid.js b/test/built-ins/Temporal/PlainMonthDay/from/monthcode-invalid.js index 8685df78a2..172ad12724 100644 --- a/test/built-ins/Temporal/PlainMonthDay/from/monthcode-invalid.js +++ b/test/built-ins/Temporal/PlainMonthDay/from/monthcode-invalid.js @@ -9,7 +9,9 @@ features: [Temporal] ["m1", "M1", "m01"].forEach((monthCode) => { assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ monthCode, day: 17 }), - `monthCode '${monthCode}' is not well-formed`); + `monthCode '${monthCode}' is not well-formed (without numeric month)`); + assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ month: 1, monthCode, day: 17 }), + `monthCode '${monthCode}' is not well-formed (with numeric month)`); }); assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ year: 2021, month: 12, monthCode: "M11", day: 17 }), @@ -17,7 +19,19 @@ assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ year: 2021, month: ["M00", "M19", "M99", "M13", "M00L", "M05L", "M13L"].forEach((monthCode) => { assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ monthCode, day: 17 }), - `monthCode '${monthCode}' is not valid for ISO 8601 calendar`); + `monthCode '${monthCode}' is not valid for ISO 8601 calendar (without numeric month)`); + var monthNumber = Number(monthCode.slice(1, 3)) + (monthCode.length - 3); + assert.throws( + RangeError, + () => Temporal.PlainMonthDay.from({ month: monthNumber, monthCode, day: 17 }), + `monthCode '${monthCode}' is not valid for ISO 8601 calendar (with numeric month)` + ); + var clampedMonthNumber = monthNumber < 1 ? 1 : monthNumber > 12 ? 12 : monthNumber; + assert.throws( + RangeError, + () => Temporal.PlainMonthDay.from({ month: clampedMonthNumber, monthCode, day: 17 }), + `monthCode '${monthCode}' is not valid for ISO 8601 calendar (with clamped numeric month)` + ); }); assert.throws( diff --git a/test/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-wrong-type.js b/test/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-wrong-type.js index 19115e4192..9ffe5f6efa 100644 --- a/test/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-wrong-type.js +++ b/test/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-wrong-type.js @@ -14,7 +14,7 @@ const instance = new Temporal.PlainMonthDay(5, 2); const wrongTypeTests = [ [null, "null"], [true, "boolean"], - [1, "number that doesn't convert to a valid ISO string"], + [1, "number"], [1n, "bigint"], [19970327, "large number"], [-19970327, "negative number"], @@ -29,6 +29,6 @@ for (const [calendar, description] of wrongTypeTests) { assert.throws( TypeError, () => instance.equals(arg), - `${description} does not convert to a valid ISO string` + `${description} is not a valid calendar` ); } diff --git a/test/built-ins/Temporal/PlainTime/compare/argument-propertybag-optional-properties.js b/test/built-ins/Temporal/PlainTime/compare/argument-propertybag-optional-properties.js new file mode 100644 index 0000000000..efaff3c0f6 --- /dev/null +++ b/test/built-ins/Temporal/PlainTime/compare/argument-propertybag-optional-properties.js @@ -0,0 +1,25 @@ +// Copyright (C) 2025 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: > + A property bag missing optional properties is equivalent to a property bag + with all the optional properties having their default values +features: [Temporal] +---*/ + +const minimumProperties = { + hour: 0, +}; +const allProperties = { + hour: 0, + minute: 0, + second: 0, + millisecond: 0, + microsecond: 0, + nanosecond: 0, +}; +const resultWithout = Temporal.PlainTime.compare(minimumProperties, minimumProperties); +const resultWith = Temporal.PlainTime.compare(allProperties, allProperties); +assert.sameValue(resultWithout, resultWith, "results should be the same with and without optional properties"); diff --git a/test/built-ins/Temporal/PlainTime/from/argument-propertybag-optional-properties.js b/test/built-ins/Temporal/PlainTime/from/argument-propertybag-optional-properties.js new file mode 100644 index 0000000000..6bef0d0964 --- /dev/null +++ b/test/built-ins/Temporal/PlainTime/from/argument-propertybag-optional-properties.js @@ -0,0 +1,25 @@ +// Copyright (C) 2025 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: > + A property bag missing optional properties is equivalent to a property bag + with all the optional properties having their default values +features: [Temporal] +---*/ + +const minimumProperties = { + hour: 0, +}; +const allProperties = { + hour: 0, + minute: 0, + second: 0, + millisecond: 0, + microsecond: 0, + nanosecond: 0, +}; +const resultWithout = Temporal.PlainTime.from(minimumProperties); +const resultWith = Temporal.PlainTime.from(allProperties); +assert(resultWithout.equals(resultWith), "results should be the same with and without optional properties"); diff --git a/test/built-ins/Temporal/PlainTime/prototype/add/add-large-subseconds.js b/test/built-ins/Temporal/PlainTime/prototype/add/add-large-subseconds.js new file mode 100644 index 0000000000..b909a44622 --- /dev/null +++ b/test/built-ins/Temporal/PlainTime/prototype/add/add-large-subseconds.js @@ -0,0 +1,65 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.add +description: Adding unbalanced durations with large subsecond values to a time +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const t1 = new Temporal.PlainTime(0, 57, 27, 747, 612, 578); + +TemporalHelpers.assertPlainTime(t1.add(Temporal.Duration.from({nanoseconds: Number.MAX_SAFE_INTEGER})), + 6, 57, 27, 2, 353, 569); +TemporalHelpers.assertPlainTime(t1.add(Temporal.Duration.from({nanoseconds: Number.MIN_SAFE_INTEGER})), + 18, 57, 28, 492, 871, 587); + +TemporalHelpers.assertPlainTime(t1.add(Temporal.Duration.from({microseconds: Number.MAX_SAFE_INTEGER})), + 0, 45, 2, 488, 603, 578); +TemporalHelpers.assertPlainTime(t1.add(Temporal.Duration.from({microseconds: Number.MIN_SAFE_INTEGER})), + 1, 9, 53, 6, 621, 578); + +TemporalHelpers.assertPlainTime(t1.add(Temporal.Duration.from({milliseconds: Number.MAX_SAFE_INTEGER})), + 9, 56, 28, 738, 612, 578); +TemporalHelpers.assertPlainTime(t1.add(Temporal.Duration.from({milliseconds: Number.MIN_SAFE_INTEGER})), + 15, 58, 26, 756, 612, 578); + +TemporalHelpers.assertPlainTime(t1.add(Temporal.Duration.from({seconds: Number.MAX_SAFE_INTEGER})), + 8, 33, 58, 747, 612, 578); +TemporalHelpers.assertPlainTime(t1.add(Temporal.Duration.from({seconds: Number.MIN_SAFE_INTEGER})), + 17, 20, 56, 747, 612, 578); + +const bigNumber = 9007199254740990976; + +TemporalHelpers.assertPlainTime(t1.add(Temporal.Duration.from({nanoseconds: bigNumber})), + 0, 45, 2, 488, 603, 554); +TemporalHelpers.assertPlainTime(t1.add(Temporal.Duration.from({nanoseconds: -bigNumber})), + 1, 9, 53, 6, 621, 602); + +TemporalHelpers.assertPlainTime(t1.add(Temporal.Duration.from({microseconds: bigNumber})), + 9, 56, 28, 738, 588, 578); +TemporalHelpers.assertPlainTime(t1.add(Temporal.Duration.from({microseconds: -bigNumber})), + 15, 58, 26, 756, 636, 578); + +TemporalHelpers.assertPlainTime(t1.add(Temporal.Duration.from({milliseconds: bigNumber})), + 8, 33, 58, 723, 612, 578); +TemporalHelpers.assertPlainTime(t1.add(Temporal.Duration.from({milliseconds: -bigNumber})), + 17, 20, 56, 771, 612, 578); + +const t2 = new Temporal.PlainTime(0); + +TemporalHelpers.assertPlainTime(t2.add(Temporal.Duration.from({nanoseconds: bigNumber})), + 23, 47, 34, 740, 990, 976); +TemporalHelpers.assertPlainTime(t2.add(Temporal.Duration.from({nanoseconds: -bigNumber})), + 0, 12, 25, 259, 9, 24); + +TemporalHelpers.assertPlainTime(t2.add(Temporal.Duration.from({microseconds: bigNumber})), + 8, 59, 0, 990, 976, 0); +TemporalHelpers.assertPlainTime(t2.add(Temporal.Duration.from({microseconds: -bigNumber})), + 15, 0, 59, 9, 24, 0); + +TemporalHelpers.assertPlainTime(t2.add(Temporal.Duration.from({milliseconds: bigNumber})), + 7, 36, 30, 976, 0, 0); +TemporalHelpers.assertPlainTime(t2.add(Temporal.Duration.from({milliseconds: -bigNumber})), + 16, 23, 29, 24, 0, 0); diff --git a/test/built-ins/Temporal/PlainTime/prototype/add/argument-propertybag-optional-properties.js b/test/built-ins/Temporal/PlainTime/prototype/add/argument-propertybag-optional-properties.js new file mode 100644 index 0000000000..7b3dcf0060 --- /dev/null +++ b/test/built-ins/Temporal/PlainTime/prototype/add/argument-propertybag-optional-properties.js @@ -0,0 +1,31 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.add +description: > + A property bag missing optional properties is equivalent to a property bag + with all the optional properties having their default values +features: [Temporal] +---*/ + +const instance = new Temporal.PlainTime(); + +const oneProperty = { + hours: 1, +}; +const allProperties = { + years: 0, + months: 0, + weeks: 0, + days: 0, + hours: 1, + minutes: 0, + seconds: 0, + milliseconds: 0, + microseconds: 0, + nanoseconds: 0, +}; +const resultWithout = instance.add(oneProperty); +const resultWith = instance.add(allProperties); +assert(resultWithout.equals(resultWith), "results should be the same with and without optional properties"); diff --git a/test/built-ins/Temporal/PlainTime/prototype/equals/argument-propertybag-optional-properties.js b/test/built-ins/Temporal/PlainTime/prototype/equals/argument-propertybag-optional-properties.js new file mode 100644 index 0000000000..3e0cc3aa9c --- /dev/null +++ b/test/built-ins/Temporal/PlainTime/prototype/equals/argument-propertybag-optional-properties.js @@ -0,0 +1,27 @@ +// Copyright (C) 2025 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: > + A property bag missing optional properties is equivalent to a property bag + with all the optional properties having their default values +features: [Temporal] +---*/ + +const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); + +const minimumProperties = { + hour: 0, +}; +const allProperties = { + hour: 0, + minute: 0, + second: 0, + millisecond: 0, + microsecond: 0, + nanosecond: 0, +}; +const resultWithout = instance.equals(minimumProperties); +const resultWith = instance.equals(allProperties); +assert.sameValue(resultWithout, resultWith, "results should be the same with and without optional properties"); diff --git a/test/built-ins/Temporal/PlainTime/prototype/since/argument-propertybag-optional-properties.js b/test/built-ins/Temporal/PlainTime/prototype/since/argument-propertybag-optional-properties.js new file mode 100644 index 0000000000..bd8572e4bf --- /dev/null +++ b/test/built-ins/Temporal/PlainTime/prototype/since/argument-propertybag-optional-properties.js @@ -0,0 +1,28 @@ +// Copyright (C) 2025 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: > + A property bag missing optional properties is equivalent to a property bag + with all the optional properties having their default values +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); + +const minimumProperties = { + hour: 0, +}; +const allProperties = { + hour: 0, + minute: 0, + second: 0, + millisecond: 0, + microsecond: 0, + nanosecond: 0, +}; +const resultWithout = instance.since(minimumProperties); +const resultWith = instance.since(allProperties); +TemporalHelpers.assertDurationsEqual(resultWithout, resultWith, "results should be the same with and without optional properties"); diff --git a/test/built-ins/Temporal/PlainTime/prototype/subtract/argument-propertybag-optional-properties.js b/test/built-ins/Temporal/PlainTime/prototype/subtract/argument-propertybag-optional-properties.js new file mode 100644 index 0000000000..292fb692b1 --- /dev/null +++ b/test/built-ins/Temporal/PlainTime/prototype/subtract/argument-propertybag-optional-properties.js @@ -0,0 +1,31 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.subtract +description: > + A property bag missing optional properties is equivalent to a property bag + with all the optional properties having their default values +features: [Temporal] +---*/ + +const instance = new Temporal.PlainTime(); + +const oneProperty = { + hours: 1, +}; +const allProperties = { + years: 0, + months: 0, + weeks: 0, + days: 0, + hours: 1, + minutes: 0, + seconds: 0, + milliseconds: 0, + microseconds: 0, + nanoseconds: 0, +}; +const resultWithout = instance.subtract(oneProperty); +const resultWith = instance.subtract(allProperties); +assert(resultWithout.equals(resultWith), "results should be the same with and without optional properties"); diff --git a/test/built-ins/Temporal/PlainTime/prototype/subtract/subtract-large-subseconds.js b/test/built-ins/Temporal/PlainTime/prototype/subtract/subtract-large-subseconds.js new file mode 100644 index 0000000000..8fc2e46d29 --- /dev/null +++ b/test/built-ins/Temporal/PlainTime/prototype/subtract/subtract-large-subseconds.js @@ -0,0 +1,65 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.subtract +description: Subtracting unbalanced durations with large subsecond values from a time +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const t1 = new Temporal.PlainTime(0, 57, 27, 747, 612, 578); + +TemporalHelpers.assertPlainTime(t1.subtract(Temporal.Duration.from({nanoseconds: Number.MAX_SAFE_INTEGER})), + 18, 57, 28, 492, 871, 587); +TemporalHelpers.assertPlainTime(t1.subtract(Temporal.Duration.from({nanoseconds: Number.MIN_SAFE_INTEGER})), + 6, 57, 27, 2, 353, 569); + +TemporalHelpers.assertPlainTime(t1.subtract(Temporal.Duration.from({microseconds: Number.MAX_SAFE_INTEGER})), + 1, 9, 53, 6, 621, 578); +TemporalHelpers.assertPlainTime(t1.subtract(Temporal.Duration.from({microseconds: Number.MIN_SAFE_INTEGER})), + 0, 45, 2, 488, 603, 578); + +TemporalHelpers.assertPlainTime(t1.subtract(Temporal.Duration.from({milliseconds: Number.MAX_SAFE_INTEGER})), + 15, 58, 26, 756, 612, 578); +TemporalHelpers.assertPlainTime(t1.subtract(Temporal.Duration.from({milliseconds: Number.MIN_SAFE_INTEGER})), + 9, 56, 28, 738, 612, 578); + +TemporalHelpers.assertPlainTime(t1.subtract(Temporal.Duration.from({seconds: Number.MAX_SAFE_INTEGER})), + 17, 20, 56, 747, 612, 578); +TemporalHelpers.assertPlainTime(t1.subtract(Temporal.Duration.from({seconds: Number.MIN_SAFE_INTEGER})), + 8, 33, 58, 747, 612, 578); + +const bigNumber = 9007199254740990976; + +TemporalHelpers.assertPlainTime(t1.subtract(Temporal.Duration.from({nanoseconds: bigNumber})), + 1, 9, 53, 6, 621, 602); +TemporalHelpers.assertPlainTime(t1.subtract(Temporal.Duration.from({nanoseconds: -bigNumber})), + 0, 45, 2, 488, 603, 554); + +TemporalHelpers.assertPlainTime(t1.subtract(Temporal.Duration.from({microseconds: bigNumber})), + 15, 58, 26, 756, 636, 578); +TemporalHelpers.assertPlainTime(t1.subtract(Temporal.Duration.from({microseconds: -bigNumber})), + 9, 56, 28, 738, 588, 578); + +TemporalHelpers.assertPlainTime(t1.subtract(Temporal.Duration.from({milliseconds: bigNumber})), + 17, 20, 56, 771, 612, 578); +TemporalHelpers.assertPlainTime(t1.subtract(Temporal.Duration.from({milliseconds: -bigNumber})), + 8, 33, 58, 723, 612, 578); + +const t2 = new Temporal.PlainTime(0); + +TemporalHelpers.assertPlainTime(t2.subtract(Temporal.Duration.from({nanoseconds: bigNumber})), + 0, 12, 25, 259, 9, 24); +TemporalHelpers.assertPlainTime(t2.subtract(Temporal.Duration.from({nanoseconds: -bigNumber})), + 23, 47, 34, 740, 990, 976); + +TemporalHelpers.assertPlainTime(t2.subtract(Temporal.Duration.from({microseconds: bigNumber})), + 15, 0, 59, 9, 24, 0); +TemporalHelpers.assertPlainTime(t2.subtract(Temporal.Duration.from({microseconds: -bigNumber})), + 8, 59, 0, 990, 976, 0); + +TemporalHelpers.assertPlainTime(t2.subtract(Temporal.Duration.from({milliseconds: bigNumber})), + 16, 23, 29, 24, 0, 0); +TemporalHelpers.assertPlainTime(t2.subtract(Temporal.Duration.from({milliseconds: -bigNumber})), + 7, 36, 30, 976, 0, 0); diff --git a/test/built-ins/Temporal/PlainTime/prototype/until/argument-propertybag-optional-properties.js b/test/built-ins/Temporal/PlainTime/prototype/until/argument-propertybag-optional-properties.js new file mode 100644 index 0000000000..cd424fcd36 --- /dev/null +++ b/test/built-ins/Temporal/PlainTime/prototype/until/argument-propertybag-optional-properties.js @@ -0,0 +1,28 @@ +// Copyright (C) 2025 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: > + A property bag missing optional properties is equivalent to a property bag + with all the optional properties having their default values +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); + +const minimumProperties = { + hour: 0, +}; +const allProperties = { + hour: 0, + minute: 0, + second: 0, + millisecond: 0, + microsecond: 0, + nanosecond: 0, +}; +const resultWithout = instance.until(minimumProperties); +const resultWith = instance.until(allProperties); +TemporalHelpers.assertDurationsEqual(resultWithout, resultWith, "results should be the same with and without optional properties"); diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/add/argument-propertybag-optional-properties.js b/test/built-ins/Temporal/PlainYearMonth/prototype/add/argument-propertybag-optional-properties.js new file mode 100644 index 0000000000..86febf630e --- /dev/null +++ b/test/built-ins/Temporal/PlainYearMonth/prototype/add/argument-propertybag-optional-properties.js @@ -0,0 +1,31 @@ +// Copyright (C) 2025 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: > + A property bag missing optional properties is equivalent to a property bag + with all the optional properties having their default values +features: [Temporal] +---*/ + +const instance = new Temporal.PlainYearMonth(1970, 1); + +const oneProperty = { + hours: 1, +}; +const allProperties = { + years: 0, + months: 0, + weeks: 0, + days: 0, + hours: 1, + minutes: 0, + seconds: 0, + milliseconds: 0, + microseconds: 0, + nanoseconds: 0, +}; +const resultWithout = instance.add(oneProperty); +const resultWith = instance.add(allProperties); +assert(resultWithout.equals(resultWith), "results should be the same with and without optional properties"); diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/add/overflow-adding-months-to-max-year.js b/test/built-ins/Temporal/PlainYearMonth/prototype/add/overflow-adding-months-to-max-year.js new file mode 100644 index 0000000000..85f468ae85 --- /dev/null +++ b/test/built-ins/Temporal/PlainYearMonth/prototype/add/overflow-adding-months-to-max-year.js @@ -0,0 +1,15 @@ +// Copyright (C) 2025 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: Adding months to maximum year should throw +features: [Temporal] +---*/ + +const maxYear = new Temporal.PlainYearMonth(275760, 1); +const duration = new Temporal.Duration(0, 5432, 5432, 0, 0, 0, 0, 0, 0, 0); +assert.throws(RangeError, () => maxYear.add(duration)); + +const minYear = new Temporal.PlainYearMonth(-271821, 4); +assert.throws(RangeError, () => minYear.add(duration.negated())); diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-wrong-type.js b/test/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-wrong-type.js index 4ac01acbd7..fcd3426a3d 100644 --- a/test/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-wrong-type.js +++ b/test/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-wrong-type.js @@ -14,7 +14,7 @@ const instance = new Temporal.PlainYearMonth(2000, 5); const wrongTypeTests = [ [null, "null"], [true, "boolean"], - [1, "number that doesn't convert to a valid ISO string"], + [1, "number"], [1n, "bigint"], [19970327, "large positive number"], [-19970327, "negative number"], @@ -29,6 +29,6 @@ for (const [calendar, description] of wrongTypeTests) { assert.throws( TypeError, () => instance.equals(arg), - `${description} does not convert to a valid ISO string` + `${description} is not a valid calendar` ); } diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-wrong-type.js b/test/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-wrong-type.js index 4329f48cfa..a39c2d1e54 100644 --- a/test/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-wrong-type.js +++ b/test/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-wrong-type.js @@ -5,7 +5,7 @@ esid: sec-temporal.plainyearmonth.prototype.since description: > Appropriate error thrown when a calendar property from a property bag cannot - be converted to a calendar object or string + be converted to a calendar ID features: [BigInt, Symbol, Temporal] ---*/ @@ -14,7 +14,7 @@ const instance = new Temporal.PlainYearMonth(2000, 5); const wrongTypeTests = [ [null, "null"], [true, "boolean"], - [1, "number that doesn't convert to a valid ISO string"], + [1, "number"], [1n, "bigint"], [19970327, "large positive number"], [-19970327, "negative number"], @@ -29,6 +29,6 @@ for (const [calendar, description] of wrongTypeTests) { assert.throws( TypeError, () => instance.since(arg), - `${description} does not convert to a valid ISO string` + `${description} is not a valid calendar` ); } diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-propertybag-optional-properties.js b/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-propertybag-optional-properties.js new file mode 100644 index 0000000000..eeb79db632 --- /dev/null +++ b/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-propertybag-optional-properties.js @@ -0,0 +1,31 @@ +// Copyright (C) 2025 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: > + A property bag missing optional properties is equivalent to a property bag + with all the optional properties having their default values +features: [Temporal] +---*/ + +const instance = new Temporal.PlainYearMonth(1970, 1); + +const oneProperty = { + hours: 1, +}; +const allProperties = { + years: 0, + months: 0, + weeks: 0, + days: 0, + hours: 1, + minutes: 0, + seconds: 0, + milliseconds: 0, + microseconds: 0, + nanoseconds: 0, +}; +const resultWithout = instance.subtract(oneProperty); +const resultWith = instance.subtract(allProperties); +assert(resultWithout.equals(resultWith), "results should be the same with and without optional properties"); diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/overflow-subtracting-months-from-min-year.js b/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/overflow-subtracting-months-from-min-year.js new file mode 100644 index 0000000000..794761b1fd --- /dev/null +++ b/test/built-ins/Temporal/PlainYearMonth/prototype/subtract/overflow-subtracting-months-from-min-year.js @@ -0,0 +1,15 @@ +// Copyright (C) 2025 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: Subtracting months from minimum year should throw +features: [Temporal] +---*/ + +const minYear = new Temporal.PlainYearMonth(-271821, 4); +const duration = new Temporal.Duration(0, 5432, 5432, 0, 0, 0, 0, 0, 0, 0); +assert.throws(RangeError, () => minYear.subtract(duration)); + +const maxYear = new Temporal.PlainYearMonth(275760, 1); +assert.throws(RangeError, () => maxYear.subtract(duration.negated())); diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-wrong-type.js b/test/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-wrong-type.js index a2bd9a3361..cea74807e4 100644 --- a/test/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-wrong-type.js +++ b/test/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-wrong-type.js @@ -14,7 +14,7 @@ const instance = new Temporal.PlainYearMonth(2000, 5); const wrongTypeTests = [ [null, "null"], [true, "boolean"], - [1, "number that doesn't convert to a valid ISO string"], + [1, "number"], [1n, "bigint"], [19970327, "large positive number"], [-19970327, "large negative number"], @@ -29,6 +29,6 @@ for (const [calendar, description] of wrongTypeTests) { assert.throws( TypeError, () => instance.until(arg), - `${description} does not convert to a valid ISO string` + `${description} is not a valid calendar` ); } diff --git a/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-optional-properties.js b/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-optional-properties.js new file mode 100644 index 0000000000..53f9f9bbbc --- /dev/null +++ b/test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-optional-properties.js @@ -0,0 +1,34 @@ +// Copyright (C) 2025 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 property bag missing optional properties is equivalent to a property bag + with all the optional properties having their default values +features: [Temporal] +---*/ + +const minimumProperties = { + year: 2021, + month: 10, + day: 28, + timeZone: "UTC", +}; +const allProperties = { + year: 2021, + month: 10, + day: 28, + hour: 0, + minute: 0, + second: 0, + millisecond: 0, + microsecond: 0, + nanosecond: 0, + offset: "+00:00", + timeZone: "UTC", + calendar: "iso8601", +}; +const resultWithout = Temporal.ZonedDateTime.compare(minimumProperties, minimumProperties); +const resultWith = Temporal.ZonedDateTime.compare(allProperties, allProperties); +assert.sameValue(resultWithout, resultWith, "results should be the same with and without optional properties"); diff --git a/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-optional-properties.js b/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-optional-properties.js new file mode 100644 index 0000000000..886faaec75 --- /dev/null +++ b/test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-optional-properties.js @@ -0,0 +1,34 @@ +// Copyright (C) 2025 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 property bag missing optional properties is equivalent to a property bag + with all the optional properties having their default values +features: [Temporal] +---*/ + +const minimumProperties = { + year: 2021, + month: 10, + day: 28, + timeZone: "UTC", +}; +const allProperties = { + year: 2021, + month: 10, + day: 28, + hour: 0, + minute: 0, + second: 0, + millisecond: 0, + microsecond: 0, + nanosecond: 0, + offset: "+00:00", + timeZone: "UTC", + calendar: "iso8601", +}; +const resultWithout = Temporal.ZonedDateTime.from(minimumProperties); +const resultWith = Temporal.ZonedDateTime.from(allProperties); +assert(resultWithout.equals(resultWith), "results should be the same with and without optional properties"); diff --git a/test/built-ins/Temporal/ZonedDateTime/prototype/add/add-large-subseconds.js b/test/built-ins/Temporal/ZonedDateTime/prototype/add/add-large-subseconds.js new file mode 100644 index 0000000000..5f9040990c --- /dev/null +++ b/test/built-ins/Temporal/ZonedDateTime/prototype/add/add-large-subseconds.js @@ -0,0 +1,53 @@ +// Copyright (C) 2025 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: Adding unbalanced durations with large subsecond values to a datetime +features: [Temporal] +---*/ + +// const pdt1 = new Temporal.PlainDateTime(2020, 2, 29, 0, 57, 27, 747, 612, 578); +const zdt1 = new Temporal.ZonedDateTime(1582966647747612578n, "America/Los_Angeles"); + +assert.sameValue(zdt1.add(Temporal.Duration.from({nanoseconds: Number.MAX_SAFE_INTEGER})).epochNanoseconds, + 1591973847002353569n); +assert.sameValue(zdt1.add(Temporal.Duration.from({nanoseconds: Number.MIN_SAFE_INTEGER})).epochNanoseconds, + 1573959448492871587n); + +assert.sameValue(zdt1.add(Temporal.Duration.from({microseconds: Number.MAX_SAFE_INTEGER})).epochNanoseconds, + 10590165902488603578n); +assert.sameValue(zdt1.add(Temporal.Duration.from({microseconds: Number.MIN_SAFE_INTEGER})).epochNanoseconds, + -7424232606993378422n); + +assert.throws(RangeError, () => zdt1.add(Temporal.Duration.from({milliseconds: Number.MAX_SAFE_INTEGER}))); +assert.throws(RangeError, () => zdt1.add(Temporal.Duration.from({milliseconds: Number.MIN_SAFE_INTEGER}))); + +assert.throws(RangeError, () => zdt1.add(Temporal.Duration.from({seconds: Number.MAX_SAFE_INTEGER}))); +assert.throws(RangeError, () => zdt1.add(Temporal.Duration.from({seconds: Number.MIN_SAFE_INTEGER}))); + +const bigNumber = 9007199254740990976; + +assert.sameValue(zdt1.add(Temporal.Duration.from({nanoseconds: bigNumber})).epochNanoseconds, + 10590165902488603554n); +assert.sameValue(zdt1.add(Temporal.Duration.from({nanoseconds: -bigNumber})).epochNanoseconds, + -7424232606993378398n); + +assert.throws(RangeError, () => zdt1.add(Temporal.Duration.from({milliseconds: bigNumber}))); +assert.throws(RangeError, () => zdt1.add(Temporal.Duration.from({milliseconds: -bigNumber}))); + +assert.throws(RangeError, () => zdt1.add(Temporal.Duration.from({microseconds: bigNumber}))); +assert.throws(RangeError, () => zdt1.add(Temporal.Duration.from({microseconds: -bigNumber}))); + +const zdt2 = new Temporal.ZonedDateTime(0n, "UTC"); + +assert.sameValue(zdt2.add(Temporal.Duration.from({nanoseconds: bigNumber})).epochNanoseconds, + 9007199254740990976n); +assert.sameValue(zdt2.add(Temporal.Duration.from({nanoseconds: -bigNumber})).epochNanoseconds, + -9007199254740990976n); + +assert.throws(RangeError, () => zdt2.add(Temporal.Duration.from({milliseconds: bigNumber}))); +assert.throws(RangeError, () => zdt2.add(Temporal.Duration.from({milliseconds: -bigNumber}))); + +assert.throws(RangeError, () => zdt2.add(Temporal.Duration.from({microseconds: bigNumber}))); +assert.throws(RangeError, () => zdt2.add(Temporal.Duration.from({microseconds: -bigNumber}))); diff --git a/test/built-ins/Temporal/ZonedDateTime/prototype/add/argument-propertybag-optional-properties.js b/test/built-ins/Temporal/ZonedDateTime/prototype/add/argument-propertybag-optional-properties.js new file mode 100644 index 0000000000..61fb3392a6 --- /dev/null +++ b/test/built-ins/Temporal/ZonedDateTime/prototype/add/argument-propertybag-optional-properties.js @@ -0,0 +1,31 @@ +// Copyright (C) 2025 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: > + A property bag missing optional properties is equivalent to a property bag + with all the optional properties having their default values +features: [Temporal] +---*/ + +const instance = new Temporal.ZonedDateTime(0n, "UTC"); + +const oneProperty = { + hours: 1, +}; +const allProperties = { + years: 0, + months: 0, + weeks: 0, + days: 0, + hours: 1, + minutes: 0, + seconds: 0, + milliseconds: 0, + microseconds: 0, + nanoseconds: 0, +}; +const resultWithout = instance.add(oneProperty); +const resultWith = instance.add(allProperties); +assert(resultWithout.equals(resultWith), "results should be the same with and without optional properties"); diff --git a/test/built-ins/Temporal/ZonedDateTime/prototype/add/overflow-adding-months-to-max-year.js b/test/built-ins/Temporal/ZonedDateTime/prototype/add/overflow-adding-months-to-max-year.js new file mode 100644 index 0000000000..57f12c1e5a --- /dev/null +++ b/test/built-ins/Temporal/ZonedDateTime/prototype/add/overflow-adding-months-to-max-year.js @@ -0,0 +1,15 @@ +// Copyright (C) 2025 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: Adding months to maximum year should throw +features: [Temporal] +---*/ + +const maxYear = new Temporal.PlainDate(275760, 1, 1).toZonedDateTime("UTC"); +const duration = new Temporal.Duration(0, 5432, 5432, 0, 0, 0, 0, 0, 0, 0); +assert.throws(RangeError, () => maxYear.add(duration)); + +const minYear = new Temporal.ZonedDateTime(-(864n * 10n ** 19n), "UTC"); +assert.throws(RangeError, () => minYear.add(duration.negated())); diff --git a/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-wrong-type.js b/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-wrong-type.js index 3dc8f562fa..a4d912d712 100644 --- a/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-wrong-type.js +++ b/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-wrong-type.js @@ -12,10 +12,10 @@ features: [BigInt, Symbol, Temporal] const timeZone = "UTC"; const instance = new Temporal.ZonedDateTime(0n, timeZone); -const primitiveTests = [ +const wrongTypeTests = [ [null, "null"], [true, "boolean"], - [1, "number that doesn't convert to a valid ISO string"], + [1, "number"], [1n, "bigint"], [19970327, "large number"], [-19970327, "negative number"], @@ -25,11 +25,11 @@ const primitiveTests = [ [new Temporal.Duration(), "duration instance"], ]; -for (const [calendar, description] of primitiveTests) { +for (const [calendar, description] of wrongTypeTests) { const arg = { year: 2019, monthCode: "M11", day: 1, calendar }; assert.throws( TypeError, () => instance.equals(arg), - `${description} does not convert to a valid ISO string` + `${description} is not a valid calendar` ); } diff --git a/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-optional-properties.js b/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-optional-properties.js new file mode 100644 index 0000000000..37fbf688b2 --- /dev/null +++ b/test/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-optional-properties.js @@ -0,0 +1,37 @@ +// Copyright (C) 2025 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 property bag missing optional properties is equivalent to a property bag + with all the optional properties having their default values +features: [Temporal] +---*/ + +const timeZone = "UTC"; +const instance = new Temporal.ZonedDateTime(0n, timeZone); + +const minimumProperties = { + year: 2021, + month: 10, + day: 28, + timeZone, +}; +const allProperties = { + year: 2021, + month: 10, + day: 28, + hour: 0, + minute: 0, + second: 0, + millisecond: 0, + microsecond: 0, + nanosecond: 0, + offset: "+00:00", + timeZone, + calendar: "iso8601", +}; +const resultWithout = instance.equals(minimumProperties); +const resultWith = instance.equals(allProperties); +assert.sameValue(resultWithout, resultWith, "results should be the same with and without optional properties"); diff --git a/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-wrong-type.js b/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-wrong-type.js index 014f3568a3..2addee30a0 100644 --- a/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-wrong-type.js +++ b/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-wrong-type.js @@ -5,7 +5,7 @@ esid: sec-temporal.zoneddatetime.prototype.since description: > Appropriate error thrown when a calendar property from a property bag cannot - be converted to a calendar object or string + be converted to a calendar ID features: [BigInt, Symbol, Temporal] ---*/ @@ -15,7 +15,7 @@ const instance = new Temporal.ZonedDateTime(0n, timeZone); const wrongTypeTests = [ [null, "null"], [true, "boolean"], - [1, "number that doesn't convert to a valid ISO string"], + [1, "number"], [1n, "bigint"], [19970327, "large number"], [-19970327, "negative number"], @@ -30,6 +30,6 @@ for (const [calendar, description] of wrongTypeTests) { assert.throws( TypeError, () => instance.since(arg), - `${description} does not convert to a valid ISO string` + `${description} is not a valid calendar` ); } diff --git a/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-optional-properties.js b/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-optional-properties.js new file mode 100644 index 0000000000..72cdcd67d0 --- /dev/null +++ b/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-optional-properties.js @@ -0,0 +1,38 @@ +// Copyright (C) 2025 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 property bag missing optional properties is equivalent to a property bag + with all the optional properties having their default values +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const timeZone = "UTC"; +const instance = new Temporal.ZonedDateTime(0n, timeZone); + +const minimumProperties = { + year: 2021, + month: 10, + day: 28, + timeZone, +}; +const allProperties = { + year: 2021, + month: 10, + day: 28, + hour: 0, + minute: 0, + second: 0, + millisecond: 0, + microsecond: 0, + nanosecond: 0, + offset: "+00:00", + timeZone, + calendar: "iso8601", +}; +const resultWithout = instance.since(minimumProperties); +const resultWith = instance.since(allProperties); +TemporalHelpers.assertDurationsEqual(resultWithout, resultWith, "results should be the same with and without optional properties"); diff --git a/test/built-ins/Temporal/ZonedDateTime/prototype/since/float64-representable-integer.js b/test/built-ins/Temporal/ZonedDateTime/prototype/since/float64-representable-integer.js new file mode 100644 index 0000000000..be329fdbff --- /dev/null +++ b/test/built-ins/Temporal/ZonedDateTime/prototype/since/float64-representable-integer.js @@ -0,0 +1,20 @@ +// Copyright (C) 2025 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: Internal representation of Duration uses float64-representable integers +features: [Temporal] +---*/ + +const z1 = new Temporal.ZonedDateTime(0n, "UTC"); +const z2 = new Temporal.ZonedDateTime(18446744073_709_551_616n, "UTC"); +const result = z1.since(z2, { largestUnit: "microseconds" }); + +// ℝ(𝔽(-18446744073709551)) = -18446744073709552 +assert.sameValue(result.microseconds, -18446744073709552, + "microseconds result should have FP precision loss"); +assert.sameValue(result.toString(), "-PT18446744073.709552616S", + "Duration.p.toString() should not use more precise internal representation than the spec prescribes"); +assert.sameValue(Temporal.Duration.compare(result.add({ microseconds: 1 }), result), 0, + "subsequent ops on duration should not use more precise internal representation than the spec prescribes"); diff --git a/test/built-ins/Temporal/ZonedDateTime/prototype/subtract/argument-propertybag-optional-properties.js b/test/built-ins/Temporal/ZonedDateTime/prototype/subtract/argument-propertybag-optional-properties.js new file mode 100644 index 0000000000..2cf85bcf11 --- /dev/null +++ b/test/built-ins/Temporal/ZonedDateTime/prototype/subtract/argument-propertybag-optional-properties.js @@ -0,0 +1,31 @@ +// Copyright (C) 2025 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: > + A property bag missing optional properties is equivalent to a property bag + with all the optional properties having their default values +features: [Temporal] +---*/ + +const instance = new Temporal.ZonedDateTime(0n, "UTC"); + +const oneProperty = { + hours: 1, +}; +const allProperties = { + years: 0, + months: 0, + weeks: 0, + days: 0, + hours: 1, + minutes: 0, + seconds: 0, + milliseconds: 0, + microseconds: 0, + nanoseconds: 0, +}; +const resultWithout = instance.subtract(oneProperty); +const resultWith = instance.subtract(allProperties); +assert(resultWithout.equals(resultWith), "results should be the same with and without optional properties"); diff --git a/test/built-ins/Temporal/ZonedDateTime/prototype/subtract/overflow-subtracting-months-from-min-year.js b/test/built-ins/Temporal/ZonedDateTime/prototype/subtract/overflow-subtracting-months-from-min-year.js new file mode 100644 index 0000000000..b16643b08a --- /dev/null +++ b/test/built-ins/Temporal/ZonedDateTime/prototype/subtract/overflow-subtracting-months-from-min-year.js @@ -0,0 +1,15 @@ +// Copyright (C) 2025 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: Subtracting months from minimum year should throw +features: [Temporal] +---*/ + +const minYear = new Temporal.ZonedDateTime(-(864n * 10n ** 19n), "UTC"); +const duration = new Temporal.Duration(0, 5432, 5432, 0, 0, 0, 0, 0, 0, 0); +assert.throws(RangeError, () => minYear.subtract(duration)); + +const maxYear = new Temporal.PlainDateTime(275760, 1, 1).toZonedDateTime("UTC"); +assert.throws(RangeError, () => maxYear.subtract(duration.negated())); diff --git a/test/built-ins/Temporal/ZonedDateTime/prototype/subtract/subtract-large-subseconds.js b/test/built-ins/Temporal/ZonedDateTime/prototype/subtract/subtract-large-subseconds.js new file mode 100644 index 0000000000..96228605c4 --- /dev/null +++ b/test/built-ins/Temporal/ZonedDateTime/prototype/subtract/subtract-large-subseconds.js @@ -0,0 +1,53 @@ +// Copyright (C) 2025 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: Subtracting unbalanced durations with large subsecond values from a date +features: [Temporal] +---*/ + +// const pdt1 = new Temporal.PlainDateTime(2020, 2, 29, 0, 57, 27, 747, 612, 578); +const zdt1 = new Temporal.ZonedDateTime(1582966647747612578n, "America/Los_Angeles"); + +assert.sameValue(zdt1.subtract(Temporal.Duration.from({nanoseconds: Number.MAX_SAFE_INTEGER})).epochNanoseconds, + 1573959448492871587n); +assert.sameValue(zdt1.subtract(Temporal.Duration.from({nanoseconds: Number.MIN_SAFE_INTEGER})).epochNanoseconds, + 1591973847002353569n); + +assert.sameValue(zdt1.subtract(Temporal.Duration.from({microseconds: Number.MAX_SAFE_INTEGER})).epochNanoseconds, + -7424232606993378422n); +assert.sameValue(zdt1.subtract(Temporal.Duration.from({microseconds: Number.MIN_SAFE_INTEGER})).epochNanoseconds, + 10590165902488603578n); + +assert.throws(RangeError, () => zdt1.subtract(Temporal.Duration.from({milliseconds: Number.MAX_SAFE_INTEGER}))); +assert.throws(RangeError, () => zdt1.subtract(Temporal.Duration.from({milliseconds: Number.MIN_SAFE_INTEGER}))); + +assert.throws(RangeError, () => zdt1.subtract(Temporal.Duration.from({seconds: Number.MAX_SAFE_INTEGER}))); +assert.throws(RangeError, () => zdt1.subtract(Temporal.Duration.from({seconds: Number.MIN_SAFE_INTEGER}))); + +const bigNumber = 9007199254740990976; + +assert.sameValue(zdt1.subtract(Temporal.Duration.from({nanoseconds: bigNumber})).epochNanoseconds, + -7424232606993378398n); +assert.sameValue(zdt1.subtract(Temporal.Duration.from({nanoseconds: -bigNumber})).epochNanoseconds, + 10590165902488603554n); + +assert.throws(RangeError, () => zdt1.subtract(Temporal.Duration.from({microseconds: bigNumber}))); +assert.throws(RangeError, () => zdt1.subtract(Temporal.Duration.from({microseconds: -bigNumber}))); + +assert.throws(RangeError, () => zdt1.subtract(Temporal.Duration.from({milliseconds: bigNumber}))); +assert.throws(RangeError, () => zdt1.subtract(Temporal.Duration.from({milliseconds: -bigNumber}))); + +const zdt2 = new Temporal.ZonedDateTime(0n, "UTC"); + +assert.sameValue(zdt2.subtract(Temporal.Duration.from({nanoseconds: bigNumber})).epochNanoseconds, + -9007199254740990976n); +assert.sameValue(zdt2.subtract(Temporal.Duration.from({nanoseconds: -bigNumber})).epochNanoseconds, + 9007199254740990976n); + +assert.throws(RangeError, () => zdt2.subtract(Temporal.Duration.from({microseconds: bigNumber}))); +assert.throws(RangeError, () => zdt2.subtract(Temporal.Duration.from({microseconds: -bigNumber}))); + +assert.throws(RangeError, () => zdt2.subtract(Temporal.Duration.from({milliseconds: bigNumber}))); +assert.throws(RangeError, () => zdt2.subtract(Temporal.Duration.from({milliseconds: -bigNumber}))); diff --git a/test/built-ins/Temporal/ZonedDateTime/prototype/toString/fractionalseconddigits-negative.js b/test/built-ins/Temporal/ZonedDateTime/prototype/toString/fractionalseconddigits-negative.js new file mode 100644 index 0000000000..4d78a0a811 --- /dev/null +++ b/test/built-ins/Temporal/ZonedDateTime/prototype/toString/fractionalseconddigits-negative.js @@ -0,0 +1,12 @@ +// Copyright (C) 2025 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: Epoch milliseconds should be rounded down before adding negative micro/nanoseconds back in +features: [BigInt, Temporal] +---*/ + +const zdt = new Temporal.ZonedDateTime(-1000000000000001000n, "UTC"); +assert.sameValue(zdt.toString(), "1938-04-24T22:13:19.999999+00:00[UTC]", + "epoch milliseconds should be rounded down to compute seconds"); diff --git a/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-wrong-type.js b/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-wrong-type.js index dde24b9baa..345df237d0 100644 --- a/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-wrong-type.js +++ b/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-wrong-type.js @@ -15,7 +15,7 @@ const instance = new Temporal.ZonedDateTime(0n, timeZone); const wrongTypeTests = [ [null, "null"], [true, "boolean"], - [1, "number that doesn't convert to a valid ISO string"], + [1, "number"], [1n, "bigint"], [19970327, "large number"], [-19970327, "negative number"], @@ -30,6 +30,6 @@ for (const [calendar, description] of wrongTypeTests) { assert.throws( TypeError, () => instance.until(arg), - `${description} does not convert to a valid ISO string` + `${description} is not a valid calendar` ); } diff --git a/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-optional-properties.js b/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-optional-properties.js new file mode 100644 index 0000000000..75f485bda9 --- /dev/null +++ b/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-optional-properties.js @@ -0,0 +1,38 @@ +// Copyright (C) 2025 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 property bag missing optional properties is equivalent to a property bag + with all the optional properties having their default values +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const timeZone = "UTC"; +const instance = new Temporal.ZonedDateTime(0n, timeZone); + +const minimumProperties = { + year: 2021, + month: 10, + day: 28, + timeZone, +}; +const allProperties = { + year: 2021, + month: 10, + day: 28, + hour: 0, + minute: 0, + second: 0, + millisecond: 0, + microsecond: 0, + nanosecond: 0, + offset: "+00:00", + timeZone, + calendar: "iso8601", +}; +const resultWithout = instance.until(minimumProperties); +const resultWith = instance.until(allProperties); +TemporalHelpers.assertDurationsEqual(resultWithout, resultWith, "results should be the same with and without optional properties"); diff --git a/test/built-ins/Temporal/ZonedDateTime/prototype/until/float64-representable-integer.js b/test/built-ins/Temporal/ZonedDateTime/prototype/until/float64-representable-integer.js new file mode 100644 index 0000000000..c3f3ba3dae --- /dev/null +++ b/test/built-ins/Temporal/ZonedDateTime/prototype/until/float64-representable-integer.js @@ -0,0 +1,20 @@ +// Copyright (C) 2025 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: Internal representation of Duration uses float64-representable integers +features: [Temporal] +---*/ + +const z1 = new Temporal.ZonedDateTime(0n, "UTC"); +const z2 = new Temporal.ZonedDateTime(18446744073_709_551_616n, "UTC"); +const result = z1.until(z2, { largestUnit: "microseconds" }); + +// ℝ(𝔽(18446744073709551)) = 18446744073709552 +assert.sameValue(result.microseconds, 18446744073709552, + "microseconds result should have FP precision loss"); +assert.sameValue(result.toString(), "PT18446744073.709552616S", + "Duration.p.toString() should not use more precise internal representation than the spec prescribes"); +assert.sameValue(Temporal.Duration.compare(result.add({ microseconds: 1 }), result), 0, + "subsequent ops on duration should not use more precise internal representation than the spec prescribes"); diff --git a/test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-wrong-type.js b/test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-wrong-type.js index 6a79b92f05..1149ad64e3 100644 --- a/test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-wrong-type.js +++ b/test/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-wrong-type.js @@ -4,7 +4,8 @@ /*--- esid: sec-temporal.zoneddatetime.prototype.withcalendar description: > - Appropriate error thrown when argument cannot be converted to a valid object or string + Appropriate error thrown when argument cannot be converted to a valid string + for Calendar features: [BigInt, Symbol, Temporal] ---*/ @@ -13,7 +14,7 @@ const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", " const wrongTypeTests = [ [null, "null"], [true, "boolean"], - [1, "number that doesn't convert to a valid ISO string"], + [1, "number"], [1n, "bigint"], [-19761118, "negative number"], [19761118, "large positive number"], @@ -27,6 +28,6 @@ for (const [arg, description] of wrongTypeTests) { assert.throws( TypeError, () => instance.withCalendar(arg), - `${description} does not convert to a valid ISO string` + `${description} is not a valid calendar` ); } diff --git a/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-propertybag-optional-properties.js b/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-propertybag-optional-properties.js new file mode 100644 index 0000000000..610c7cdc3a --- /dev/null +++ b/test/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-propertybag-optional-properties.js @@ -0,0 +1,27 @@ +// Copyright (C) 2025 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: > + A property bag missing optional properties is equivalent to a property bag + with all the optional properties having their default values +features: [Temporal] +---*/ + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); + +const minimumProperties = { + hour: 0, +}; +const allProperties = { + hour: 0, + minute: 0, + second: 0, + millisecond: 0, + microsecond: 0, + nanosecond: 0, +}; +const resultWithout = instance.withPlainTime(minimumProperties); +const resultWith = instance.withPlainTime(allProperties); +assert(resultWithout.equals(resultWith), "results should be the same with and without optional properties"); diff --git a/test/built-ins/ThrowTypeError/distinct-cross-realm.js b/test/built-ins/ThrowTypeError/distinct-cross-realm.js index b256601791..f356ff4383 100644 --- a/test/built-ins/ThrowTypeError/distinct-cross-realm.js +++ b/test/built-ins/ThrowTypeError/distinct-cross-realm.js @@ -17,8 +17,15 @@ var localArgs = function() { "use strict"; return arguments; }(); -var otherArgs = (new other.Function('return arguments;'))(); +var otherArgs = (new other.Function('"use strict"; return arguments;'))(); +var otherArgs2 = (new other.Function('"use strict"; return arguments;'))(); var localThrowTypeError = Object.getOwnPropertyDescriptor(localArgs, "callee").get; var otherThrowTypeError = Object.getOwnPropertyDescriptor(otherArgs, "callee").get; +var otherThrowTypeError2 = Object.getOwnPropertyDescriptor(otherArgs, "callee").get; + +assert.throws(TypeError, function() { + otherThrowTypeError(); +}); assert.notSameValue(localThrowTypeError, otherThrowTypeError); +assert.sameValue(otherThrowTypeError, otherThrowTypeError2); diff --git a/test/built-ins/Uint8Array/prototype/setFromBase64/trailing-garbage-empty.js b/test/built-ins/Uint8Array/prototype/setFromBase64/trailing-garbage-empty.js new file mode 100644 index 0000000000..6a5190f752 --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/setFromBase64/trailing-garbage-empty.js @@ -0,0 +1,48 @@ +// Copyright (C) 2025 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-uint8array.prototype.setfrombase64 +description: > + Garbage input is ignored when the typed array has a zero length +info: | + Uint8Array.prototype.setFromBase64 ( string [ , options ] ) + ... + 13. Let byteLength be TypedArrayLength(taRecord). + 14. Let result be FromBase64(string, alphabet, lastChunkHandling, byteLength). + ... + + FromBase64 ( string, alphabet, lastChunkHandling [ , maxLength ] ) + ... + 3. If maxLength = 0, then + a. Return the Record { [[Read]]: 0, [[Bytes]]: « », [[Error]]: none }. + ... + +features: [uint8array-base64, TypedArray] +---*/ + +// Zero length typed array. +var u8 = new Uint8Array(0); + +// No SyntaxError when passing invalid inputs. +for (var string of [ + "#", + "a#", + "aa#", + "aaa#", + "aaaa#", +]) { + for (var lastChunkHandling of ["loose", "strict", "stop-before-partial"]) { + var result = u8.setFromBase64(string, {lastChunkHandling}); + assert.sameValue( + result.read, + 0, + `Read for "${string}" with lastChunkHandling="${lastChunkHandling}"` + ); + assert.sameValue( + result.written, + 0, + `Write for "${string}" with lastChunkHandling="${lastChunkHandling}"` + ); + } +} diff --git a/test/built-ins/Uint8Array/prototype/setFromBase64/trailing-garbage.js b/test/built-ins/Uint8Array/prototype/setFromBase64/trailing-garbage.js new file mode 100644 index 0000000000..6321d1e830 --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/setFromBase64/trailing-garbage.js @@ -0,0 +1,83 @@ +// Copyright (C) 2025 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-uint8array.prototype.setfrombase64 +description: > + Trailing garbage is ignored when no more space is left in the output +info: | + Uint8Array.prototype.setFromBase64 ( string [ , options ] ) + ... + 13. Let byteLength be TypedArrayLength(taRecord). + 14. Let result be FromBase64(string, alphabet, lastChunkHandling, byteLength). + ... + + FromBase64 ( string, alphabet, lastChunkHandling [ , maxLength ] ) + ... + 10. Repeat, + ... + l. If chunkLength = 4, then + ... + v. If the number of elements in bytes = maxLength, then + 1. Return the Record { [[Read]]: read, [[Bytes]]: bytes, [[Error]]: none }. + +features: [uint8array-base64, TypedArray] +---*/ + +// Uint8Array large enough to hold a single decoded chunk. +var u8 = new Uint8Array(3); + +// Throws a SyntaxError for incomplete chunks. +for (var invalid of [ + "#", + "a#", + "aa#", + "aaa#", +]) { + for (var lastChunkHandling of ["loose", "strict", "stop-before-partial"]) { + assert.throws(SyntaxError, function() { + u8.setFromBase64(invalid, {lastChunkHandling}); + }, `"${invalid}" is rejected with lastChunkHandling="${lastChunkHandling}"`); + } +} + +// No SyntaxError when a full chunk can be read. +for (var valid of [ + "aaaa#", + "aaaaa#", + "aaaaaa#", + "aaaaaaa#", + "aaaaaaaa#", +]) { + for (var lastChunkHandling of ["loose", "strict", "stop-before-partial"]) { + // Reset state. + u8.fill(0); + + var result = u8.setFromBase64(valid, {lastChunkHandling}); + assert.sameValue( + result.read, + 4, + `Read for "${valid}" with lastChunkHandling="${lastChunkHandling}"` + ); + assert.sameValue( + result.written, + 3, + `Write for "${valid}" with lastChunkHandling="${lastChunkHandling}"` + ); + assert.sameValue( + u8[0], + 0x69, + `Index=0 for "${valid}" with lastChunkHandling="${lastChunkHandling}"` + ); + assert.sameValue( + u8[1], + 0xa6, + `Index=1 for "${valid}" with lastChunkHandling="${lastChunkHandling}"` + ); + assert.sameValue( + u8[2], + 0x9a, + `Index=2 for "${valid}" with lastChunkHandling="${lastChunkHandling}"` + ); + } +} diff --git a/test/harness/compare-array-falsy-arguments.js b/test/harness/compare-array-falsy-arguments.js index 1b17976401..9cbc38acd2 100644 --- a/test/harness/compare-array-falsy-arguments.js +++ b/test/harness/compare-array-falsy-arguments.js @@ -20,9 +20,9 @@ function assertThrows(func, errorMessage) { assert(caught, `Expected ${func} to throw, but it didn't.`); } -assertThrows(() => assert.compareArray(), "Actual argument shouldn't be nullish. "); -assertThrows(() => assert.compareArray(null, []), "Actual argument shouldn't be nullish. "); -assertThrows(() => assert.compareArray(null, [], "foo"), "Actual argument shouldn't be nullish. foo"); +assertThrows(() => assert.compareArray(), "Actual argument [undefined] shouldn't be primitive. "); +assertThrows(() => assert.compareArray(null, []), "Actual argument [null] shouldn't be primitive. "); +assertThrows(() => assert.compareArray(null, [], "foo"), "Actual argument [null] shouldn't be primitive. foo"); -assertThrows(() => assert.compareArray([]), "Expected argument shouldn't be nullish. "); -assertThrows(() => assert.compareArray([], undefined, "foo"), "Expected argument shouldn't be nullish. foo"); +assertThrows(() => assert.compareArray([]), "Expected argument [undefined] shouldn't be primitive. "); +assertThrows(() => assert.compareArray([], undefined, "foo"), "Expected argument [undefined] shouldn't be primitive. foo"); diff --git a/test/intl402/Intl/supportedValuesOf/calendars-required-by-intl-era-monthcode.js b/test/intl402/Intl/supportedValuesOf/calendars-required-by-intl-era-monthcode.js new file mode 100644 index 0000000000..bb9e8003a1 --- /dev/null +++ b/test/intl402/Intl/supportedValuesOf/calendars-required-by-intl-era-monthcode.js @@ -0,0 +1,51 @@ +// Copyright (C) 2025 Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.supportedvaluesof +description: > + Verifies that all calendars required by Intl.Era-monthcode are supported. See: + https://tc39.es/proposal-intl-era-monthcode/#table-calendar-types +info: | + Intl.supportedValuesOf ( key ) + 1 Let key be ? ToString(key). + 2. If key is "calendar", then + a. Let list be a new empty List. + b. For each element identifier of AvailableCalendars(), do + i. Let canonical be CanonicalizeUValue("ca", identifier). + ii. If identifier is canonical, then + 1. Append identifier to list. + ... + 9. Return CreateArrayFromList( list ). + + AvailableCalendars ( ) + The implementation-defined abstract operation AvailableCalendars takes no arguments and returns a List of calendar types. The returned List is sorted according to lexicographic code unit order, and contains unique calendar types in canonical form (6.9) identifying the calendars for which the implementation provides the functionality of Intl.DateTimeFormat objects, including their aliases (e.g., both of "islamicc" and "islamic-civil"). The List must include the Calendar Type value of every row of Table 1, except the header row. +locale: [en] +features: [Intl-enumeration, Intl.Era-monthcode] +---*/ + +const requiredCalendars = [ + "buddhist", + "chinese", + "coptic", + "dangi", + "ethioaa", + "ethiopic", + "ethiopic-amete-alem", + "gregory", + "hebrew", + "indian", + "islamic-civil", + "islamic-tbla", + "islamic-umalqura", + "islamicc", + "iso8601", + "japanese", + "persian", + "roc" +] + +const supportedCalendars = Intl.supportedValuesOf("calendar"); +for (const calendar of requiredCalendars) { + assert(supportedCalendars.includes(calendar), "Required calendar: " + calendar + " must be supported"); +} diff --git a/test/intl402/Temporal/PlainDate/from/canonicalize-era-codes-non-gregorian.js b/test/intl402/Temporal/PlainDate/from/canonicalize-era-codes-non-gregorian.js new file mode 100644 index 0000000000..7af94acef1 --- /dev/null +++ b/test/intl402/Temporal/PlainDate/from/canonicalize-era-codes-non-gregorian.js @@ -0,0 +1,26 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal-calendarsupportsera +description: Calendar era code is canonicalized (non-Gregorian calendars) +features: [Temporal, Intl.Era-monthcode] +---*/ + + +const calendarEraAliases = [ + { calendar: "japanese", canonicalizedEra: "ce", alias: "ad" }, + { calendar: "japanese", canonicalizedEra: "bce", alias: "bc" } +]; + + +for (const calendarEraAlias of calendarEraAliases) { + const calendar = Temporal.PlainDate.from({ + calendar: calendarEraAlias.calendar, + era: calendarEraAlias.alias, + eraYear: 1, + month: 1, + day: 1 + }); + assert.sameValue(calendar.era, calendarEraAlias.canonicalizedEra, calendar.era + " should canonicalize to " + calendarEraAlias.canonicalizedEra) +} diff --git a/test/intl402/Temporal/PlainDateTime/from/canonicalize-era-codes-non-gregorian.js b/test/intl402/Temporal/PlainDateTime/from/canonicalize-era-codes-non-gregorian.js new file mode 100644 index 0000000000..a397636d7a --- /dev/null +++ b/test/intl402/Temporal/PlainDateTime/from/canonicalize-era-codes-non-gregorian.js @@ -0,0 +1,26 @@ +// Copyright (C) 2025 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: Calendar era code is canonicalized (non-Gregorian calendars) +features: [Temporal, Intl.Era-monthcode] +---*/ + + +const calendarEraAliases = [ + { calendar: "japanese", canonicalizedEra: "ce", alias: "ad" }, + { calendar: "japanese", canonicalizedEra: "bce", alias: "bc" } +]; + + +for (const calendarEraAlias of calendarEraAliases) { + const calendar = Temporal.PlainDateTime.from({ + calendar: calendarEraAlias.calendar, + era: calendarEraAlias.alias, + eraYear: 1, + month: 1, + day: 1 + }); + assert.sameValue(calendar.era, calendarEraAlias.canonicalizedEra, calendar.era + " should canonicalize to " + calendarEraAlias.canonicalizedEra) +} diff --git a/test/intl402/Temporal/PlainYearMonth/from/canonicalize-era-codes-non-gregorian.js b/test/intl402/Temporal/PlainYearMonth/from/canonicalize-era-codes-non-gregorian.js new file mode 100644 index 0000000000..acc42b8803 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/from/canonicalize-era-codes-non-gregorian.js @@ -0,0 +1,26 @@ +// Copyright (C) 2025 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 era code is canonicalized (non-Gregorian calendars) +features: [Temporal, Intl.Era-monthcode] +---*/ + + +const calendarEraAliases = [ + { calendar: "japanese", canonicalizedEra: "ce", alias: "ad" }, + { calendar: "japanese", canonicalizedEra: "bce", alias: "bc" } +]; + + +for (const calendarEraAlias of calendarEraAliases) { + const calendar = Temporal.PlainYearMonth.from({ + calendar: calendarEraAlias.calendar, + era: calendarEraAlias.alias, + eraYear: 1, + month: 1, + day: 1 + }); + assert.sameValue(calendar.era, calendarEraAlias.canonicalizedEra, calendar.era + " should canonicalize to " + calendarEraAlias.canonicalizedEra) +} diff --git a/test/intl402/Temporal/ZonedDateTime/from/canonicalize-era-codes-non-gregorian.js b/test/intl402/Temporal/ZonedDateTime/from/canonicalize-era-codes-non-gregorian.js new file mode 100644 index 0000000000..61e6ae20c1 --- /dev/null +++ b/test/intl402/Temporal/ZonedDateTime/from/canonicalize-era-codes-non-gregorian.js @@ -0,0 +1,27 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zonedatetime.from +description: Calendar era code is canonicalized (non-Gregorian calendars) +features: [Temporal, Intl.Era-monthcode] +---*/ + + +const calendarEraAliases = [ + { calendar: "japanese", canonicalizedEra: "ce", alias: "ad" }, + { calendar: "japanese", canonicalizedEra: "bce", alias: "bc" } +]; + + +for (const calendarEraAlias of calendarEraAliases) { + const calendar = Temporal.ZonedDateTime.from({ + calendar: calendarEraAlias.calendar, + era: calendarEraAlias.alias, + eraYear: 1, + month: 1, + day: 1, + timeZone: "UTC" + }); + assert.sameValue(calendar.era, calendarEraAlias.canonicalizedEra, calendar.era + " should canonicalize to " + calendarEraAlias.canonicalizedEra) +} diff --git a/test/language/module-code/top-level-await/fulfillment-order.js b/test/language/module-code/top-level-await/fulfillment-order.js new file mode 100644 index 0000000000..3c29254fb3 --- /dev/null +++ b/test/language/module-code/top-level-await/fulfillment-order.js @@ -0,0 +1,55 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-async-module-execution-fulfilled +description: > + When an async module fulfills, the promises relative to itself and its ancestors are resolved in leaf-to-root order +info: | + AsyncModuleExecutionFulfilled ( module ) + ... + 7. If module.[[TopLevelCapability]] is not empty, then + a. Assert: module.[[CycleRoot]] and module are the same Module Record. + b. Perform ! Call(module.[[TopLevelCapability]].[[Resolve]], undefined, « undefined »). + 8. Let execList be a new empty List. + 9. Perform GatherAvailableAncestors(module, execList). + 10. Assert: All elements of execList have their [[AsyncEvaluationOrder]] field set to an integer, [[PendingAsyncDependencies]] field set to 0, and [[EvaluationError]] field set to empty. + 11. Let sortedExecList be a List whose elements are the elements of execList, sorted by their [[AsyncEvaluationOrder]] field in ascending order. + 12. For each Cyclic Module Record m of sortedExecList, do + a. If m.[[Status]] is evaluated, then + i. Assert: m.[[EvaluationError]] is not empty. + b. Else if m.[[HasTLA]] is true, then + i. Perform ExecuteAsyncModule(m). + c. Else, + i. Let result be m.ExecuteModule(). + ii. If result is an abrupt completion, then + 1. Perform AsyncModuleExecutionRejected(m, result.[[Value]]). + iii. Else, + 1. Set m.[[AsyncEvaluationOrder]] to done. + 2. Set m.[[Status]] to evaluated. + 3. If m.[[TopLevelCapability]] is not empty, then + a. Assert: m.[[CycleRoot]] and m are the same Module Record. + b. Perform ! Call(m.[[TopLevelCapability]].[[Resolve]], undefined, « undefined »). +flags: [module, async] +features: [top-level-await, promise-with-resolvers] +includes: [compareArray.js] +---*/ + +import { p1, pA_start, pB_start } from "./fulfillment-order_setup_FIXTURE.js"; + +let logs = []; + +const importsP = Promise.all([ + // Ensure that a.Evaluate() is called after b.Evaluate() + pB_start.promise.then(() => import("./fulfillment-order_a_FIXTURE.js").finally(() => logs.push("A"))).catch(() => {}), + import("./fulfillment-order_b_FIXTURE.js").finally(() => logs.push("B")).catch(() => {}), +]); + +// Wait for evaluation of both graphs with entry points in A and B to start before +// settling the promise that B is blocked on. +Promise.all([pA_start.promise, pB_start.promise]).then(p1.resolve); + +importsP.then(() => { + assert.compareArray(logs, ["B", "A"]); + + $DONE(); +}); diff --git a/test/language/module-code/top-level-await/fulfillment-order_a-sentinel_FIXTURE.js b/test/language/module-code/top-level-await/fulfillment-order_a-sentinel_FIXTURE.js new file mode 100644 index 0000000000..194bba0af7 --- /dev/null +++ b/test/language/module-code/top-level-await/fulfillment-order_a-sentinel_FIXTURE.js @@ -0,0 +1,5 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +import { pA_start } from "./fulfillment-order_setup_FIXTURE.js"; +pA_start.resolve(); diff --git a/test/language/module-code/top-level-await/fulfillment-order_a_FIXTURE.js b/test/language/module-code/top-level-await/fulfillment-order_a_FIXTURE.js new file mode 100644 index 0000000000..2dcb80bcd2 --- /dev/null +++ b/test/language/module-code/top-level-await/fulfillment-order_a_FIXTURE.js @@ -0,0 +1,5 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +import "./fulfillment-order_a-sentinel_FIXTURE.js"; // Signal that evaluation of a's subgraph has started +import "./fulfillment-order_b_FIXTURE.js"; diff --git a/test/language/module-code/top-level-await/fulfillment-order_b-sentinel_FIXTURE.js b/test/language/module-code/top-level-await/fulfillment-order_b-sentinel_FIXTURE.js new file mode 100644 index 0000000000..57cdd523ee --- /dev/null +++ b/test/language/module-code/top-level-await/fulfillment-order_b-sentinel_FIXTURE.js @@ -0,0 +1,5 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +import { pB_start } from "./fulfillment-order_setup_FIXTURE.js"; +pB_start.resolve(); diff --git a/test/language/module-code/top-level-await/fulfillment-order_b_FIXTURE.js b/test/language/module-code/top-level-await/fulfillment-order_b_FIXTURE.js new file mode 100644 index 0000000000..caee0ea134 --- /dev/null +++ b/test/language/module-code/top-level-await/fulfillment-order_b_FIXTURE.js @@ -0,0 +1,7 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +import "./fulfillment-order_b-sentinel_FIXTURE.js"; // Signal that evaluation of b's subgraph has started + +import { p1 } from "./fulfillment-order_setup_FIXTURE.js"; +await p1.promise; diff --git a/test/language/module-code/top-level-await/fulfillment-order_setup_FIXTURE.js b/test/language/module-code/top-level-await/fulfillment-order_setup_FIXTURE.js new file mode 100644 index 0000000000..a1c11d8cc9 --- /dev/null +++ b/test/language/module-code/top-level-await/fulfillment-order_setup_FIXTURE.js @@ -0,0 +1,6 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +export const p1 = Promise.withResolvers(); +export const pA_start = Promise.withResolvers(); +export const pB_start = Promise.withResolvers(); diff --git a/test/language/module-code/top-level-await/pending-async-dep-from-cycle.js b/test/language/module-code/top-level-await/pending-async-dep-from-cycle.js new file mode 100644 index 0000000000..d8438bb3cc --- /dev/null +++ b/test/language/module-code/top-level-await/pending-async-dep-from-cycle.js @@ -0,0 +1,70 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-innermoduleevaluation +description: > + A module depending on an async module of a separate cycle should wait for the cycle root to complete +info: | + Module graph: + + ┌──────────────────┐ + │ entrypoint │ + └──────────────────┘ + │ │ + ▼ ▼ + ┌──────────────────┐ ┌────────────────────────┐ + │ cycle root (TLA) │ │ importer of cycle leaf │ + └──────────────────┘ └────────────────────────┘ + │ ▲ │ + ▼ │ │ + ┌──────────────────┐ │ + │ cycle leaf (TLA) │ ◄──────┘ + └──────────────────┘ + + This test exercises step 11.c.iv.1 of the following algorithm when _module_ is + "importer of cycle leaf", _requiredModule_ is "cycle leaf (TLA)", and + _requiredModule_.[[CycleRoot]] is "cycle root (TLA)". + The [[Status]] of "cycle leaf (TLA)" and of "cycle root (TLA)" is ~evaluating-async~, + because they have already been traversed and they are blocked on the TLA in "cycle leaf (TLA)". + Thus, their [[AsyncEvaluationOrder]] is an integer, so the _requiredModule_ variable is used + to determine what module "importer of cycle leaf" should wait for. + + InnerModuleEvaluation ( module, stack, index ) + ... + 11. For each ModuleRequest Record request of module.[[RequestedModules]], do + a. Let requiredModule be GetImportedModule(module, request). + b. Set index to ? InnerModuleEvaluation(requiredModule, stack, index). + c. If requiredModule is a Cyclic Module Record, then + i. Assert: requiredModule.[[Status]] is one of evaluating, evaluating-async, or evaluated. + ii. Assert: requiredModule.[[Status]] is evaluating if and only if stack contains requiredModule. + iii. If requiredModule.[[Status]] is evaluating, then + 1. Set module.[[DFSAncestorIndex]] to min(module.[[DFSAncestorIndex]], requiredModule.[[DFSAncestorIndex]]). + iv. Else, + 1. Set requiredModule to requiredModule.[[CycleRoot]]. + 2. Assert: requiredModule.[[Status]] is either evaluating-async or evaluated. + 3. If requiredModule.[[EvaluationError]] is not empty, return ? requiredModule.[[EvaluationError]]. + v. If requiredModule.[[AsyncEvaluationOrder]] is an integer, then + 1. Set module.[[PendingAsyncDependencies]] to module.[[PendingAsyncDependencies]] + 1. + 2. Append module to requiredModule.[[AsyncParentModules]]. + +flags: [module, async] +features: [top-level-await] +includes: [compareArray.js] +---*/ + +import "./pending-async-dep-from-cycle_setup_FIXTURE.js"; +import "./pending-async-dep-from-cycle_cycle-root_FIXTURE.js"; +import "./pending-async-dep-from-cycle_import-cycle-leaf_FIXTURE.js"; + +assert.compareArray(globalThis.logs, [ + "cycle leaf start", + "cycle leaf end", + "cycle root start", + // Without the step covered by this test, + // these last two entries would be swapped. + "cycle root end", + "importer of cycle leaf" +]); + +$DONE(); diff --git a/test/language/module-code/top-level-await/pending-async-dep-from-cycle_cycle-leaf_FIXTURE.js b/test/language/module-code/top-level-await/pending-async-dep-from-cycle_cycle-leaf_FIXTURE.js new file mode 100644 index 0000000000..abe8adc6c9 --- /dev/null +++ b/test/language/module-code/top-level-await/pending-async-dep-from-cycle_cycle-leaf_FIXTURE.js @@ -0,0 +1,8 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +import "./pending-async-dep-from-cycle_cycle-root_FIXTURE.js"; + +globalThis.logs.push("cycle leaf start"); +await 1; +globalThis.logs.push("cycle leaf end"); diff --git a/test/language/module-code/top-level-await/pending-async-dep-from-cycle_cycle-root_FIXTURE.js b/test/language/module-code/top-level-await/pending-async-dep-from-cycle_cycle-root_FIXTURE.js new file mode 100644 index 0000000000..618217c653 --- /dev/null +++ b/test/language/module-code/top-level-await/pending-async-dep-from-cycle_cycle-root_FIXTURE.js @@ -0,0 +1,8 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +import "./pending-async-dep-from-cycle_cycle-leaf_FIXTURE.js"; + +globalThis.logs.push("cycle root start"); +await 1; +globalThis.logs.push("cycle root end"); diff --git a/test/language/module-code/top-level-await/pending-async-dep-from-cycle_import-cycle-leaf_FIXTURE.js b/test/language/module-code/top-level-await/pending-async-dep-from-cycle_import-cycle-leaf_FIXTURE.js new file mode 100644 index 0000000000..1e102a9de8 --- /dev/null +++ b/test/language/module-code/top-level-await/pending-async-dep-from-cycle_import-cycle-leaf_FIXTURE.js @@ -0,0 +1,6 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +import "./pending-async-dep-from-cycle_cycle-leaf_FIXTURE.js"; + +globalThis.logs.push("importer of cycle leaf"); diff --git a/test/language/module-code/top-level-await/pending-async-dep-from-cycle_setup_FIXTURE.js b/test/language/module-code/top-level-await/pending-async-dep-from-cycle_setup_FIXTURE.js new file mode 100644 index 0000000000..5a4508019b --- /dev/null +++ b/test/language/module-code/top-level-await/pending-async-dep-from-cycle_setup_FIXTURE.js @@ -0,0 +1,4 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +globalThis.logs = []; diff --git a/test/language/module-code/top-level-await/rejection-order.js b/test/language/module-code/top-level-await/rejection-order.js new file mode 100644 index 0000000000..6bf131537c --- /dev/null +++ b/test/language/module-code/top-level-await/rejection-order.js @@ -0,0 +1,38 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-async-module-execution-rejected +description: > + When an async module rejects, the promises relative to itself and its ancestors are resolved in leaf-to-root order +info: | + AsyncModuleExecutionRejected ( module, error ) + ... + 9. If module.[[TopLevelCapability]] is not empty, then + a. Assert: module.[[CycleRoot]] and module are the same Module Record. + b. Perform ! Call(module.[[TopLevelCapability]].[[Reject]], undefined, « error »). + 10. For each Cyclic Module Record m of module.[[AsyncParentModules]], do + a. Perform AsyncModuleExecutionRejected(m, error). +flags: [module, async] +features: [top-level-await, promise-with-resolvers] +includes: [compareArray.js] +---*/ + +import { p1, pA_start, pB_start } from "./rejection-order_setup_FIXTURE.js"; + +let logs = []; + +const importsP = Promise.all([ + // Ensure that a.Evaluate() is called after b.Evaluate() + pB_start.promise.then(() => import("./rejection-order_a_FIXTURE.js").finally(() => logs.push("A"))).catch(() => {}), + import("./rejection-order_b_FIXTURE.js").finally(() => logs.push("B")).catch(() => {}), +]); + +// Wait for evaluation of both graphs with entry points in A and B to start before +// rejecting the promise that B is blocked on. +Promise.all([pA_start.promise, pB_start.promise]).then(p1.reject); + +importsP.then(() => { + assert.compareArray(logs, ["B", "A"]); + + $DONE(); +}); diff --git a/test/language/module-code/top-level-await/rejection-order_a-sentinel_FIXTURE.js b/test/language/module-code/top-level-await/rejection-order_a-sentinel_FIXTURE.js new file mode 100644 index 0000000000..d63be707ad --- /dev/null +++ b/test/language/module-code/top-level-await/rejection-order_a-sentinel_FIXTURE.js @@ -0,0 +1,5 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +import { pA_start } from "./rejection-order_setup_FIXTURE.js"; +pA_start.resolve(); diff --git a/test/language/module-code/top-level-await/rejection-order_a_FIXTURE.js b/test/language/module-code/top-level-await/rejection-order_a_FIXTURE.js new file mode 100644 index 0000000000..344439e9ba --- /dev/null +++ b/test/language/module-code/top-level-await/rejection-order_a_FIXTURE.js @@ -0,0 +1,5 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +import "./rejection-order_a-sentinel_FIXTURE.js"; // Signal that evaluation of a's subgraph has started +import "./rejection-order_b_FIXTURE.js"; diff --git a/test/language/module-code/top-level-await/rejection-order_b-sentinel_FIXTURE.js b/test/language/module-code/top-level-await/rejection-order_b-sentinel_FIXTURE.js new file mode 100644 index 0000000000..4db95eb3c3 --- /dev/null +++ b/test/language/module-code/top-level-await/rejection-order_b-sentinel_FIXTURE.js @@ -0,0 +1,5 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +import { pB_start } from "./rejection-order_setup_FIXTURE.js"; +pB_start.resolve(); diff --git a/test/language/module-code/top-level-await/rejection-order_b_FIXTURE.js b/test/language/module-code/top-level-await/rejection-order_b_FIXTURE.js new file mode 100644 index 0000000000..6daf762bad --- /dev/null +++ b/test/language/module-code/top-level-await/rejection-order_b_FIXTURE.js @@ -0,0 +1,7 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +import "./rejection-order_b-sentinel_FIXTURE.js"; // Signal that evaluation of b's subgraph has started + +import { p1 } from "./rejection-order_setup_FIXTURE.js"; +await p1.promise; diff --git a/test/language/module-code/top-level-await/rejection-order_setup_FIXTURE.js b/test/language/module-code/top-level-await/rejection-order_setup_FIXTURE.js new file mode 100644 index 0000000000..a1c11d8cc9 --- /dev/null +++ b/test/language/module-code/top-level-await/rejection-order_setup_FIXTURE.js @@ -0,0 +1,6 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +export const p1 = Promise.withResolvers(); +export const pA_start = Promise.withResolvers(); +export const pB_start = Promise.withResolvers(); diff --git a/test/language/module-code/top-level-await/unobservable-global-async-evaluation-count-reset-a_FIXTURE.js b/test/language/module-code/top-level-await/unobservable-global-async-evaluation-count-reset-a_FIXTURE.js new file mode 100644 index 0000000000..cfd99c55ac --- /dev/null +++ b/test/language/module-code/top-level-await/unobservable-global-async-evaluation-count-reset-a_FIXTURE.js @@ -0,0 +1,6 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +import { logs } from "./unobservable-global-async-evaluation-count-reset-setup_FIXTURE.js"; +import "./unobservable-global-async-evaluation-count-reset-b_FIXTURE.js"; +logs.push("A"); diff --git a/test/language/module-code/top-level-await/unobservable-global-async-evaluation-count-reset-b_FIXTURE.js b/test/language/module-code/top-level-await/unobservable-global-async-evaluation-count-reset-b_FIXTURE.js new file mode 100644 index 0000000000..0d02d28631 --- /dev/null +++ b/test/language/module-code/top-level-await/unobservable-global-async-evaluation-count-reset-b_FIXTURE.js @@ -0,0 +1,6 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +import { pB, pB_start } from "./unobservable-global-async-evaluation-count-reset-setup_FIXTURE.js"; +pB_start.resolve(); +await pB.promise; diff --git a/test/language/module-code/top-level-await/unobservable-global-async-evaluation-count-reset-c_FIXTURE.js b/test/language/module-code/top-level-await/unobservable-global-async-evaluation-count-reset-c_FIXTURE.js new file mode 100644 index 0000000000..e15f94d8ad --- /dev/null +++ b/test/language/module-code/top-level-await/unobservable-global-async-evaluation-count-reset-c_FIXTURE.js @@ -0,0 +1,4 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +await 1; diff --git a/test/language/module-code/top-level-await/unobservable-global-async-evaluation-count-reset-d_FIXTURE.js b/test/language/module-code/top-level-await/unobservable-global-async-evaluation-count-reset-d_FIXTURE.js new file mode 100644 index 0000000000..cffc326f0a --- /dev/null +++ b/test/language/module-code/top-level-await/unobservable-global-async-evaluation-count-reset-d_FIXTURE.js @@ -0,0 +1,7 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +import { logs } from "./unobservable-global-async-evaluation-count-reset-setup_FIXTURE.js"; +import "./unobservable-global-async-evaluation-count-reset-e_FIXTURE.js"; +import "./unobservable-global-async-evaluation-count-reset-b_FIXTURE.js"; +logs.push("D"); diff --git a/test/language/module-code/top-level-await/unobservable-global-async-evaluation-count-reset-e_FIXTURE.js b/test/language/module-code/top-level-await/unobservable-global-async-evaluation-count-reset-e_FIXTURE.js new file mode 100644 index 0000000000..62dc105b29 --- /dev/null +++ b/test/language/module-code/top-level-await/unobservable-global-async-evaluation-count-reset-e_FIXTURE.js @@ -0,0 +1,5 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +import { pE_start } from "./unobservable-global-async-evaluation-count-reset-setup_FIXTURE.js"; +pE_start.resolve(); diff --git a/test/language/module-code/top-level-await/unobservable-global-async-evaluation-count-reset-setup_FIXTURE.js b/test/language/module-code/top-level-await/unobservable-global-async-evaluation-count-reset-setup_FIXTURE.js new file mode 100644 index 0000000000..2d4606e82d --- /dev/null +++ b/test/language/module-code/top-level-await/unobservable-global-async-evaluation-count-reset-setup_FIXTURE.js @@ -0,0 +1,7 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +export const logs = []; +export const pB = Promise.withResolvers(); +export const pB_start = Promise.withResolvers(); +export const pE_start = Promise.withResolvers(); diff --git a/test/language/module-code/top-level-await/unobservable-global-async-evaluation-count-reset.js b/test/language/module-code/top-level-await/unobservable-global-async-evaluation-count-reset.js new file mode 100644 index 0000000000..8dadfedf2b --- /dev/null +++ b/test/language/module-code/top-level-await/unobservable-global-async-evaluation-count-reset.js @@ -0,0 +1,82 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + An implementation may unobservably reset [[ModuleAsyncEvaluationCount]] to 0 + whenever there are no pending modules. +info: | + IncrementModuleAsyncEvaluationCount ( ) + 1. Let AR be the Agent Record of the surrounding agent. + 2. Let count be AR.[[ModuleAsyncEvaluationCount]]. + 3. Set AR.[[ModuleAsyncEvaluationCount]] to count + 1. + 4. Return count. + + NOTE: This value is only used to keep track of the relative evaluation order + between pending modules. An implementation may unobservably reset + [[ModuleAsyncEvaluationCount]] to 0 whenever there are no pending modules. + + InnerModuleEvaluation ( module, stack, index ) + ... + 12. If module.[[PendingAsyncDependencies]] > 0 or module.[[HasTLA]] is true, then + a. Assert: module.[[AsyncEvaluationOrder]] is unset. + b. Set module.[[AsyncEvaluationOrder]] to IncrementModuleAsyncEvaluationCount(). + ... + + AsyncModuleExecutionFulfilled ( module ) + ... + 9. Perform GatherAvailableAncestors(module, execList). + 10. ... + 11. Let sortedExecList be a List whose elements are the elements of execList, sorted by their [[AsyncEvaluationOrder]] field in ascending order. + 12. For each Cyclic Module Record m of sortedExecList, do + a. If m.[[Status]] is evaluated, then + i. Assert: m.[[EvaluationError]] is not empty. + b. Else if m.[[HasTLA]] is true, then + i. Perform ExecuteAsyncModule(m). + c. Else, + i. Let result be m.ExecuteModule(). + ... + + Module graph (the order of dependencies in each module is important, and it's left-to-right): + ┌─────┐ ┌─────┐ ┌─────┐ + │ A │ │ C │ │ D │ + └─────┘ └─────┘ └─────┘ + │ │ │ + │ ▼ │ + │ ┌─────┐ │ + │ │ E │ │ + │ └─────┘ │ + │ ┌──────────────────┘ + ▼ ▼ + ┌───────┐ + │ B │ + └───────┘ + + Where B and C have top-level await. The test orchestrates the evaluation order such that: + - Import A first + - Once B starts evaluating, import C and immediately resolve its top-level await + - Once C finishes evaluating, import D + - Once E is evaluated, resolve B's await + +esid: sec-IncrementModuleAsyncEvaluationCount +flags: [module, async] +features: [top-level-await, dynamic-import, promise-with-resolvers] +includes: [compareArray.js] +---*/ + +import { logs, pB, pB_start, pE_start } from "./unobservable-global-async-evaluation-count-reset-setup_FIXTURE.js"; + +const pA = import("./unobservable-global-async-evaluation-count-reset-a_FIXTURE.js"); +let pD; + +pB_start.promise.then(() => { + return import("./unobservable-global-async-evaluation-count-reset-c_FIXTURE.js"); +}).then(() => { + pD = import("./unobservable-global-async-evaluation-count-reset-d_FIXTURE.js"); + return pE_start.promise; +}).then(() => { + pB.resolve(); + return Promise.all([pA, pD]); +}).then(() => { + assert.compareArray(logs, ["A", "D"], "A should evaluate before D"); +}).then($DONE, $DONE); diff --git a/test/language/statements/class/elements/private-class-field-on-nonextensible-objects.js b/test/language/statements/class/elements/private-class-field-on-nonextensible-objects.js index ada3868916..a87c9cd634 100644 --- a/test/language/statements/class/elements/private-class-field-on-nonextensible-objects.js +++ b/test/language/statements/class/elements/private-class-field-on-nonextensible-objects.js @@ -92,7 +92,7 @@ class ClassWithPrivateAccessor extends NonExtensibleBase { const a = new ClassWithPrivateAccessor(false); // extensible objects can be extended -assert.sameValue(m.publicAccessor, 42); +assert.sameValue(a.publicAccessor, 42); // where superclass prevented extensions & subclass extended assert.throws(TypeError, function () { diff --git a/test/language/statements/class/subclass/private-class-field-on-nonextensible-return-override.js b/test/language/statements/class/subclass/private-class-field-on-nonextensible-return-override.js index d8e7034a7d..de0623bb62 100644 --- a/test/language/statements/class/subclass/private-class-field-on-nonextensible-return-override.js +++ b/test/language/statements/class/subclass/private-class-field-on-nonextensible-return-override.js @@ -35,14 +35,14 @@ class ClassWithPrivateField extends TrojanBase { super(obj); this.#val = 42; } - val() { - return this.#val; + static val(obj) { + return obj.#val; } } const t = new ClassWithPrivateField({}); // extensible objects can be extended -assert.sameValue(t.val(), 42); +assert.sameValue(ClassWithPrivateField.val(t), 42); // where superclass prevented extensions & subclass extended assert.throws(TypeError, function () { @@ -59,15 +59,14 @@ class ClassWithPrivateMethod extends TrojanBase { #privateMethod() { return 42; }; - // public methods are on the prototype, so are ok. - publicMethod() { - return this.#privateMethod(); + static val(obj) { + return obj.#privateMethod(); } } const m = new ClassWithPrivateMethod({}); // extensible objects can be extended -assert.sameValue(m.publicMethod(), 42); +assert.sameValue(ClassWithPrivateMethod.val(m), 42); // where superclass prevented extensions & subclass extended assert.throws(TypeError, function () { @@ -84,15 +83,14 @@ class ClassWithPrivateAccessor extends TrojanBase { get #privateAccessor() { return 42; }; - // public accessors are on the prototype, so are ok. - get publicAccessor() { - return this.#privateAccessor; + static val(obj) { + return obj.#privateAccessor; } } const a = new ClassWithPrivateAccessor({}); // extensible objects can be extended -assert.sameValue(m.publicAccessor, 42); +assert.sameValue(ClassWithPrivateAccessor.val(a), 42); // where superclass prevented extensions & subclass extended assert.throws(TypeError, function () { diff --git a/test/staging/Temporal/v8/calendar-date-add.js b/test/staging/Temporal/v8/calendar-date-add.js new file mode 100644 index 0000000000..7298da0f5d --- /dev/null +++ b/test/staging/Temporal/v8/calendar-date-add.js @@ -0,0 +1,87 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from calendar-date-add test + in V8's mjsunit test calendar-date-add.js +features: [Temporal] +---*/ + +let p1y = new Temporal.Duration(1); +let p4y = new Temporal.Duration(4); +let p5m = new Temporal.Duration(0, 5); +let p1y2m = new Temporal.Duration(1, 2); +let p1y4d = new Temporal.Duration(1, 0, 0, 4); +let p1y2m4d = new Temporal.Duration(1, 2, 0, 4); +let p10d = new Temporal.Duration(0, 0, 0, 10); +let p1w = new Temporal.Duration(0, 0, 1); +let p6w = new Temporal.Duration(0, 0, 6); +let p2w3d = new Temporal.Duration(0, 0, 2, 3); +let p1y2w = new Temporal.Duration(1, 0, 2); +let p2m3w = new Temporal.Duration(0, 2, 3); +assert.sameValue(Temporal.PlainDate.from('2020-02-29').add(p1y).toJSON(), '2021-02-28'); +assert.sameValue(Temporal.PlainDate.from('2020-02-29').add(p4y).toJSON(), '2024-02-29'); +assert.sameValue(Temporal.PlainDate.from('2021-07-16').add(p1y).toJSON(), '2022-07-16'); +assert.sameValue(Temporal.PlainDate.from('2021-07-16').add(p5m).toJSON(), '2021-12-16'); +assert.sameValue(Temporal.PlainDate.from('2021-08-16').add(p5m).toJSON(), '2022-01-16'); +assert.sameValue(Temporal.PlainDate.from('2021-10-31').add(p5m).toJSON(), '2022-03-31'); +assert.sameValue(Temporal.PlainDate.from('2021-09-30').add(p5m).toJSON(), '2022-02-28'); +assert.sameValue(Temporal.PlainDate.from('2019-09-30').add(p5m).toJSON(), '2020-02-29'); +assert.sameValue(Temporal.PlainDate.from('2019-10-01').add(p5m).toJSON(), '2020-03-01'); +assert.sameValue(Temporal.PlainDate.from('2021-07-16').add(p1y2m).toJSON(), '2022-09-16'); +assert.sameValue(Temporal.PlainDate.from('2021-11-30').add(p1y2m).toJSON(), '2023-01-30'); +assert.sameValue(Temporal.PlainDate.from('2021-12-31').add(p1y2m).toJSON(), '2023-02-28'); +assert.sameValue(Temporal.PlainDate.from('2022-12-31').add(p1y2m).toJSON(), '2024-02-29'); +assert.sameValue(Temporal.PlainDate.from('2021-07-16').add(p1y4d).toJSON(), '2022-07-20'); +assert.sameValue(Temporal.PlainDate.from('2021-02-27').add(p1y4d).toJSON(), '2022-03-03'); +assert.sameValue(Temporal.PlainDate.from('2023-02-27').add(p1y4d).toJSON(), '2024-03-02'); +assert.sameValue(Temporal.PlainDate.from('2021-12-30').add(p1y4d).toJSON(), '2023-01-03'); +assert.sameValue(Temporal.PlainDate.from('2021-07-30').add(p1y4d).toJSON(), '2022-08-03'); +assert.sameValue(Temporal.PlainDate.from('2021-06-30').add(p1y4d).toJSON(), '2022-07-04'); +assert.sameValue(Temporal.PlainDate.from('2021-07-16').add(p1y2m4d).toJSON(), '2022-09-20'); +assert.sameValue(Temporal.PlainDate.from('2021-02-27').add(p1y2m4d).toJSON(), '2022-05-01'); +assert.sameValue(Temporal.PlainDate.from('2021-02-26').add(p1y2m4d).toJSON(), '2022-04-30'); +assert.sameValue(Temporal.PlainDate.from('2023-02-26').add(p1y2m4d).toJSON(), '2024-04-30'); +assert.sameValue(Temporal.PlainDate.from('2021-12-30').add(p1y2m4d).toJSON(), '2023-03-04'); +assert.sameValue(Temporal.PlainDate.from('2021-07-30').add(p1y2m4d).toJSON(), '2022-10-04'); +assert.sameValue(Temporal.PlainDate.from('2021-06-30').add(p1y2m4d).toJSON(), '2022-09-03'); +assert.sameValue(Temporal.PlainDate.from('2021-07-16').add(p10d).toJSON(), '2021-07-26'); +assert.sameValue(Temporal.PlainDate.from('2021-07-26').add(p10d).toJSON(), '2021-08-05'); +assert.sameValue(Temporal.PlainDate.from('2021-12-26').add(p10d).toJSON(), '2022-01-05'); +assert.sameValue(Temporal.PlainDate.from('2020-02-26').add(p10d).toJSON(), '2020-03-07'); +assert.sameValue(Temporal.PlainDate.from('2021-02-26').add(p10d).toJSON(), '2021-03-08'); +assert.sameValue(Temporal.PlainDate.from('2020-02-19').add(p10d).toJSON(), '2020-02-29'); +assert.sameValue(Temporal.PlainDate.from('2021-02-19').add(p10d).toJSON(), '2021-03-01'); +assert.sameValue(Temporal.PlainDate.from('2021-02-19').add(p1w).toJSON(), '2021-02-26'); +assert.sameValue(Temporal.PlainDate.from('2021-02-27').add(p1w).toJSON(), '2021-03-06'); +assert.sameValue(Temporal.PlainDate.from('2020-02-27').add(p1w).toJSON(), '2020-03-05'); +assert.sameValue(Temporal.PlainDate.from('2021-12-24').add(p1w).toJSON(), '2021-12-31'); +assert.sameValue(Temporal.PlainDate.from('2021-12-27').add(p1w).toJSON(), '2022-01-03'); +assert.sameValue(Temporal.PlainDate.from('2021-01-27').add(p1w).toJSON(), '2021-02-03'); +assert.sameValue(Temporal.PlainDate.from('2021-06-27').add(p1w).toJSON(), '2021-07-04'); +assert.sameValue(Temporal.PlainDate.from('2021-07-27').add(p1w).toJSON(), '2021-08-03'); +assert.sameValue(Temporal.PlainDate.from('2021-02-19').add(p6w).toJSON(), '2021-04-02'); +assert.sameValue(Temporal.PlainDate.from('2021-02-27').add(p6w).toJSON(), '2021-04-10'); +assert.sameValue(Temporal.PlainDate.from('2020-02-27').add(p6w).toJSON(), '2020-04-09'); +assert.sameValue(Temporal.PlainDate.from('2021-12-24').add(p6w).toJSON(), '2022-02-04'); +assert.sameValue(Temporal.PlainDate.from('2021-12-27').add(p6w).toJSON(), '2022-02-07'); +assert.sameValue(Temporal.PlainDate.from('2021-01-27').add(p6w).toJSON(), '2021-03-10'); +assert.sameValue(Temporal.PlainDate.from('2021-06-27').add(p6w).toJSON(), '2021-08-08'); +assert.sameValue(Temporal.PlainDate.from('2021-07-27').add(p6w).toJSON(), '2021-09-07'); +assert.sameValue(Temporal.PlainDate.from('2020-02-29').add(p2w3d).toJSON(), '2020-03-17'); +assert.sameValue(Temporal.PlainDate.from('2020-02-28').add(p2w3d).toJSON(), '2020-03-16'); +assert.sameValue(Temporal.PlainDate.from('2021-02-28').add(p2w3d).toJSON(), '2021-03-17'); +assert.sameValue(Temporal.PlainDate.from('2020-12-28').add(p2w3d).toJSON(), '2021-01-14'); +assert.sameValue(Temporal.PlainDate.from('2020-02-29').add(p1y2w).toJSON(), '2021-03-14'); +assert.sameValue(Temporal.PlainDate.from('2020-02-28').add(p1y2w).toJSON(), '2021-03-14'); +assert.sameValue(Temporal.PlainDate.from('2021-02-28').add(p1y2w).toJSON(), '2022-03-14'); +assert.sameValue(Temporal.PlainDate.from('2020-12-28').add(p1y2w).toJSON(), '2022-01-11'); +assert.sameValue(Temporal.PlainDate.from('2020-02-29').add(p2m3w).toJSON(), '2020-05-20'); +assert.sameValue(Temporal.PlainDate.from('2020-02-28').add(p2m3w).toJSON(), '2020-05-19'); +assert.sameValue(Temporal.PlainDate.from('2021-02-28').add(p2m3w).toJSON(), '2021-05-19'); +assert.sameValue(Temporal.PlainDate.from('2020-12-28').add(p2m3w).toJSON(), '2021-03-21'); +assert.sameValue(Temporal.PlainDate.from('2019-12-28').add(p2m3w).toJSON(), '2020-03-20'); +assert.sameValue(Temporal.PlainDate.from('2019-10-28').add(p2m3w).toJSON(), '2020-01-18'); +assert.sameValue(Temporal.PlainDate.from('2019-10-31').add(p2m3w).toJSON(), '2020-01-21'); diff --git a/test/staging/Temporal/v8/calendar-date-from-fields.js b/test/staging/Temporal/v8/calendar-date-from-fields.js new file mode 100644 index 0000000000..e3af434aa3 --- /dev/null +++ b/test/staging/Temporal/v8/calendar-date-from-fields.js @@ -0,0 +1,425 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from calendar-date-from-fields test + in V8's mjsunit test calendar-date-from-fields.js +features: [Temporal] +---*/ + +assert.throws(TypeError, () => Temporal.PlainDate.from()); +[ + undefined, + true, + false, + 123, + 456n, + Symbol(), + 123.456, + NaN, + null +].forEach(function (fields) { + assert.throws(TypeError, () => Temporal.PlainDate.from(fields)); + assert.throws(TypeError, () => Temporal.PlainDate.from(fields, undefined)); + assert.throws(TypeError, () => Temporal.PlainDate.from(fields, { overflow: 'constrain' })); + assert.throws(TypeError, () => Temporal.PlainDate.from(fields, { overflow: 'reject' })); +}); +assert.throws(RangeError, () => Temporal.PlainDate.from('string')); +assert.throws(RangeError, () => Temporal.PlainDate.from('string', undefined)); +assert.throws(RangeError, () => Temporal.PlainDate.from('string', { overflow: 'constrain' })); +assert.throws(RangeError, () => Temporal.PlainDate.from('string', { overflow: 'reject' })); +assert.throws(TypeError, () => Temporal.PlainDate.from({ + month: 1, + day: 17 +})); +assert.throws(TypeError, () => Temporal.PlainDate.from({ + year: 2021, + day: 17 +})); +assert.throws(TypeError, () => Temporal.PlainDate.from({ + year: 2021, + month: 12 +})); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + monthCode: 'm1', + day: 17 +})); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + monthCode: 'M1', + day: 17 +})); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + monthCode: 'm01', + day: 17 +})); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + month: 12, + monthCode: 'M11', + day: 17 +})); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + monthCode: 'M00', + day: 17 +})); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + monthCode: 'M19', + day: 17 +})); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + monthCode: 'M99', + day: 17 +})); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + monthCode: 'M13', + day: 17 +})); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + month: -1, + day: 17 +})); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + month: -Infinity, + day: 17 +})); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + month: 7, + day: -17 +})); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + month: 7, + day: -Infinity +})); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + month: 12, + day: 0 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + month: 12, + day: 32 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + month: 1, + day: 32 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + month: 2, + day: 29 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + month: 6, + day: 31 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + month: 9, + day: 31 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + month: 0, + day: 5 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + month: 13, + day: 5 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + monthCode: 'M12', + day: 0 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + monthCode: 'M12', + day: 32 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + monthCode: 'M01', + day: 32 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + monthCode: 'M02', + day: 29 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + monthCode: 'M06', + day: 31 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + monthCode: 'M09', + day: 31 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + monthCode: 'M00', + day: 5 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + monthCode: 'M13', + day: 5 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + month: 12, + day: 0 +})); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + month: 0, + day: 3 +})); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + month: 7, + day: 13 +}, { overflow: 'invalid' })); +assert.sameValue(Temporal.PlainDate.from({ + year: 2021, + month: 7, + day: 15 +}).toJSON(), '2021-07-15'); +assert.sameValue(Temporal.PlainDate.from({ + year: 2021, + month: 7, + day: 3 +}).toJSON(), '2021-07-03'); +assert.sameValue(Temporal.PlainDate.from({ + year: 2021, + month: 12, + day: 31 +}).toJSON(), '2021-12-31'); +assert.sameValue(Temporal.PlainDate.from({ + year: 2021, + monthCode: 'M07', + day: 15 +}).toJSON(), '2021-07-15'); +assert.sameValue(Temporal.PlainDate.from({ + year: 2021, + monthCode: 'M07', + day: 3 +}).toJSON(), '2021-07-03'); +assert.sameValue(Temporal.PlainDate.from({ + year: 2021, + monthCode: 'M12', + day: 31 +}).toJSON(), '2021-12-31'); +assert.sameValue(Temporal.PlainDate.from({ + year: 2021, + month: 1, + day: 133 +}).toJSON(), '2021-01-31'); +assert.sameValue(Temporal.PlainDate.from({ + year: 2021, + month: 2, + day: 133 +}).toJSON(), '2021-02-28'); +assert.sameValue(Temporal.PlainDate.from({ + year: 2021, + month: 3, + day: 9033 +}).toJSON(), '2021-03-31'); +assert.sameValue(Temporal.PlainDate.from({ + year: 2021, + month: 4, + day: 50 +}).toJSON(), '2021-04-30'); +assert.sameValue(Temporal.PlainDate.from({ + year: 2021, + month: 5, + day: 77 +}).toJSON(), '2021-05-31'); +assert.sameValue(Temporal.PlainDate.from({ + year: 2021, + month: 6, + day: 33 +}).toJSON(), '2021-06-30'); +assert.sameValue(Temporal.PlainDate.from({ + year: 2021, + month: 7, + day: 33 +}).toJSON(), '2021-07-31'); +assert.sameValue(Temporal.PlainDate.from({ + year: 2021, + month: 8, + day: 300 +}).toJSON(), '2021-08-31'); +assert.sameValue(Temporal.PlainDate.from({ + year: 2021, + month: 9, + day: 400 +}).toJSON(), '2021-09-30'); +assert.sameValue(Temporal.PlainDate.from({ + year: 2021, + month: 10, + day: 400 +}).toJSON(), '2021-10-31'); +assert.sameValue(Temporal.PlainDate.from({ + year: 2021, + month: 11, + day: 400 +}).toJSON(), '2021-11-30'); +assert.sameValue(Temporal.PlainDate.from({ + year: 2021, + month: 12, + day: 500 +}).toJSON(), '2021-12-31'); +assert.sameValue(Temporal.PlainDate.from({ + year: 2021, + month: 13, + day: 500 +}).toJSON(), '2021-12-31'); +assert.sameValue(Temporal.PlainDate.from({ + year: 2021, + month: 999999, + day: 500 +}).toJSON(), '2021-12-31'); +assert.sameValue(Temporal.PlainDate.from({ + year: 2021, + monthCode: 'M01', + day: 133 +}).toJSON(), '2021-01-31'); +assert.sameValue(Temporal.PlainDate.from({ + year: 2021, + monthCode: 'M02', + day: 133 +}).toJSON(), '2021-02-28'); +assert.sameValue(Temporal.PlainDate.from({ + year: 2021, + monthCode: 'M03', + day: 9033 +}).toJSON(), '2021-03-31'); +assert.sameValue(Temporal.PlainDate.from({ + year: 2021, + monthCode: 'M04', + day: 50 +}).toJSON(), '2021-04-30'); +assert.sameValue(Temporal.PlainDate.from({ + year: 2021, + monthCode: 'M05', + day: 77 +}).toJSON(), '2021-05-31'); +assert.sameValue(Temporal.PlainDate.from({ + year: 2021, + monthCode: 'M06', + day: 33 +}).toJSON(), '2021-06-30'); +assert.sameValue(Temporal.PlainDate.from({ + year: 2021, + monthCode: 'M07', + day: 33 +}).toJSON(), '2021-07-31'); +assert.sameValue(Temporal.PlainDate.from({ + year: 2021, + monthCode: 'M08', + day: 300 +}).toJSON(), '2021-08-31'); +assert.sameValue(Temporal.PlainDate.from({ + year: 2021, + monthCode: 'M09', + day: 400 +}).toJSON(), '2021-09-30'); +assert.sameValue(Temporal.PlainDate.from({ + year: 2021, + monthCode: 'M10', + day: 400 +}).toJSON(), '2021-10-31'); +assert.sameValue(Temporal.PlainDate.from({ + year: 2021, + monthCode: 'M11', + day: 400 +}).toJSON(), '2021-11-30'); +assert.sameValue(Temporal.PlainDate.from({ + year: 2021, + monthCode: 'M12', + day: 500 +}).toJSON(), '2021-12-31'); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + month: 1, + day: 32 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + month: 2, + day: 29 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + month: 3, + day: 32 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + month: 4, + day: 31 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + month: 5, + day: 32 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + month: 6, + day: 31 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + month: 7, + day: 32 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + month: 8, + day: 32 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + month: 9, + day: 31 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + month: 10, + day: 32 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + month: 11, + day: 31 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + month: 12, + day: 32 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 2021, + month: 13, + day: 5 +}, { overflow: 'reject' })); diff --git a/test/staging/Temporal/v8/calendar-date-until.js b/test/staging/Temporal/v8/calendar-date-until.js new file mode 100644 index 0000000000..960b911e3b --- /dev/null +++ b/test/staging/Temporal/v8/calendar-date-until.js @@ -0,0 +1,156 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from calendar-date-until test + in V8's mjsunit test calendar-date-until.js +features: [Temporal] +---*/ + +[ + 'hour', + 'minute', + 'second', + 'millisecond', + 'microsecond', + 'nanosecond' +].forEach(function (largestUnit) { + assert.throws(RangeError, () => Temporal.PlainDate.from('2021-07-16').until('2021-07-17', { largestUnit })); +}); +assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2021-07-16').toJSON(), 'PT0S'); +assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2021-07-17').toJSON(), 'P1D'); +assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2021-08-17').toJSON(), 'P32D'); +assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2021-09-16').toJSON(), 'P62D'); +assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2022-07-16').toJSON(), 'P365D'); +assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2031-07-16').toJSON(), 'P3652D'); +assert.sameValue(Temporal.PlainDate.from('2021-07-17').until('2021-07-16').toJSON(), '-P1D'); +assert.sameValue(Temporal.PlainDate.from('2021-08-17').until('2021-07-16').toJSON(), '-P32D'); +assert.sameValue(Temporal.PlainDate.from('2021-09-16').until('2021-07-16').toJSON(), '-P62D'); +assert.sameValue(Temporal.PlainDate.from('2022-07-16').until('2021-07-16').toJSON(), '-P365D'); +assert.sameValue(Temporal.PlainDate.from('2031-07-16').until('2021-07-16').toJSON(), '-P3652D'); +[ + 'day', + 'days' +].forEach(function (largestUnit) { + let opt = { largestUnit }; + assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2021-07-16', opt).toJSON(), 'PT0S'); + assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2021-07-17', opt).toJSON(), 'P1D'); + assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2021-08-17', opt).toJSON(), 'P32D'); + assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2021-09-16', opt).toJSON(), 'P62D'); + assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2022-07-16', opt).toJSON(), 'P365D'); + assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2031-07-16', opt).toJSON(), 'P3652D'); + assert.sameValue(Temporal.PlainDate.from('2021-07-17').until('2021-07-16', opt).toJSON(), '-P1D'); + assert.sameValue(Temporal.PlainDate.from('2021-08-17').until('2021-07-16', opt).toJSON(), '-P32D'); + assert.sameValue(Temporal.PlainDate.from('2021-09-16').until('2021-07-16', opt).toJSON(), '-P62D'); + assert.sameValue(Temporal.PlainDate.from('2022-07-16').until('2021-07-16', opt).toJSON(), '-P365D'); + assert.sameValue(Temporal.PlainDate.from('2031-07-16').until('2021-07-16', opt).toJSON(), '-P3652D'); +}); +[ + 'week', + 'weeks' +].forEach(function (largestUnit) { + let opt = { largestUnit }; + assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2021-07-16', opt).toJSON(), 'PT0S'); + assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2021-07-17', opt).toJSON(), 'P1D'); + assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2021-07-23', opt).toJSON(), 'P1W'); + assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2021-08-17', opt).toJSON(), 'P4W4D'); + assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2021-08-13', opt).toJSON(), 'P4W'); + assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2021-09-16', opt).toJSON(), 'P8W6D'); + assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2022-07-16', opt).toJSON(), 'P52W1D'); + assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2031-07-16', opt).toJSON(), 'P521W5D'); + assert.sameValue(Temporal.PlainDate.from('2021-07-17').until('2021-07-16', opt).toJSON(), '-P1D'); + assert.sameValue(Temporal.PlainDate.from('2021-08-17').until('2021-07-16', opt).toJSON(), '-P4W4D'); + assert.sameValue(Temporal.PlainDate.from('2021-08-13').until('2021-07-16', opt).toJSON(), '-P4W'); + assert.sameValue(Temporal.PlainDate.from('2021-09-16').until('2021-07-16', opt).toJSON(), '-P8W6D'); + assert.sameValue(Temporal.PlainDate.from('2022-07-16').until('2021-07-16', opt).toJSON(), '-P52W1D'); + assert.sameValue(Temporal.PlainDate.from('2031-07-16').until('2021-07-16', opt).toJSON(), '-P521W5D'); +}); +[ + 'month', + 'months' +].forEach(function (largestUnit) { + let opt = { largestUnit }; + assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2021-07-16', opt).toJSON(), 'PT0S'); + assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2021-07-17', opt).toJSON(), 'P1D'); + assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2021-07-23', opt).toJSON(), 'P7D'); + assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2021-08-16', opt).toJSON(), 'P1M'); + assert.sameValue(Temporal.PlainDate.from('2020-12-16').until('2021-01-16', opt).toJSON(), 'P1M'); + assert.sameValue(Temporal.PlainDate.from('2021-01-05').until('2021-02-05', opt).toJSON(), 'P1M'); + assert.sameValue(Temporal.PlainDate.from('2021-01-07').until('2021-03-07', opt).toJSON(), 'P2M'); + assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2021-08-17', opt).toJSON(), 'P1M1D'); + assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2021-08-13', opt).toJSON(), 'P28D'); + assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2021-09-16', opt).toJSON(), 'P2M'); + assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2022-07-16', opt).toJSON(), 'P12M'); + assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2031-07-16', opt).toJSON(), 'P120M'); + assert.sameValue(Temporal.PlainDate.from('2021-07-17').until('2021-07-16', opt).toJSON(), '-P1D'); + assert.sameValue(Temporal.PlainDate.from('2021-08-17').until('2021-07-16', opt).toJSON(), '-P1M1D'); + assert.sameValue(Temporal.PlainDate.from('2021-08-13').until('2021-07-16', opt).toJSON(), '-P28D'); + assert.sameValue(Temporal.PlainDate.from('2021-08-16').until('2021-07-16', opt).toJSON(), '-P1M'); + assert.sameValue(Temporal.PlainDate.from('2021-08-16').until('2021-07-13', opt).toJSON(), '-P1M3D'); + assert.sameValue(Temporal.PlainDate.from('2021-09-16').until('2021-07-16', opt).toJSON(), '-P2M'); + assert.sameValue(Temporal.PlainDate.from('2021-09-21').until('2021-07-16', opt).toJSON(), '-P2M5D'); + assert.sameValue(Temporal.PlainDate.from('2022-07-16').until('2021-07-16', opt).toJSON(), '-P12M'); + assert.sameValue(Temporal.PlainDate.from('2022-07-17').until('2021-07-16', opt).toJSON(), '-P12M1D'); + assert.sameValue(Temporal.PlainDate.from('2031-07-16').until('2021-07-16', opt).toJSON(), '-P120M'); +}); +[ + 'year', + 'years' +].forEach(function (largestUnit) { + let opt = { largestUnit }; + assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2021-07-16', opt).toJSON(), 'PT0S'); + assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2021-07-17', opt).toJSON(), 'P1D'); + assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2021-07-23', opt).toJSON(), 'P7D'); + assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2021-08-16', opt).toJSON(), 'P1M'); + assert.sameValue(Temporal.PlainDate.from('2020-12-16').until('2021-01-16', opt).toJSON(), 'P1M'); + assert.sameValue(Temporal.PlainDate.from('2021-01-05').until('2021-02-05', opt).toJSON(), 'P1M'); + assert.sameValue(Temporal.PlainDate.from('2021-01-07').until('2021-03-07', opt).toJSON(), 'P2M'); + assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2021-08-17', opt).toJSON(), 'P1M1D'); + assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2021-08-13', opt).toJSON(), 'P28D'); + assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2021-09-16', opt).toJSON(), 'P2M'); + assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2022-07-16', opt).toJSON(), 'P1Y'); + assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2022-07-19', opt).toJSON(), 'P1Y3D'); + assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2022-09-19', opt).toJSON(), 'P1Y2M3D'); + assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2031-07-16', opt).toJSON(), 'P10Y'); + assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('2031-12-16', opt).toJSON(), 'P10Y5M'); + assert.sameValue(Temporal.PlainDate.from('1997-12-16').until('2021-07-16', opt).toJSON(), 'P23Y7M'); + assert.sameValue(Temporal.PlainDate.from('1997-07-16').until('2021-07-16', opt).toJSON(), 'P24Y'); + assert.sameValue(Temporal.PlainDate.from('1997-07-16').until('2021-07-15', opt).toJSON(), 'P23Y11M29D'); + assert.sameValue(Temporal.PlainDate.from('1997-06-16').until('2021-06-15', opt).toJSON(), 'P23Y11M30D'); + assert.sameValue(Temporal.PlainDate.from('1960-02-16').until('2020-03-16', opt).toJSON(), 'P60Y1M'); + assert.sameValue(Temporal.PlainDate.from('1960-02-16').until('2021-03-15', opt).toJSON(), 'P61Y27D'); + assert.sameValue(Temporal.PlainDate.from('1960-02-16').until('2020-03-15', opt).toJSON(), 'P60Y28D'); + assert.sameValue(Temporal.PlainDate.from('2021-03-30').until('2021-07-16', opt).toJSON(), 'P3M16D'); + assert.sameValue(Temporal.PlainDate.from('2020-03-30').until('2021-07-16', opt).toJSON(), 'P1Y3M16D'); + assert.sameValue(Temporal.PlainDate.from('1960-03-30').until('2021-07-16', opt).toJSON(), 'P61Y3M16D'); + assert.sameValue(Temporal.PlainDate.from('2019-12-30').until('2021-07-16', opt).toJSON(), 'P1Y6M16D'); + assert.sameValue(Temporal.PlainDate.from('2020-12-30').until('2021-07-16', opt).toJSON(), 'P6M16D'); + assert.sameValue(Temporal.PlainDate.from('1997-12-30').until('2021-07-16', opt).toJSON(), 'P23Y6M16D'); + assert.sameValue(Temporal.PlainDate.from('0001-12-25').until('2021-07-16', opt).toJSON(), 'P2019Y6M21D'); + assert.sameValue(Temporal.PlainDate.from('2019-12-30').until('2021-03-05', opt).toJSON(), 'P1Y2M5D'); + assert.sameValue(Temporal.PlainDate.from('2021-07-17').until('2021-07-16', opt).toJSON(), '-P1D'); + assert.sameValue(Temporal.PlainDate.from('2021-08-17').until('2021-07-16', opt).toJSON(), '-P1M1D'); + assert.sameValue(Temporal.PlainDate.from('2021-08-13').until('2021-07-16', opt).toJSON(), '-P28D'); + assert.sameValue(Temporal.PlainDate.from('2021-08-16').until('2021-07-16', opt).toJSON(), '-P1M'); + assert.sameValue(Temporal.PlainDate.from('2021-08-16').until('2021-07-13', opt).toJSON(), '-P1M3D'); + assert.sameValue(Temporal.PlainDate.from('2021-09-16').until('2021-07-16', opt).toJSON(), '-P2M'); + assert.sameValue(Temporal.PlainDate.from('2021-09-21').until('2021-07-16', opt).toJSON(), '-P2M5D'); + assert.sameValue(Temporal.PlainDate.from('2022-07-16').until('2021-07-16', opt).toJSON(), '-P1Y'); + assert.sameValue(Temporal.PlainDate.from('2022-07-17').until('2021-07-16', opt).toJSON(), '-P1Y1D'); + assert.sameValue(Temporal.PlainDate.from('2022-10-17').until('2021-07-16', opt).toJSON(), '-P1Y3M1D'); + assert.sameValue(Temporal.PlainDate.from('2031-07-16').until('2021-07-16', opt).toJSON(), '-P10Y'); + assert.sameValue(Temporal.PlainDate.from('2032-07-16').until('2021-08-16', opt).toJSON(), '-P10Y11M'); + assert.sameValue(Temporal.PlainDate.from('2031-12-16').until('2021-07-16', opt).toJSON(), '-P10Y5M'); + assert.sameValue(Temporal.PlainDate.from('2011-07-16').until('1997-12-16', opt).toJSON(), '-P13Y7M'); + assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('1997-07-16', opt).toJSON(), '-P24Y'); + assert.sameValue(Temporal.PlainDate.from('2021-07-15').until('1997-07-16', opt).toJSON(), '-P23Y11M30D'); + assert.sameValue(Temporal.PlainDate.from('2021-06-15').until('1997-06-16', opt).toJSON(), '-P23Y11M29D'); + assert.sameValue(Temporal.PlainDate.from('2020-03-16').until('1960-02-16', opt).toJSON(), '-P60Y1M'); + assert.sameValue(Temporal.PlainDate.from('2021-03-15').until('1960-02-16', opt).toJSON(), '-P61Y28D'); + assert.sameValue(Temporal.PlainDate.from('2020-03-15').until('1960-02-16', opt).toJSON(), '-P60Y28D'); + assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('1960-03-30', opt).toJSON(), '-P61Y3M17D'); + assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('0001-12-25', opt).toJSON(), '-P2019Y6M22D'); + assert.sameValue(Temporal.PlainDate.from('2021-07-16').until('1997-12-30', opt).toJSON(), '-P23Y6M17D'); +}); diff --git a/test/staging/Temporal/v8/calendar-day-of-week.js b/test/staging/Temporal/v8/calendar-day-of-week.js new file mode 100644 index 0000000000..831faf92ec --- /dev/null +++ b/test/staging/Temporal/v8/calendar-day-of-week.js @@ -0,0 +1,54 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from calendar-day-of-week test + in V8's mjsunit test calendar-day-of-week.js +features: [Temporal] +---*/ + +assert.sameValue((new Temporal.PlainDate(1970, 1, 1)).dayOfWeek, 4); +assert.sameValue((new Temporal.PlainDate(2000, 1, 1)).dayOfWeek, 6); +assert.sameValue((new Temporal.PlainDate(2021, 1, 15)).dayOfWeek, 5); +assert.sameValue((new Temporal.PlainDate(2020, 2, 15)).dayOfWeek, 6); +assert.sameValue((new Temporal.PlainDate(2000, 2, 15)).dayOfWeek, 2); +assert.sameValue((new Temporal.PlainDate(2021, 2, 15)).dayOfWeek, 1); +assert.sameValue((new Temporal.PlainDate(2021, 3, 15)).dayOfWeek, 1); +assert.sameValue((new Temporal.PlainDate(2021, 4, 15)).dayOfWeek, 4); +assert.sameValue((new Temporal.PlainDate(2021, 5, 15)).dayOfWeek, 6); +assert.sameValue((new Temporal.PlainDate(2021, 6, 15)).dayOfWeek, 2); +assert.sameValue((new Temporal.PlainDate(2021, 7, 15)).dayOfWeek, 4); +assert.sameValue((new Temporal.PlainDate(2021, 8, 15)).dayOfWeek, 7); +assert.sameValue((new Temporal.PlainDate(2021, 9, 15)).dayOfWeek, 3); +assert.sameValue((new Temporal.PlainDate(2021, 10, 15)).dayOfWeek, 5); +assert.sameValue((new Temporal.PlainDate(2021, 11, 15)).dayOfWeek, 1); +assert.sameValue((new Temporal.PlainDate(2021, 12, 15)).dayOfWeek, 3); +assert.sameValue((new Temporal.PlainDateTime(1997, 1, 23, 5, 30, 13)).dayOfWeek, 4); +assert.sameValue((new Temporal.PlainDateTime(1996, 2, 23, 5, 30, 13)).dayOfWeek, 5); +assert.sameValue((new Temporal.PlainDateTime(2000, 2, 23, 5, 30, 13)).dayOfWeek, 3); +assert.sameValue((new Temporal.PlainDateTime(1997, 2, 23, 5, 30, 13)).dayOfWeek, 7); +assert.sameValue((new Temporal.PlainDateTime(1997, 3, 23, 5, 30, 13)).dayOfWeek, 7); +assert.sameValue((new Temporal.PlainDateTime(1997, 4, 23, 5, 30, 13)).dayOfWeek, 3); +assert.sameValue((new Temporal.PlainDateTime(1997, 5, 23, 5, 30, 13)).dayOfWeek, 5); +assert.sameValue((new Temporal.PlainDateTime(1997, 6, 23, 5, 30, 13)).dayOfWeek, 1); +assert.sameValue((new Temporal.PlainDateTime(1997, 7, 23, 5, 30, 13)).dayOfWeek, 3); +assert.sameValue((new Temporal.PlainDateTime(1997, 8, 23, 5, 30, 13)).dayOfWeek, 6); +assert.sameValue((new Temporal.PlainDateTime(1997, 9, 23, 5, 30, 13)).dayOfWeek, 2); +assert.sameValue((new Temporal.PlainDateTime(1997, 10, 23, 5, 30, 13)).dayOfWeek, 4); +assert.sameValue((new Temporal.PlainDateTime(1997, 11, 23, 5, 30, 13)).dayOfWeek, 7); +assert.sameValue((new Temporal.PlainDateTime(1997, 12, 23, 5, 30, 13)).dayOfWeek, 2); +assert.sameValue(Temporal.PlainDate.from('2019-01-18').dayOfWeek, 5); +assert.sameValue(Temporal.PlainDate.from('2020-02-18').dayOfWeek, 2); +assert.sameValue(Temporal.PlainDate.from('2019-02-18').dayOfWeek, 1); +assert.sameValue(Temporal.PlainDate.from('2019-03-18').dayOfWeek, 1); +assert.sameValue(Temporal.PlainDate.from('2019-04-18').dayOfWeek, 4); +assert.sameValue(Temporal.PlainDate.from('2019-05-18').dayOfWeek, 6); +assert.sameValue(Temporal.PlainDate.from('2019-06-18').dayOfWeek, 2); +assert.sameValue(Temporal.PlainDate.from('2019-07-18').dayOfWeek, 4); +assert.sameValue(Temporal.PlainDate.from('2019-08-18').dayOfWeek, 7); +assert.sameValue(Temporal.PlainDate.from('2019-09-18').dayOfWeek, 3); +assert.sameValue(Temporal.PlainDate.from('2019-10-18').dayOfWeek, 5); +assert.sameValue(Temporal.PlainDate.from('2019-11-18').dayOfWeek, 1); +assert.sameValue(Temporal.PlainDate.from('2019-12-18').dayOfWeek, 3); diff --git a/test/staging/Temporal/v8/calendar-day-of-year.js b/test/staging/Temporal/v8/calendar-day-of-year.js new file mode 100644 index 0000000000..61fb57e212 --- /dev/null +++ b/test/staging/Temporal/v8/calendar-day-of-year.js @@ -0,0 +1,31 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from calendar-day-of-year test + in V8's mjsunit test calendar-day-of-year.js +features: [Temporal] +---*/ + +assert.sameValue((new Temporal.PlainDate(1970, 1, 1)).dayOfYear, 1); +assert.sameValue((new Temporal.PlainDate(2000, 1, 1)).dayOfYear, 1); +assert.sameValue((new Temporal.PlainDate(2021, 1, 15)).dayOfYear, 15); +assert.sameValue((new Temporal.PlainDate(2020, 2, 15)).dayOfYear, 46); +assert.sameValue((new Temporal.PlainDate(2000, 2, 15)).dayOfYear, 46); +assert.sameValue((new Temporal.PlainDate(2020, 3, 15)).dayOfYear, 75); +assert.sameValue((new Temporal.PlainDate(2000, 3, 15)).dayOfYear, 75); +assert.sameValue((new Temporal.PlainDate(2001, 3, 15)).dayOfYear, 74); +assert.sameValue((new Temporal.PlainDate(2000, 12, 31)).dayOfYear, 366); +assert.sameValue((new Temporal.PlainDate(2001, 12, 31)).dayOfYear, 365); +assert.sameValue((new Temporal.PlainDateTime(1997, 1, 23, 5, 30, 13)).dayOfYear, 23); +assert.sameValue((new Temporal.PlainDateTime(1997, 2, 23, 5, 30, 13)).dayOfYear, 54); +assert.sameValue((new Temporal.PlainDateTime(1996, 3, 23, 5, 30, 13)).dayOfYear, 83); +assert.sameValue((new Temporal.PlainDateTime(1997, 3, 23, 5, 30, 13)).dayOfYear, 82); +assert.sameValue((new Temporal.PlainDateTime(1997, 12, 31, 5, 30, 13)).dayOfYear, 365); +assert.sameValue((new Temporal.PlainDateTime(1996, 12, 31, 5, 30, 13)).dayOfYear, 366); +assert.sameValue(Temporal.PlainDate.from('2019-01-18').dayOfYear, 18); +assert.sameValue(Temporal.PlainDate.from('2020-02-18').dayOfYear, 49); +assert.sameValue(Temporal.PlainDate.from('2019-12-31').dayOfYear, 365); +assert.sameValue(Temporal.PlainDate.from('2000-12-31').dayOfYear, 366); diff --git a/test/staging/Temporal/v8/calendar-day.js b/test/staging/Temporal/v8/calendar-day.js new file mode 100644 index 0000000000..bfbeaed017 --- /dev/null +++ b/test/staging/Temporal/v8/calendar-day.js @@ -0,0 +1,15 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from calendar-day test + in V8's mjsunit test calendar-day.js +features: [Temporal] +---*/ + +assert.sameValue((new Temporal.PlainDate(2021, 7, 15)).day, 15); +assert.sameValue((new Temporal.PlainDateTime(1997, 8, 23, 5, 30, 13)).day, 23); +assert.sameValue((new Temporal.PlainMonthDay(2, 6)).day, 6); +assert.sameValue(Temporal.PlainDate.from('2019-03-18').day, 18); diff --git a/test/staging/Temporal/v8/calendar-days-in-month.js b/test/staging/Temporal/v8/calendar-days-in-month.js new file mode 100644 index 0000000000..35ecbaad6b --- /dev/null +++ b/test/staging/Temporal/v8/calendar-days-in-month.js @@ -0,0 +1,52 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from calendar-days-in-month test + in V8's mjsunit test calendar-days-in-month.js +features: [Temporal] +---*/ + +assert.sameValue((new Temporal.PlainDate(2021, 1, 15)).daysInMonth, 31); +assert.sameValue((new Temporal.PlainDate(2020, 2, 15)).daysInMonth, 29); +assert.sameValue((new Temporal.PlainDate(2000, 2, 15)).daysInMonth, 29); +assert.sameValue((new Temporal.PlainDate(2021, 2, 15)).daysInMonth, 28); +assert.sameValue((new Temporal.PlainDate(2021, 3, 15)).daysInMonth, 31); +assert.sameValue((new Temporal.PlainDate(2021, 4, 15)).daysInMonth, 30); +assert.sameValue((new Temporal.PlainDate(2021, 5, 15)).daysInMonth, 31); +assert.sameValue((new Temporal.PlainDate(2021, 6, 15)).daysInMonth, 30); +assert.sameValue((new Temporal.PlainDate(2021, 7, 15)).daysInMonth, 31); +assert.sameValue((new Temporal.PlainDate(2021, 8, 15)).daysInMonth, 31); +assert.sameValue((new Temporal.PlainDate(2021, 9, 15)).daysInMonth, 30); +assert.sameValue((new Temporal.PlainDate(2021, 10, 15)).daysInMonth, 31); +assert.sameValue((new Temporal.PlainDate(2021, 11, 15)).daysInMonth, 30); +assert.sameValue((new Temporal.PlainDate(2021, 12, 15)).daysInMonth, 31); +assert.sameValue((new Temporal.PlainDateTime(1997, 1, 23, 5, 30, 13)).daysInMonth, 31); +assert.sameValue((new Temporal.PlainDateTime(1996, 2, 23, 5, 30, 13)).daysInMonth, 29); +assert.sameValue((new Temporal.PlainDateTime(2000, 2, 23, 5, 30, 13)).daysInMonth, 29); +assert.sameValue((new Temporal.PlainDateTime(1997, 2, 23, 5, 30, 13)).daysInMonth, 28); +assert.sameValue((new Temporal.PlainDateTime(1997, 3, 23, 5, 30, 13)).daysInMonth, 31); +assert.sameValue((new Temporal.PlainDateTime(1997, 4, 23, 5, 30, 13)).daysInMonth, 30); +assert.sameValue((new Temporal.PlainDateTime(1997, 5, 23, 5, 30, 13)).daysInMonth, 31); +assert.sameValue((new Temporal.PlainDateTime(1997, 6, 23, 5, 30, 13)).daysInMonth, 30); +assert.sameValue((new Temporal.PlainDateTime(1997, 7, 23, 5, 30, 13)).daysInMonth, 31); +assert.sameValue((new Temporal.PlainDateTime(1997, 8, 23, 5, 30, 13)).daysInMonth, 31); +assert.sameValue((new Temporal.PlainDateTime(1997, 9, 23, 5, 30, 13)).daysInMonth, 30); +assert.sameValue((new Temporal.PlainDateTime(1997, 10, 23, 5, 30, 13)).daysInMonth, 31); +assert.sameValue((new Temporal.PlainDateTime(1997, 11, 23, 5, 30, 13)).daysInMonth, 30); +assert.sameValue((new Temporal.PlainDateTime(1997, 12, 23, 5, 30, 13)).daysInMonth, 31); +assert.sameValue(Temporal.PlainDate.from('2019-01-18').daysInMonth, 31); +assert.sameValue(Temporal.PlainDate.from('2020-02-18').daysInMonth, 29); +assert.sameValue(Temporal.PlainDate.from('2019-02-18').daysInMonth, 28); +assert.sameValue(Temporal.PlainDate.from('2019-03-18').daysInMonth, 31); +assert.sameValue(Temporal.PlainDate.from('2019-04-18').daysInMonth, 30); +assert.sameValue(Temporal.PlainDate.from('2019-05-18').daysInMonth, 31); +assert.sameValue(Temporal.PlainDate.from('2019-06-18').daysInMonth, 30); +assert.sameValue(Temporal.PlainDate.from('2019-07-18').daysInMonth, 31); +assert.sameValue(Temporal.PlainDate.from('2019-08-18').daysInMonth, 31); +assert.sameValue(Temporal.PlainDate.from('2019-09-18').daysInMonth, 30); +assert.sameValue(Temporal.PlainDate.from('2019-10-18').daysInMonth, 31); +assert.sameValue(Temporal.PlainDate.from('2019-11-18').daysInMonth, 30); +assert.sameValue(Temporal.PlainDate.from('2019-12-18').daysInMonth, 31); diff --git a/test/staging/Temporal/v8/calendar-days-in-week.js b/test/staging/Temporal/v8/calendar-days-in-week.js new file mode 100644 index 0000000000..382484bf63 --- /dev/null +++ b/test/staging/Temporal/v8/calendar-days-in-week.js @@ -0,0 +1,14 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from calendar-days-in-week test + in V8's mjsunit test calendar-days-in-week.js +features: [Temporal] +---*/ + +assert.sameValue((new Temporal.PlainDate(2021, 7, 15)).daysInWeek, 7); +assert.sameValue((new Temporal.PlainDateTime(1997, 8, 23, 5, 30, 13)).daysInWeek, 7); +assert.sameValue(Temporal.PlainDate.from('2019-03-18').daysInWeek, 7); diff --git a/test/staging/Temporal/v8/calendar-days-in-year.js b/test/staging/Temporal/v8/calendar-days-in-year.js new file mode 100644 index 0000000000..badd2ff58c --- /dev/null +++ b/test/staging/Temporal/v8/calendar-days-in-year.js @@ -0,0 +1,41 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from calendar-days-in-year test + in V8's mjsunit test calendar-days-in-year.js +features: [Temporal] +---*/ + +assert.sameValue((new Temporal.PlainDate(1995, 7, 15)).daysInYear, 365); +assert.sameValue((new Temporal.PlainDate(1996, 7, 15)).daysInYear, 366); +assert.sameValue((new Temporal.PlainDate(1997, 7, 15)).daysInYear, 365); +assert.sameValue((new Temporal.PlainDate(1998, 7, 15)).daysInYear, 365); +assert.sameValue((new Temporal.PlainDate(1999, 7, 15)).daysInYear, 365); +assert.sameValue((new Temporal.PlainDate(2000, 7, 15)).daysInYear, 366); +assert.sameValue((new Temporal.PlainDate(2001, 7, 15)).daysInYear, 365); +assert.sameValue((new Temporal.PlainDate(2002, 7, 15)).daysInYear, 365); +assert.sameValue((new Temporal.PlainDate(2003, 7, 15)).daysInYear, 365); +assert.sameValue((new Temporal.PlainDate(2004, 7, 15)).daysInYear, 366); +assert.sameValue((new Temporal.PlainDate(2005, 7, 15)).daysInYear, 365); +assert.sameValue((new Temporal.PlainDateTime(1995, 8, 23, 5, 30, 13)).daysInYear, 365); +assert.sameValue((new Temporal.PlainDateTime(1996, 8, 23, 5, 30, 13)).daysInYear, 366); +assert.sameValue((new Temporal.PlainDateTime(1997, 8, 23, 5, 30, 13)).daysInYear, 365); +assert.sameValue((new Temporal.PlainDateTime(1998, 8, 23, 5, 30, 13)).daysInYear, 365); +assert.sameValue((new Temporal.PlainDateTime(1999, 8, 23, 5, 30, 13)).daysInYear, 365); +assert.sameValue((new Temporal.PlainDateTime(2000, 8, 23, 5, 30, 13)).daysInYear, 366); +assert.sameValue((new Temporal.PlainDateTime(2001, 8, 23, 5, 30, 13)).daysInYear, 365); +assert.sameValue((new Temporal.PlainDateTime(2002, 8, 23, 5, 30, 13)).daysInYear, 365); +assert.sameValue((new Temporal.PlainDateTime(2003, 8, 23, 5, 30, 13)).daysInYear, 365); +assert.sameValue((new Temporal.PlainDateTime(2004, 8, 23, 5, 30, 13)).daysInYear, 366); +assert.sameValue((new Temporal.PlainDateTime(2005, 8, 23, 5, 30, 13)).daysInYear, 365); +assert.sameValue(Temporal.PlainDate.from('2019-03-18').daysInYear, 365); +assert.sameValue(Temporal.PlainDate.from('2020-03-18').daysInYear, 366); +assert.sameValue(Temporal.PlainDate.from('2021-03-18').daysInYear, 365); +assert.sameValue(Temporal.PlainDate.from('2022-03-18').daysInYear, 365); +assert.sameValue(Temporal.PlainDate.from('2023-03-18').daysInYear, 365); +assert.sameValue(Temporal.PlainDate.from('2024-03-18').daysInYear, 366); +assert.sameValue(Temporal.PlainDate.from('2025-03-18').daysInYear, 365); +assert.sameValue(Temporal.PlainDate.from('2026-03-18').daysInYear, 365); diff --git a/test/staging/Temporal/v8/calendar-in-leap-year.js b/test/staging/Temporal/v8/calendar-in-leap-year.js new file mode 100644 index 0000000000..ff387ce440 --- /dev/null +++ b/test/staging/Temporal/v8/calendar-in-leap-year.js @@ -0,0 +1,41 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from calendar-in-leap-year test + in V8's mjsunit test calendar-in-leap-year.js +features: [Temporal] +---*/ + +assert.sameValue((new Temporal.PlainDate(1995, 7, 15)).inLeapYear, false); +assert.sameValue((new Temporal.PlainDate(1996, 7, 15)).inLeapYear, true); +assert.sameValue((new Temporal.PlainDate(1997, 7, 15)).inLeapYear, false); +assert.sameValue((new Temporal.PlainDate(1998, 7, 15)).inLeapYear, false); +assert.sameValue((new Temporal.PlainDate(1999, 7, 15)).inLeapYear, false); +assert.sameValue((new Temporal.PlainDate(2000, 7, 15)).inLeapYear, true); +assert.sameValue((new Temporal.PlainDate(2001, 7, 15)).inLeapYear, false); +assert.sameValue((new Temporal.PlainDate(2002, 7, 15)).inLeapYear, false); +assert.sameValue((new Temporal.PlainDate(2003, 7, 15)).inLeapYear, false); +assert.sameValue((new Temporal.PlainDate(2004, 7, 15)).inLeapYear, true); +assert.sameValue((new Temporal.PlainDate(2005, 7, 15)).inLeapYear, false); +assert.sameValue((new Temporal.PlainDateTime(1995, 8, 23, 5, 30, 13)).inLeapYear, false); +assert.sameValue((new Temporal.PlainDateTime(1996, 8, 23, 5, 30, 13)).inLeapYear, true); +assert.sameValue((new Temporal.PlainDateTime(1997, 8, 23, 5, 30, 13)).inLeapYear, false); +assert.sameValue((new Temporal.PlainDateTime(1998, 8, 23, 5, 30, 13)).inLeapYear, false); +assert.sameValue((new Temporal.PlainDateTime(1999, 8, 23, 5, 30, 13)).inLeapYear, false); +assert.sameValue((new Temporal.PlainDateTime(2000, 8, 23, 5, 30, 13)).inLeapYear, true); +assert.sameValue((new Temporal.PlainDateTime(2001, 8, 23, 5, 30, 13)).inLeapYear, false); +assert.sameValue((new Temporal.PlainDateTime(2002, 8, 23, 5, 30, 13)).inLeapYear, false); +assert.sameValue((new Temporal.PlainDateTime(2003, 8, 23, 5, 30, 13)).inLeapYear, false); +assert.sameValue((new Temporal.PlainDateTime(2004, 8, 23, 5, 30, 13)).inLeapYear, true); +assert.sameValue((new Temporal.PlainDateTime(2005, 8, 23, 5, 30, 13)).inLeapYear, false); +assert.sameValue(Temporal.PlainDate.from('2019-03-18').inLeapYear, false); +assert.sameValue(Temporal.PlainDate.from('2020-03-18').inLeapYear, true); +assert.sameValue(Temporal.PlainDate.from('2021-03-18').inLeapYear, false); +assert.sameValue(Temporal.PlainDate.from('2022-03-18').inLeapYear, false); +assert.sameValue(Temporal.PlainDate.from('2023-03-18').inLeapYear, false); +assert.sameValue(Temporal.PlainDate.from('2024-03-18').inLeapYear, true); +assert.sameValue(Temporal.PlainDate.from('2025-03-18').inLeapYear, false); +assert.sameValue(Temporal.PlainDate.from('2026-03-18').inLeapYear, false); diff --git a/test/staging/Temporal/v8/calendar-month-code.js b/test/staging/Temporal/v8/calendar-month-code.js new file mode 100644 index 0000000000..b27174f9b8 --- /dev/null +++ b/test/staging/Temporal/v8/calendar-month-code.js @@ -0,0 +1,16 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from calendar-month-code test + in V8's mjsunit test calendar-month-code.js +features: [Temporal] +---*/ + +assert.sameValue((new Temporal.PlainDate(2021, 7, 15)).monthCode, 'M07'); +assert.sameValue((new Temporal.PlainDateTime(1997, 8, 23, 5, 30, 13)).monthCode, 'M08'); +assert.sameValue((new Temporal.PlainYearMonth(1999, 6)).monthCode, 'M06'); +assert.sameValue((new Temporal.PlainMonthDay(2, 6)).monthCode, 'M02'); +assert.sameValue(Temporal.PlainDate.from('2019-03-15').monthCode, 'M03'); diff --git a/test/staging/Temporal/v8/calendar-month-day-from-fields.js b/test/staging/Temporal/v8/calendar-month-day-from-fields.js new file mode 100644 index 0000000000..8b9905f9aa --- /dev/null +++ b/test/staging/Temporal/v8/calendar-month-day-from-fields.js @@ -0,0 +1,422 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from calendar-month-day-from-fields test + in V8's mjsunit test calendar-month-day-from-fields.js +features: [Temporal] +---*/ + +assert.throws(TypeError, () => Temporal.PlainMonthDay.from()); +[ + undefined, + true, + false, + 123, + 456n, + Symbol(), +].forEach(function (fields) { + assert.throws(TypeError, () => Temporal.PlainMonthDay.from(fields)); + assert.throws(TypeError, () => Temporal.PlainMonthDay.from(fields, undefined)); + assert.throws(TypeError, () => Temporal.PlainMonthDay.from(fields, { overflow: 'constrain' })); + assert.throws(TypeError, () => Temporal.PlainMonthDay.from(fields, { overflow: 'reject' })); +}); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from('string')); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from('string', undefined)); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from('string', { overflow: 'constrain' })); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from('string', { overflow: 'reject' })); +assert.sameValue(Temporal.PlainMonthDay.from({ + month: 1, + day: 17 +}).toJSON(), '01-17'); +assert.throws(TypeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + day: 17 +})); +assert.throws(TypeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + month: 12 +})); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + monthCode: 'm1', + day: 17 +})); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + monthCode: 'M1', + day: 17 +})); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + monthCode: 'm01', + day: 17 +})); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + month: 12, + monthCode: 'M11', + day: 17 +})); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + monthCode: 'M00', + day: 17 +})); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + monthCode: 'M19', + day: 17 +})); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + monthCode: 'M99', + day: 17 +})); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + monthCode: 'M13', + day: 17 +})); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + month: -1, + day: 17 +})); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + month: -Infinity, + day: 17 +})); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + month: 7, + day: -17 +})); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + month: 7, + day: -Infinity +})); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + month: 12, + day: 0 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + month: 12, + day: 32 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + month: 1, + day: 32 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + month: 2, + day: 29 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + month: 6, + day: 31 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + month: 9, + day: 31 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + month: 0, + day: 5 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + month: 13, + day: 5 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + monthCode: 'M12', + day: 0 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + monthCode: 'M12', + day: 32 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + monthCode: 'M01', + day: 32 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + monthCode: 'M06', + day: 31 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + monthCode: 'M09', + day: 31 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + monthCode: 'M00', + day: 5 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + monthCode: 'M13', + day: 5 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + month: 12, + day: 0 +})); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + month: 0, + day: 3 +})); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + month: 7, + day: 13 +}, { overflow: 'invalid' })); +assert.sameValue(Temporal.PlainMonthDay.from({ + year: 2021, + month: 7, + day: 15 +}).toJSON(), '07-15'); +assert.sameValue(Temporal.PlainMonthDay.from({ + year: 2021, + month: 7, + day: 3 +}).toJSON(), '07-03'); +assert.sameValue(Temporal.PlainMonthDay.from({ + year: 2021, + month: 12, + day: 31 +}).toJSON(), '12-31'); +assert.sameValue(Temporal.PlainMonthDay.from({ + year: 2021, + monthCode: 'M07', + day: 15 +}).toJSON(), '07-15'); +assert.sameValue(Temporal.PlainMonthDay.from({ + year: 2021, + monthCode: 'M07', + day: 3 +}).toJSON(), '07-03'); +assert.sameValue(Temporal.PlainMonthDay.from({ + year: 2021, + monthCode: 'M12', + day: 31 +}).toJSON(), '12-31'); +assert.sameValue(Temporal.PlainMonthDay.from({ + year: 2021, + monthCode: 'M02', + day: 29 +}).toJSON(), '02-28'); +assert.sameValue(Temporal.PlainMonthDay.from({ + year: 2021, + month: 1, + day: 133 +}).toJSON(), '01-31'); +assert.sameValue(Temporal.PlainMonthDay.from({ + year: 2021, + month: 2, + day: 133 +}).toJSON(), '02-28'); +assert.sameValue(Temporal.PlainMonthDay.from({ + year: 2021, + month: 3, + day: 9033 +}).toJSON(), '03-31'); +assert.sameValue(Temporal.PlainMonthDay.from({ + year: 2021, + month: 4, + day: 50 +}).toJSON(), '04-30'); +assert.sameValue(Temporal.PlainMonthDay.from({ + year: 2021, + month: 5, + day: 77 +}).toJSON(), '05-31'); +assert.sameValue(Temporal.PlainMonthDay.from({ + year: 2021, + month: 6, + day: 33 +}).toJSON(), '06-30'); +assert.sameValue(Temporal.PlainMonthDay.from({ + year: 2021, + month: 7, + day: 33 +}).toJSON(), '07-31'); +assert.sameValue(Temporal.PlainMonthDay.from({ + year: 2021, + month: 8, + day: 300 +}).toJSON(), '08-31'); +assert.sameValue(Temporal.PlainMonthDay.from({ + year: 2021, + month: 9, + day: 400 +}).toJSON(), '09-30'); +assert.sameValue(Temporal.PlainMonthDay.from({ + year: 2021, + month: 10, + day: 400 +}).toJSON(), '10-31'); +assert.sameValue(Temporal.PlainMonthDay.from({ + year: 2021, + month: 11, + day: 400 +}).toJSON(), '11-30'); +assert.sameValue(Temporal.PlainMonthDay.from({ + year: 2021, + month: 12, + day: 500 +}).toJSON(), '12-31'); +assert.sameValue(Temporal.PlainMonthDay.from({ + year: 2021, + month: 13, + day: 500 +}).toJSON(), '12-31'); +assert.sameValue(Temporal.PlainMonthDay.from({ + year: 2021, + month: 999999, + day: 500 +}).toJSON(), '12-31'); +assert.sameValue(Temporal.PlainMonthDay.from({ + year: 2021, + monthCode: 'M01', + day: 133 +}).toJSON(), '01-31'); +assert.sameValue(Temporal.PlainMonthDay.from({ + year: 2021, + monthCode: 'M02', + day: 133 +}).toJSON(), '02-28'); +assert.sameValue(Temporal.PlainMonthDay.from({ + year: 2021, + monthCode: 'M03', + day: 9033 +}).toJSON(), '03-31'); +assert.sameValue(Temporal.PlainMonthDay.from({ + year: 2021, + monthCode: 'M04', + day: 50 +}).toJSON(), '04-30'); +assert.sameValue(Temporal.PlainMonthDay.from({ + year: 2021, + monthCode: 'M05', + day: 77 +}).toJSON(), '05-31'); +assert.sameValue(Temporal.PlainMonthDay.from({ + year: 2021, + monthCode: 'M06', + day: 33 +}).toJSON(), '06-30'); +assert.sameValue(Temporal.PlainMonthDay.from({ + year: 2021, + monthCode: 'M07', + day: 33 +}).toJSON(), '07-31'); +assert.sameValue(Temporal.PlainMonthDay.from({ + year: 2021, + monthCode: 'M08', + day: 300 +}).toJSON(), '08-31'); +assert.sameValue(Temporal.PlainMonthDay.from({ + year: 2021, + monthCode: 'M09', + day: 400 +}).toJSON(), '09-30'); +assert.sameValue(Temporal.PlainMonthDay.from({ + year: 2021, + monthCode: 'M10', + day: 400 +}).toJSON(), '10-31'); +assert.sameValue(Temporal.PlainMonthDay.from({ + year: 2021, + monthCode: 'M11', + day: 400 +}).toJSON(), '11-30'); +assert.sameValue(Temporal.PlainMonthDay.from({ + year: 2021, + monthCode: 'M12', + day: 500 +}).toJSON(), '12-31'); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + month: 1, + day: 32 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + month: 2, + day: 29 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + month: 3, + day: 32 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + month: 4, + day: 31 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + month: 5, + day: 32 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + month: 6, + day: 31 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + month: 7, + day: 32 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + month: 8, + day: 32 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + month: 9, + day: 31 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + month: 10, + day: 32 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + month: 11, + day: 31 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + month: 12, + day: 32 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ + year: 2021, + month: 13, + day: 5 +}, { overflow: 'reject' })); diff --git a/test/staging/Temporal/v8/calendar-month.js b/test/staging/Temporal/v8/calendar-month.js new file mode 100644 index 0000000000..33663d15b1 --- /dev/null +++ b/test/staging/Temporal/v8/calendar-month.js @@ -0,0 +1,16 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from calendar-month test + in V8's mjsunit test calendar-month.js +features: [Temporal] +---*/ + +assert.sameValue((new Temporal.PlainDate(2021, 7, 15)).month, 7); +assert.sameValue((new Temporal.PlainDateTime(1997, 8, 23, 5, 30, 13)).month, 8); +assert.sameValue((new Temporal.PlainYearMonth(1999, 6)).month, 6); +assert.sameValue(Temporal.PlainDate.from('2019-03-15').month, 3); +assert.sameValue((new Temporal.PlainMonthDay(3, 16)).month, undefined); diff --git a/test/staging/Temporal/v8/calendar-months-in-year.js b/test/staging/Temporal/v8/calendar-months-in-year.js new file mode 100644 index 0000000000..5aff81e861 --- /dev/null +++ b/test/staging/Temporal/v8/calendar-months-in-year.js @@ -0,0 +1,17 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from calendar-months-in-year test + in V8's mjsunit test calendar-months-in-year.js +features: [Temporal] +---*/ + +assert.sameValue((new Temporal.PlainDate(2021, 7, 15)).monthsInYear, 12); +assert.sameValue((new Temporal.PlainDate(1234, 7, 15)).monthsInYear, 12); +assert.sameValue((new Temporal.PlainDateTime(1997, 8, 23, 5, 30, 13)).monthsInYear, 12); +assert.sameValue((new Temporal.PlainDateTime(1234, 8, 23, 5, 30, 13)).monthsInYear, 12); +assert.sameValue(Temporal.PlainDate.from('2019-03-18').monthsInYear, 12); +assert.sameValue(Temporal.PlainDate.from('1234-03-18').monthsInYear, 12); diff --git a/test/staging/Temporal/v8/calendar-week-of-year.js b/test/staging/Temporal/v8/calendar-week-of-year.js new file mode 100644 index 0000000000..4aeab8a7cb --- /dev/null +++ b/test/staging/Temporal/v8/calendar-week-of-year.js @@ -0,0 +1,49 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from calendar-week-of-year test + in V8's mjsunit test calendar-week-of-year.js +features: [Temporal] +---*/ + +assert.sameValue((new Temporal.PlainDate(1977, 1, 1)).weekOfYear, 53); +assert.sameValue((new Temporal.PlainDate(1977, 1, 2)).weekOfYear, 53); +assert.sameValue((new Temporal.PlainDate(1977, 12, 31)).weekOfYear, 52); +assert.sameValue((new Temporal.PlainDate(1978, 1, 1)).weekOfYear, 52); +assert.sameValue((new Temporal.PlainDate(1978, 1, 2)).weekOfYear, 1); +assert.sameValue((new Temporal.PlainDate(1978, 12, 31)).weekOfYear, 52); +assert.sameValue((new Temporal.PlainDate(1979, 1, 1)).weekOfYear, 1); +assert.sameValue((new Temporal.PlainDate(1979, 12, 30)).weekOfYear, 52); +assert.sameValue((new Temporal.PlainDate(1979, 12, 31)).weekOfYear, 1); +assert.sameValue((new Temporal.PlainDate(1980, 1, 1)).weekOfYear, 1); +assert.sameValue((new Temporal.PlainDate(1980, 12, 28)).weekOfYear, 52); +assert.sameValue((new Temporal.PlainDate(1980, 12, 29)).weekOfYear, 1); +assert.sameValue((new Temporal.PlainDate(1980, 12, 30)).weekOfYear, 1); +assert.sameValue((new Temporal.PlainDate(1980, 12, 31)).weekOfYear, 1); +assert.sameValue((new Temporal.PlainDate(1981, 1, 1)).weekOfYear, 1); +assert.sameValue((new Temporal.PlainDate(1981, 12, 31)).weekOfYear, 53); +assert.sameValue((new Temporal.PlainDate(1982, 1, 1)).weekOfYear, 53); +assert.sameValue((new Temporal.PlainDate(1982, 1, 2)).weekOfYear, 53); +assert.sameValue((new Temporal.PlainDate(1982, 1, 3)).weekOfYear, 53); +assert.sameValue(Temporal.PlainDate.from('1977-01-01').weekOfYear, 53); +assert.sameValue(Temporal.PlainDate.from('1977-01-02').weekOfYear, 53); +assert.sameValue(Temporal.PlainDate.from('1977-12-31').weekOfYear, 52); +assert.sameValue(Temporal.PlainDate.from('1978-01-01').weekOfYear, 52); +assert.sameValue(Temporal.PlainDate.from('1978-01-02').weekOfYear, 1); +assert.sameValue(Temporal.PlainDate.from('1978-12-31').weekOfYear, 52); +assert.sameValue(Temporal.PlainDate.from('1979-01-01').weekOfYear, 1); +assert.sameValue(Temporal.PlainDate.from('1979-12-30').weekOfYear, 52); +assert.sameValue(Temporal.PlainDate.from('1979-12-31').weekOfYear, 1); +assert.sameValue(Temporal.PlainDate.from('1980-01-01').weekOfYear, 1); +assert.sameValue(Temporal.PlainDate.from('1980-12-28').weekOfYear, 52); +assert.sameValue(Temporal.PlainDate.from('1980-12-29').weekOfYear, 1); +assert.sameValue(Temporal.PlainDate.from('1980-12-30').weekOfYear, 1); +assert.sameValue(Temporal.PlainDate.from('1980-12-31').weekOfYear, 1); +assert.sameValue(Temporal.PlainDate.from('1981-01-01').weekOfYear, 1); +assert.sameValue(Temporal.PlainDate.from('1981-12-31').weekOfYear, 53); +assert.sameValue(Temporal.PlainDate.from('1982-01-01').weekOfYear, 53); +assert.sameValue(Temporal.PlainDate.from('1982-01-02').weekOfYear, 53); +assert.sameValue(Temporal.PlainDate.from('1982-01-03').weekOfYear, 53); diff --git a/test/staging/Temporal/v8/calendar-year-month-from-fields.js b/test/staging/Temporal/v8/calendar-year-month-from-fields.js new file mode 100644 index 0000000000..e2cd03d3aa --- /dev/null +++ b/test/staging/Temporal/v8/calendar-year-month-from-fields.js @@ -0,0 +1,226 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from calendar-year-month-from-fields test + in V8's mjsunit test calendar-year-month-from-fields.js +features: [Temporal] +---*/ + +assert.throws(TypeError, () => Temporal.PlainYearMonth.from()); +[ + undefined, + true, + false, + 123, + 456n, + Symbol(), +].forEach(function (fields) { + assert.throws(TypeError, () => Temporal.PlainYearMonth.from(fields)); + assert.throws(TypeError, () => Temporal.PlainYearMonth.from(fields, undefined)); + assert.throws(TypeError, () => Temporal.PlainYearMonth.from(fields, { overflow: 'constrain' })); + assert.throws(TypeError, () => Temporal.PlainYearMonth.from(fields, { overflow: 'reject' })); +}); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from('string')); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from('string', undefined)); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from('string', { overflow: 'constrain' })); +assert.throws(RangeError, () => Temporal.PlainMonthDay.from('string', { overflow: 'reject' })); +assert.throws(TypeError, () => Temporal.PlainYearMonth.from({ month: 1 })); +assert.throws(TypeError, () => Temporal.PlainYearMonth.from({ year: 2021 })); +assert.throws(RangeError, () => Temporal.PlainYearMonth.from({ + year: 2021, + monthCode: 'm1' +})); +assert.throws(RangeError, () => Temporal.PlainYearMonth.from({ + year: 2021, + monthCode: 'M1' +})); +assert.throws(RangeError, () => Temporal.PlainYearMonth.from({ + year: 2021, + monthCode: 'm01' +})); +assert.throws(RangeError, () => Temporal.PlainYearMonth.from({ + year: 2021, + month: 12, + monthCode: 'M11' +})); +assert.throws(RangeError, () => Temporal.PlainYearMonth.from({ + year: 2021, + monthCode: 'M00' +})); +assert.throws(RangeError, () => Temporal.PlainYearMonth.from({ + year: 2021, + monthCode: 'M19' +})); +assert.throws(RangeError, () => Temporal.PlainYearMonth.from({ + year: 2021, + monthCode: 'M99' +})); +assert.throws(RangeError, () => Temporal.PlainYearMonth.from({ + year: 2021, + monthCode: 'M13' +})); +assert.throws(RangeError, () => Temporal.PlainYearMonth.from({ + year: 2021, + month: -1 +})); +assert.throws(RangeError, () => Temporal.PlainYearMonth.from({ + year: 2021, + month: -Infinity +})); +assert.throws(RangeError, () => Temporal.PlainYearMonth.from({ + year: 2021, + month: 0, + day: 5 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainYearMonth.from({ + year: 2021, + month: 13, + day: 5 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainYearMonth.from({ + year: 2021, + monthCode: 'M00' +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainYearMonth.from({ + year: 2021, + monthCode: 'M13' +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainYearMonth.from({ + year: 2021, + month: 0 +})); +assert.throws(RangeError, () => Temporal.PlainYearMonth.from({ + year: 2021, + month: 7 +}, { overflow: 'invalid' })); +assert.sameValue(Temporal.PlainYearMonth.from({ + year: 2021, + month: 7 +}).toJSON(), '2021-07'); +assert.sameValue(Temporal.PlainYearMonth.from({ + year: 2021, + month: 12 +}).toJSON(), '2021-12'); +assert.sameValue(Temporal.PlainYearMonth.from({ + year: 2021, + monthCode: 'M07' +}).toJSON(), '2021-07'); +assert.sameValue(Temporal.PlainYearMonth.from({ + year: 2021, + monthCode: 'M12' +}).toJSON(), '2021-12'); +assert.sameValue(Temporal.PlainYearMonth.from({ + year: 2021, + month: 1 +}).toJSON(), '2021-01'); +assert.sameValue(Temporal.PlainYearMonth.from({ + year: 2021, + month: 2 +}).toJSON(), '2021-02'); +assert.sameValue(Temporal.PlainYearMonth.from({ + year: 2021, + month: 3 +}).toJSON(), '2021-03'); +assert.sameValue(Temporal.PlainYearMonth.from({ + year: 2021, + month: 4 +}).toJSON(), '2021-04'); +assert.sameValue(Temporal.PlainYearMonth.from({ + year: 2021, + month: 5 +}).toJSON(), '2021-05'); +assert.sameValue(Temporal.PlainYearMonth.from({ + year: 2021, + month: 6 +}).toJSON(), '2021-06'); +assert.sameValue(Temporal.PlainYearMonth.from({ + year: 2021, + month: 7 +}).toJSON(), '2021-07'); +assert.sameValue(Temporal.PlainYearMonth.from({ + year: 2021, + month: 8 +}).toJSON(), '2021-08'); +assert.sameValue(Temporal.PlainYearMonth.from({ + year: 2021, + month: 9 +}).toJSON(), '2021-09'); +assert.sameValue(Temporal.PlainYearMonth.from({ + year: 2021, + month: 10 +}).toJSON(), '2021-10'); +assert.sameValue(Temporal.PlainYearMonth.from({ + year: 2021, + month: 11 +}).toJSON(), '2021-11'); +assert.sameValue(Temporal.PlainYearMonth.from({ + year: 2021, + month: 12 +}).toJSON(), '2021-12'); +assert.sameValue(Temporal.PlainYearMonth.from({ + year: 2021, + month: 13 +}).toJSON(), '2021-12'); +assert.sameValue(Temporal.PlainYearMonth.from({ + year: 2021, + month: 999999 +}).toJSON(), '2021-12'); +assert.sameValue(Temporal.PlainYearMonth.from({ + year: 2021, + monthCode: 'M01' +}).toJSON(), '2021-01'); +assert.sameValue(Temporal.PlainYearMonth.from({ + year: 2021, + monthCode: 'M02' +}).toJSON(), '2021-02'); +assert.sameValue(Temporal.PlainYearMonth.from({ + year: 2021, + monthCode: 'M03' +}).toJSON(), '2021-03'); +assert.sameValue(Temporal.PlainYearMonth.from({ + year: 2021, + monthCode: 'M04' +}).toJSON(), '2021-04'); +assert.sameValue(Temporal.PlainYearMonth.from({ + year: 2021, + monthCode: 'M05' +}).toJSON(), '2021-05'); +assert.sameValue(Temporal.PlainYearMonth.from({ + year: 2021, + monthCode: 'M06' +}).toJSON(), '2021-06'); +assert.sameValue(Temporal.PlainYearMonth.from({ + year: 2021, + monthCode: 'M07' +}).toJSON(), '2021-07'); +assert.sameValue(Temporal.PlainYearMonth.from({ + year: 2021, + monthCode: 'M08' +}).toJSON(), '2021-08'); +assert.sameValue(Temporal.PlainYearMonth.from({ + year: 2021, + monthCode: 'M09' +}).toJSON(), '2021-09'); +assert.sameValue(Temporal.PlainYearMonth.from({ + year: 2021, + monthCode: 'M10' +}).toJSON(), '2021-10'); +assert.sameValue(Temporal.PlainYearMonth.from({ + year: 2021, + monthCode: 'M11' +}).toJSON(), '2021-11'); +assert.sameValue(Temporal.PlainYearMonth.from({ + year: 2021, + monthCode: 'M12' +}).toJSON(), '2021-12'); +assert.throws(RangeError, () => Temporal.PlainYearMonth.from({ + year: 2021, + month: 13 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainYearMonth.from({ + year: 2021, + month: 9995 +}, { overflow: 'reject' })); diff --git a/test/staging/Temporal/v8/calendar-year.js b/test/staging/Temporal/v8/calendar-year.js new file mode 100644 index 0000000000..c5705b5e72 --- /dev/null +++ b/test/staging/Temporal/v8/calendar-year.js @@ -0,0 +1,15 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from calendar-year test + in V8's mjsunit test calendar-year.js +features: [Temporal] +---*/ + +assert.sameValue((new Temporal.PlainDate(2021, 7, 15)).year, 2021); +assert.sameValue((new Temporal.PlainDateTime(1997, 8, 23, 5, 30, 13)).year, 1997); +assert.sameValue((new Temporal.PlainYearMonth(1999, 6)).year, 1999); +assert.sameValue(Temporal.PlainDate.from('2019-03-15').year, 2019); diff --git a/test/staging/Temporal/v8/duration-abs.js b/test/staging/Temporal/v8/duration-abs.js new file mode 100644 index 0000000000..13927e59c9 --- /dev/null +++ b/test/staging/Temporal/v8/duration-abs.js @@ -0,0 +1,20 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from duration-abs test + in V8's mjsunit test duration-abs.js +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +let d1 = new Temporal.Duration(); +TemporalHelpers.assertDuration(d1.abs(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); +let d2 = new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); +TemporalHelpers.assertDuration(d2.abs(), 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); +let d3 = new Temporal.Duration(100000, 200000, 300000, 400000, 500000, 600000, 700000, 800000, 900000, 1000000); +TemporalHelpers.assertDuration(d3.abs(), 100000, 200000, 300000, 400000, 500000, 600000, 700000, 800000, 900000, 1000000); +let d4 = new Temporal.Duration(-1, -2, -3, -4, -5, -6, -7, -8, -9, -10); +TemporalHelpers.assertDuration(d4.abs(), 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); diff --git a/test/staging/Temporal/v8/duration-add.js b/test/staging/Temporal/v8/duration-add.js new file mode 100644 index 0000000000..4fc7fe84b1 --- /dev/null +++ b/test/staging/Temporal/v8/duration-add.js @@ -0,0 +1,26 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from duration-add test + in V8's mjsunit test duration-add.js +features: [Temporal] +---*/ + +let d1 = new Temporal.Duration(); +let badDur = { add: d1.add }; +assert.throws(TypeError, () => badDur.add(d1)); +let d2 = new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); +assert.throws(RangeError, () => d2.add(d1)); +assert.throws(RangeError, () => d1.add(d2)); +assert.throws(RangeError, () => d2.add(d2)); +let d3 = new Temporal.Duration(100000, 200000, 300000, 400000, 500000, 600000, 700000, 800000, 900000, 1000000); +assert.throws(RangeError, () => d3.add(d3)); +let d4 = new Temporal.Duration(-1, -2, -3, -4, -5, -6, -7, -8, -9, -10); +assert.throws(RangeError, () => d4.add(d1)); +assert.throws(RangeError, () => d1.add(d4)); +assert.throws(RangeError, () => d4.add(d4)); +assert.throws(RangeError, () => d2.add(d4)); +assert.throws(RangeError, () => d4.add(d2)); diff --git a/test/staging/Temporal/v8/duration-constructor.js b/test/staging/Temporal/v8/duration-constructor.js new file mode 100644 index 0000000000..8b85c147bf --- /dev/null +++ b/test/staging/Temporal/v8/duration-constructor.js @@ -0,0 +1,49 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from duration-constructor test + in V8's mjsunit test duration-constructor.js +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +let d1 = new Temporal.Duration(); +TemporalHelpers.assertDuration(d1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); +let d2 = new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); +TemporalHelpers.assertDuration(d2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); +let d3 = new Temporal.Duration(100000, 200000, 300000, 400000, 500000, 600000, 700000, 800000, 900000, 1000000); +TemporalHelpers.assertDuration(d3, 100000, 200000, 300000, 400000, 500000, 600000, 700000, 800000, 900000, 1000000); +let d4 = new Temporal.Duration(-1, -2, -3, -4, -5, -6, -7, -8, -9, -10); +TemporalHelpers.assertDuration(d4, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10); +assert.throws(TypeError, () => Temporal.Duration()); +TemporalHelpers.assertDuration(new Temporal.Duration(undefined, 234, true, false, '567'), 0, 234, 1, 0, 567, 0, 0, 0, 0, 0); +assert.throws(TypeError, () => new Temporal.Duration(Symbol(123))); +assert.throws(TypeError, () => new Temporal.Duration(123n)); +assert.throws(RangeError, () => new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, 8, 9, Infinity)); +assert.throws(RangeError, () => new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, 8, Infinity)); +assert.throws(RangeError, () => new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, Infinity)); +assert.throws(RangeError, () => new Temporal.Duration(1, 2, 3, 4, 5, 6, Infinity)); +assert.throws(RangeError, () => new Temporal.Duration(1, 2, 3, 4, 5, Infinity)); +assert.throws(RangeError, () => new Temporal.Duration(1, 2, 3, 4, Infinity)); +assert.throws(RangeError, () => new Temporal.Duration(1, 2, 3, Infinity)); +assert.throws(RangeError, () => new Temporal.Duration(1, 2, Infinity)); +assert.throws(RangeError, () => new Temporal.Duration(1, Infinity)); +assert.throws(RangeError, () => new Temporal.Duration(Infinity)); +assert.throws(RangeError, () => new Temporal.Duration(-1, -2, -3, -4, -5, -6, -7, -8, -9, -Infinity)); +assert.throws(RangeError, () => new Temporal.Duration(-1, -2, -3, -4, -5, -6, -7, -8, -Infinity)); +assert.throws(RangeError, () => new Temporal.Duration(-1, -2, -3, -4, -5, -6, -7, -Infinity)); +assert.throws(RangeError, () => new Temporal.Duration(-1, -2, -3, -4, -5, -6, -Infinity)); +assert.throws(RangeError, () => new Temporal.Duration(-1, -2, -3, -4, -5, -Infinity)); +assert.throws(RangeError, () => new Temporal.Duration(-1, -2, -3, -4, -Infinity)); +assert.throws(RangeError, () => new Temporal.Duration(-1, -2, -3, -Infinity)); +assert.throws(RangeError, () => new Temporal.Duration(-1, -2, -Infinity)); +assert.throws(RangeError, () => new Temporal.Duration(-1, -Infinity)); +assert.throws(RangeError, () => new Temporal.Duration(-Infinity)); +assert.throws(RangeError, () => new Temporal.Duration(1, -2)); +assert.throws(RangeError, () => new Temporal.Duration(1, 0, -2)); +assert.throws(RangeError, () => new Temporal.Duration(-1, 0, 0, 3)); +assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, 1, -1)); +assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, -1, 1)); diff --git a/test/staging/Temporal/v8/duration-from.js b/test/staging/Temporal/v8/duration-from.js new file mode 100644 index 0000000000..895aec6d72 --- /dev/null +++ b/test/staging/Temporal/v8/duration-from.js @@ -0,0 +1,143 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from duration-from test + in V8's mjsunit test duration-from.js +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +let d1 = new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); +TemporalHelpers.assertDuration(d1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); +let d2 = Temporal.Duration.from(d1); +TemporalHelpers.assertDuration(d2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); +assert.notSameValue(d2, d1); +TemporalHelpers.assertDuration(Temporal.Duration.from('PT0S'), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('P1Y'), 1, 0, 0, 0, 0, 0, 0, 0, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('P2M'), 0, 2, 0, 0, 0, 0, 0, 0, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('P3W'), 0, 0, 3, 0, 0, 0, 0, 0, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('P4D'), 0, 0, 0, 4, 0, 0, 0, 0, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('PT5H'), 0, 0, 0, 0, 5, 0, 0, 0, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('PT6M'), 0, 0, 0, 0, 0, 6, 0, 0, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('PT7S'), 0, 0, 0, 0, 0, 0, 7, 0, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('PT0.008S'), 0, 0, 0, 0, 0, 0, 0, 8, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('PT0.000009S'), 0, 0, 0, 0, 0, 0, 0, 0, 9, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('PT0.000000001S'), 0, 0, 0, 0, 0, 0, 0, 0, 0, 1); +TemporalHelpers.assertDuration(Temporal.Duration.from('P1Y2M3W4DT5H6M7.008009001S'), 1, 2, 3, 4, 5, 6, 7, 8, 9, 1); +TemporalHelpers.assertDuration(Temporal.Duration.from('P111111111Y222222222M333333333W444444444D' + 'T555555555H666666666M777777777.987654321S'), 111111111, 222222222, 333333333, 444444444, 555555555, 666666666, 777777777, 987, 654, 321); +TemporalHelpers.assertDuration(Temporal.Duration.from('P1Y3WT5H7.000009001S'), 1, 0, 3, 0, 5, 0, 7, 0, 9, 1); +TemporalHelpers.assertDuration(Temporal.Duration.from('P2M4DT6M0.008000001S'), 0, 2, 0, 4, 0, 6, 0, 8, 0, 1); +TemporalHelpers.assertDuration(Temporal.Duration.from('P1Y4DT7.000000001S'), 1, 0, 0, 4, 0, 0, 7, 0, 0, 1); +TemporalHelpers.assertDuration(Temporal.Duration.from('P2MT5H0.008S'), 0, 2, 0, 0, 5, 0, 0, 8, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('P3WT6M0.000009S'), 0, 0, 3, 0, 0, 6, 0, 0, 9, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('P1YT5H0.000009000S'), 1, 0, 0, 0, 5, 0, 0, 0, 9, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('P2MT6M0.000000001S'), 0, 2, 0, 0, 0, 6, 0, 0, 0, 1); +TemporalHelpers.assertDuration(Temporal.Duration.from('P3WT7S'), 0, 0, 3, 0, 0, 0, 7, 0, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('P4DT0.008S'), 0, 0, 0, 4, 0, 0, 0, 8, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('P1YT5H0.000000001S'), 1, 0, 0, 0, 5, 0, 0, 0, 0, 1); +TemporalHelpers.assertDuration(Temporal.Duration.from('P2MT6M'), 0, 2, 0, 0, 0, 6, 0, 0, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('P3WT7S'), 0, 0, 3, 0, 0, 0, 7, 0, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('P4DT0.008S'), 0, 0, 0, 4, 0, 0, 0, 8, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('PT5H0.000009S'), 0, 0, 0, 0, 5, 0, 0, 0, 9, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('P1YT6M'), 1, 0, 0, 0, 0, 6, 0, 0, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('P2MT7S'), 0, 2, 0, 0, 0, 0, 7, 0, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('P3WT0.008S'), 0, 0, 3, 0, 0, 0, 0, 8, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('P4DT0.000009S'), 0, 0, 0, 4, 0, 0, 0, 0, 9, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('PT5H0.000000001S'), 0, 0, 0, 0, 5, 0, 0, 0, 0, 1); +TemporalHelpers.assertDuration(Temporal.Duration.from('P1YT7S'), 1, 0, 0, 0, 0, 0, 7, 0, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('P2MT0.008S'), 0, 2, 0, 0, 0, 0, 0, 8, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('P3WT0.000009S'), 0, 0, 3, 0, 0, 0, 0, 0, 9, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('P4DT0.000000001S'), 0, 0, 0, 4, 0, 0, 0, 0, 0, 1); +TemporalHelpers.assertDuration(Temporal.Duration.from('PT5H'), 0, 0, 0, 0, 5, 0, 0, 0, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('-P1Y2M3W4DT5H6M7.008009001S'), -1, -2, -3, -4, -5, -6, -7, -8, -9, -1); +TemporalHelpers.assertDuration(Temporal.Duration.from('-P111111111Y222222222M333333333W444444444D' + 'T555555555H666666666M777777777.987654321S'), -111111111, -222222222, -333333333, -444444444, -555555555, -666666666, -777777777, -987, -654, -321); +TemporalHelpers.assertDuration(Temporal.Duration.from('+P1Y2M3W4DT5H6M7.008009001S'), 1, 2, 3, 4, 5, 6, 7, 8, 9, 1); +TemporalHelpers.assertDuration(Temporal.Duration.from('PT2.5H'), 0, 0, 0, 0, 2, 30, 0, 0, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('PT2.25H'), 0, 0, 0, 0, 2, 15, 0, 0, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('PT2.05H'), 0, 0, 0, 0, 2, 3, 0, 0, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('PT2.005H'), 0, 0, 0, 0, 2, 0, 18, 0, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('PT2.505H'), 0, 0, 0, 0, 2, 30, 18, 0, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('PT2.0025H'), 0, 0, 0, 0, 2, 0, 9, 0, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('PT3.5M'), 0, 0, 0, 0, 0, 3, 30, 0, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('PT3.25M'), 0, 0, 0, 0, 0, 3, 15, 0, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('PT3.125M'), 0, 0, 0, 0, 0, 3, 7, 500, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('PT3.025M'), 0, 0, 0, 0, 0, 3, 1, 500, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('PT3.01M'), 0, 0, 0, 0, 0, 3, 0, 600, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('PT3.005M'), 0, 0, 0, 0, 0, 3, 0, 300, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('PT3.001M'), 0, 0, 0, 0, 0, 3, 0, 60, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('PT3.006M'), 0, 0, 0, 0, 0, 3, 0, 360, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('PT2,5H'), 0, 0, 0, 0, 2, 30, 0, 0, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('PT2,25H'), 0, 0, 0, 0, 2, 15, 0, 0, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('PT2,05H'), 0, 0, 0, 0, 2, 3, 0, 0, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('PT2,005H'), 0, 0, 0, 0, 2, 0, 18, 0, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('PT2,505H'), 0, 0, 0, 0, 2, 30, 18, 0, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('PT2,0025H'), 0, 0, 0, 0, 2, 0, 9, 0, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('PT3,5M'), 0, 0, 0, 0, 0, 3, 30, 0, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('PT3,25M'), 0, 0, 0, 0, 0, 3, 15, 0, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('PT3,125M'), 0, 0, 0, 0, 0, 3, 7, 500, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('PT3,025M'), 0, 0, 0, 0, 0, 3, 1, 500, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('PT3,01M'), 0, 0, 0, 0, 0, 3, 0, 600, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('PT3,005M'), 0, 0, 0, 0, 0, 3, 0, 300, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('PT3,001M'), 0, 0, 0, 0, 0, 3, 0, 60, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('PT3,006M'), 0, 0, 0, 0, 0, 3, 0, 360, 0, 0); +assert.throws(RangeError, () => Temporal.Duration.from('P2H')); +assert.throws(RangeError, () => Temporal.Duration.from('P2.5M')); +assert.throws(RangeError, () => Temporal.Duration.from('P2,5M')); +assert.throws(RangeError, () => Temporal.Duration.from('P2S')); +assert.throws(RangeError, () => Temporal.Duration.from('PT2.H3M')); +assert.throws(RangeError, () => Temporal.Duration.from('PT2,H3M')); +assert.throws(RangeError, () => Temporal.Duration.from('PT2.H3S')); +assert.throws(RangeError, () => Temporal.Duration.from('PT2,H3S')); +assert.throws(RangeError, () => Temporal.Duration.from('PT2.H0.5M')); +assert.throws(RangeError, () => Temporal.Duration.from('PT2,H0,5M')); +assert.throws(RangeError, () => Temporal.Duration.from('PT2.H0.5S')); +assert.throws(RangeError, () => Temporal.Duration.from('PT2,H0,5S')); +assert.throws(RangeError, () => Temporal.Duration.from('PT2H3.2M3S')); +assert.throws(RangeError, () => Temporal.Duration.from('PT2H3,2M3S')); +assert.throws(RangeError, () => Temporal.Duration.from('PT2H3.2M0.3S')); +assert.throws(RangeError, () => Temporal.Duration.from('PT2H3,2M0,3S')); +assert.throws(RangeError, () => Temporal.Duration.from('PT.1H')); +assert.throws(RangeError, () => Temporal.Duration.from('PT,1H')); +assert.throws(RangeError, () => Temporal.Duration.from('PT.1M')); +assert.throws(RangeError, () => Temporal.Duration.from('PT,1M')); +assert.throws(RangeError, () => Temporal.Duration.from('PT.1S')); +assert.throws(RangeError, () => Temporal.Duration.from('PT,1S')); +TemporalHelpers.assertDuration(Temporal.Duration.from({ + years: 0, + months: 0, + weeks: 0, + days: 0, + hours: 0, + minutes: 0, + seconds: 0, + milliseconds: 0, + microseconds: 0, + nanoseconds: 0 +}), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from({ + years: 1, + months: 2, + weeks: 3, + days: 4, + hours: 5, + minutes: 6, + seconds: 7, + milliseconds: 8, + microseconds: 9, + nanoseconds: 10 +}), 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); +TemporalHelpers.assertDuration(Temporal.Duration.from({ + years: -1, + months: -2, + weeks: -3, + days: -4, + hours: -5, + minutes: -6, + seconds: -7, + milliseconds: -8, + microseconds: -9, + nanoseconds: -10 +}), -1, -2, -3, -4, -5, -6, -7, -8, -9, -10); diff --git a/test/staging/Temporal/v8/duration-negated.js b/test/staging/Temporal/v8/duration-negated.js new file mode 100644 index 0000000000..83756016cd --- /dev/null +++ b/test/staging/Temporal/v8/duration-negated.js @@ -0,0 +1,22 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from duration-negated test + in V8's mjsunit test duration-negated.js +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +let d1 = new Temporal.Duration(); +TemporalHelpers.assertDuration(d1.negated(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); +let d2 = new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); +TemporalHelpers.assertDuration(d2.negated(), -1, -2, -3, -4, -5, -6, -7, -8, -9, -10); +let d3 = new Temporal.Duration(100000, 200000, 300000, 400000, 500000, 600000, 700000, 800000, 900000, 1000000); +TemporalHelpers.assertDuration(d3.negated(), -100000, -200000, -300000, -400000, -500000, -600000, -700000, -800000, -900000, -1000000); +let d4 = new Temporal.Duration(-1, -2, -3, -4, -5, -6, -7, -8, -9, -10); +TemporalHelpers.assertDuration(d4.negated(), 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); +let d5 = new Temporal.Duration(-100000, -200000, -300000, -400000, -500000, -600000, -700000, -800000, -900000, -1000000); +TemporalHelpers.assertDuration(d5.negated(), 100000, 200000, 300000, 400000, 500000, 600000, 700000, 800000, 900000, 1000000); diff --git a/test/staging/Temporal/v8/duration-to-json-boundary-cases.js b/test/staging/Temporal/v8/duration-to-json-boundary-cases.js new file mode 100644 index 0000000000..5de81c3952 --- /dev/null +++ b/test/staging/Temporal/v8/duration-to-json-boundary-cases.js @@ -0,0 +1,66 @@ +// Copyright 2022 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from duration-to-json-boundary-cases test + in V8's mjsunit test duration-to-json-boundary-cases.js +features: [Temporal] +---*/ + +let MAX_UINT32 = Math.pow(2, 32); +assert.throws(RangeError, () => new Temporal.Duration(MAX_UINT32)); +assert.throws(RangeError, () => new Temporal.Duration(-MAX_UINT32)); +assert.throws(RangeError, () => new Temporal.Duration(0, MAX_UINT32)); +assert.throws(RangeError, () => new Temporal.Duration(0, -MAX_UINT32)); +assert.throws(RangeError, () => new Temporal.Duration(0, 0, MAX_UINT32)); +assert.throws(RangeError, () => new Temporal.Duration(0, 0, -MAX_UINT32)); +assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, Number.MAX_SAFE_INTEGER / 86400 + 1)); +assert.sameValue(new Temporal.Duration(0, 0, 0, Math.floor(Number.MAX_SAFE_INTEGER / 86400)).toJSON(), 'P' + Math.floor(Number.MAX_SAFE_INTEGER / 86400) + 'D'); +assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, -(Number.MAX_SAFE_INTEGER / 86400 + 1))); +assert.sameValue(new Temporal.Duration(0, 0, 0, -Math.floor(Number.MAX_SAFE_INTEGER / 86400)).toJSON(), '-P' + Math.floor(Number.MAX_SAFE_INTEGER / 86400) + 'D'); +assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, 0, Number.MAX_SAFE_INTEGER / 3600 + 1)); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, Math.floor(Number.MAX_SAFE_INTEGER / 3600)).toJSON(), 'PT' + Math.floor(Number.MAX_SAFE_INTEGER / 3600) + 'H'); +assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, 0, -(Number.MAX_SAFE_INTEGER / 3600 + 1))); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, -Math.floor(Number.MAX_SAFE_INTEGER / 3600)).toJSON(), '-PT' + Math.floor(Number.MAX_SAFE_INTEGER / 3600) + 'H'); +assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, 0, 0, Number.MAX_SAFE_INTEGER / 60 + 1)); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, Math.floor(Number.MAX_SAFE_INTEGER / 60)).toJSON(), 'PT' + Math.floor(Number.MAX_SAFE_INTEGER / 60) + 'M'); +assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, 0, 0, -(Number.MAX_SAFE_INTEGER / 60 + 1))); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, -Math.floor(Number.MAX_SAFE_INTEGER / 60)).toJSON(), '-PT' + Math.floor(Number.MAX_SAFE_INTEGER / 60) + 'M'); +assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, 0, 0, 0, Number.MAX_SAFE_INTEGER + 1)); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, Number.MAX_SAFE_INTEGER).toJSON(), 'PT' + Number.MAX_SAFE_INTEGER + 'S'); +assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, 0, 0, 0, -(Number.MAX_SAFE_INTEGER + 1))); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, -Number.MAX_SAFE_INTEGER).toJSON(), '-PT' + Number.MAX_SAFE_INTEGER + 'S'); +assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, 0, 0, 0, Number.MAX_SAFE_INTEGER, 1000)); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, Number.MAX_SAFE_INTEGER, 999).toJSON(), 'PT' + Number.MAX_SAFE_INTEGER + '.999S'); +assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, 0, 0, 0, -Number.MAX_SAFE_INTEGER, -1000)); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, -Number.MAX_SAFE_INTEGER, -999).toJSON(), '-PT' + Number.MAX_SAFE_INTEGER + '.999S'); +assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, 0, 0, 0, Number.MAX_SAFE_INTEGER, 999, 1000)); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, Number.MAX_SAFE_INTEGER, 999, 999).toJSON(), 'PT' + Number.MAX_SAFE_INTEGER + '.999999S'); +assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, 0, 0, 0, -Number.MAX_SAFE_INTEGER, -999, -1000)); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, -Number.MAX_SAFE_INTEGER, -999, -999).toJSON(), '-PT' + Number.MAX_SAFE_INTEGER + '.999999S'); +assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, 0, 0, 0, Number.MAX_SAFE_INTEGER, 999, 999, 1000)); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, Number.MAX_SAFE_INTEGER, 999, 999, 999).toJSON(), 'PT' + Number.MAX_SAFE_INTEGER + '.999999999S'); +assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, 0, 0, 0, -Number.MAX_SAFE_INTEGER, -999, -999, -1000)); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, -Number.MAX_SAFE_INTEGER, -999, -999, -999).toJSON(), '-PT' + Number.MAX_SAFE_INTEGER + '.999999999S'); +assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, 0, 0, 0, Number.MAX_SAFE_INTEGER - Math.floor(Number.MAX_SAFE_INTEGER / 1000) + 1, Number.MAX_SAFE_INTEGER, 0, 0)); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, Number.MAX_SAFE_INTEGER - Math.floor(Number.MAX_SAFE_INTEGER / 1000), Number.MAX_SAFE_INTEGER, 0, 0).toJSON(), 'PT' + Number.MAX_SAFE_INTEGER + '.' + Number.MAX_SAFE_INTEGER % 1000 + 'S'); +assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, 0, 0, 0, -(Number.MAX_SAFE_INTEGER - Math.floor(Number.MAX_SAFE_INTEGER / 1000) + 1), -Number.MAX_SAFE_INTEGER, 0, 0)); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, -(Number.MAX_SAFE_INTEGER - Math.floor(Number.MAX_SAFE_INTEGER / 1000)), -Number.MAX_SAFE_INTEGER, 0, 0).toJSON(), '-PT' + Number.MAX_SAFE_INTEGER + '.' + Number.MAX_SAFE_INTEGER % 1000 + 'S'); +assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, 0, 0, 0, Number.MAX_SAFE_INTEGER - Math.floor(Number.MAX_SAFE_INTEGER / 1000000) + 1, 0, Number.MAX_SAFE_INTEGER, 0)); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, Number.MAX_SAFE_INTEGER - Math.floor(Number.MAX_SAFE_INTEGER / 1000000), 0, Number.MAX_SAFE_INTEGER, 0).toJSON(), 'PT' + Number.MAX_SAFE_INTEGER + '.' + Number.MAX_SAFE_INTEGER % 1000000 + 'S'); +assert.sameValue(new Temporal.Duration(MAX_UINT32 - 1).toJSON(), 'P' + (MAX_UINT32 - 1) + 'Y'); +assert.sameValue(new Temporal.Duration(-(MAX_UINT32 - 1)).toJSON(), '-P' + (MAX_UINT32 - 1) + 'Y'); +assert.sameValue(new Temporal.Duration(0, MAX_UINT32 - 1).toJSON(), 'P' + (MAX_UINT32 - 1) + 'M'); +assert.sameValue(new Temporal.Duration(0, -(MAX_UINT32 - 1)).toJSON(), '-P' + (MAX_UINT32 - 1) + 'M'); +assert.sameValue(new Temporal.Duration(0, 0, MAX_UINT32 - 1).toJSON(), 'P' + (MAX_UINT32 - 1) + 'W'); +assert.sameValue(new Temporal.Duration(0, 0, -(MAX_UINT32 - 1)).toJSON(), '-P' + (MAX_UINT32 - 1) + 'W'); +assert.sameValue(new Temporal.Duration(0, 0, 0, MAX_UINT32 - 1).toJSON(), 'P' + (MAX_UINT32 - 1) + 'D'); +assert.sameValue(new Temporal.Duration(0, 0, 0, -(MAX_UINT32 - 1)).toJSON(), '-P' + (MAX_UINT32 - 1) + 'D'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, MAX_UINT32 - 1).toJSON(), 'PT' + (MAX_UINT32 - 1) + 'H'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, -(MAX_UINT32 - 1)).toJSON(), '-PT' + (MAX_UINT32 - 1) + 'H'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, MAX_UINT32 - 1).toJSON(), 'PT' + (MAX_UINT32 - 1) + 'M'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, -(MAX_UINT32 - 1)).toJSON(), '-PT' + (MAX_UINT32 - 1) + 'M'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, MAX_UINT32 - 1).toJSON(), 'PT' + (MAX_UINT32 - 1) + 'S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, -(MAX_UINT32 - 1)).toJSON(), '-PT' + (MAX_UINT32 - 1) + 'S'); diff --git a/test/staging/Temporal/v8/duration-to-json.js b/test/staging/Temporal/v8/duration-to-json.js new file mode 100644 index 0000000000..a811934679 --- /dev/null +++ b/test/staging/Temporal/v8/duration-to-json.js @@ -0,0 +1,118 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from duration-to-json test + in V8's mjsunit test duration-to-json.js +features: [Temporal] +---*/ + +assert.sameValue(new Temporal.Duration().toJSON(), 'PT0S'); +assert.sameValue(new Temporal.Duration(1).toJSON(), 'P1Y'); +assert.sameValue(new Temporal.Duration(-1).toJSON(), '-P1Y'); +assert.sameValue(new Temporal.Duration(1234567890).toJSON(), 'P1234567890Y'); +assert.sameValue(new Temporal.Duration(-1234567890).toJSON(), '-P1234567890Y'); +assert.sameValue(new Temporal.Duration(1, 2).toJSON(), 'P1Y2M'); +assert.sameValue(new Temporal.Duration(-1, -2).toJSON(), '-P1Y2M'); +assert.sameValue(new Temporal.Duration(0, 2).toJSON(), 'P2M'); +assert.sameValue(new Temporal.Duration(0, -2).toJSON(), '-P2M'); +assert.sameValue(new Temporal.Duration(0, 1234567890).toJSON(), 'P1234567890M'); +assert.sameValue(new Temporal.Duration(0, -1234567890).toJSON(), '-P1234567890M'); +assert.sameValue(new Temporal.Duration(1, 2, 3).toJSON(), 'P1Y2M3W'); +assert.sameValue(new Temporal.Duration(-1, -2, -3).toJSON(), '-P1Y2M3W'); +assert.sameValue(new Temporal.Duration(0, 0, 3).toJSON(), 'P3W'); +assert.sameValue(new Temporal.Duration(0, 0, -3).toJSON(), '-P3W'); +assert.sameValue(new Temporal.Duration(1, 0, 3).toJSON(), 'P1Y3W'); +assert.sameValue(new Temporal.Duration(-1, 0, -3).toJSON(), '-P1Y3W'); +assert.sameValue(new Temporal.Duration(0, 2, 3).toJSON(), 'P2M3W'); +assert.sameValue(new Temporal.Duration(0, -2, -3).toJSON(), '-P2M3W'); +assert.sameValue(new Temporal.Duration(0, 0, 1234567890).toJSON(), 'P1234567890W'); +assert.sameValue(new Temporal.Duration(0, 0, -1234567890).toJSON(), '-P1234567890W'); +assert.sameValue(new Temporal.Duration(1, 2, 3, 4).toJSON(), 'P1Y2M3W4D'); +assert.sameValue(new Temporal.Duration(-1, -2, -3, -4).toJSON(), '-P1Y2M3W4D'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 1234567890).toJSON(), 'P1234567890D'); +assert.sameValue(new Temporal.Duration(0, 0, 0, -1234567890).toJSON(), '-P1234567890D'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 4).toJSON(), 'P4D'); +assert.sameValue(new Temporal.Duration(0, 0, 0, -4).toJSON(), '-P4D'); +assert.sameValue(new Temporal.Duration(1, 0, 0, 4).toJSON(), 'P1Y4D'); +assert.sameValue(new Temporal.Duration(-1, 0, 0, -4).toJSON(), '-P1Y4D'); +assert.sameValue(new Temporal.Duration(0, 2, 0, 4).toJSON(), 'P2M4D'); +assert.sameValue(new Temporal.Duration(0, -2, 0, -4).toJSON(), '-P2M4D'); +assert.sameValue(new Temporal.Duration(0, 0, 3, 4).toJSON(), 'P3W4D'); +assert.sameValue(new Temporal.Duration(0, 0, -3, -4).toJSON(), '-P3W4D'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 5).toJSON(), 'PT5H'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, -5).toJSON(), '-PT5H'); +assert.sameValue(new Temporal.Duration(1, 0, 0, 0, 5).toJSON(), 'P1YT5H'); +assert.sameValue(new Temporal.Duration(-1, 0, 0, 0, -5).toJSON(), '-P1YT5H'); +assert.sameValue(new Temporal.Duration(0, 2, 0, 0, 5).toJSON(), 'P2MT5H'); +assert.sameValue(new Temporal.Duration(0, -2, 0, 0, -5).toJSON(), '-P2MT5H'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 6).toJSON(), 'PT6M'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, -6).toJSON(), '-PT6M'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 5, 6).toJSON(), 'PT5H6M'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, -5, -6).toJSON(), '-PT5H6M'); +assert.sameValue(new Temporal.Duration(0, 0, 3, 0, 0, 6).toJSON(), 'P3WT6M'); +assert.sameValue(new Temporal.Duration(0, 0, -3, 0, 0, -6).toJSON(), '-P3WT6M'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 4, 0, 6).toJSON(), 'P4DT6M'); +assert.sameValue(new Temporal.Duration(0, 0, 0, -4, 0, -6).toJSON(), '-P4DT6M'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 7).toJSON(), 'PT7S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, -7).toJSON(), '-PT7S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 5, 0, 7).toJSON(), 'PT5H7S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, -5, 0, -7).toJSON(), '-PT5H7S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 6, 7).toJSON(), 'PT6M7S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, -6, -7).toJSON(), '-PT6M7S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 5, 6, 7).toJSON(), 'PT5H6M7S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, -5, -6, -7).toJSON(), '-PT5H6M7S'); +assert.sameValue(new Temporal.Duration(1, 0, 0, 0, 5, 6, 7).toJSON(), 'P1YT5H6M7S'); +assert.sameValue(new Temporal.Duration(-1, 0, 0, 0, -5, -6, -7).toJSON(), '-P1YT5H6M7S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 8).toJSON(), 'PT0.008S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, -8).toJSON(), '-PT0.008S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 80).toJSON(), 'PT0.08S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, -80).toJSON(), '-PT0.08S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 87).toJSON(), 'PT0.087S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, -87).toJSON(), '-PT0.087S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 876).toJSON(), 'PT0.876S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, -876).toJSON(), '-PT0.876S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 876543).toJSON(), 'PT876.543S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, -876543).toJSON(), '-PT876.543S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, 9).toJSON(), 'PT0.000009S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, -9).toJSON(), '-PT0.000009S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, 90).toJSON(), 'PT0.00009S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, -90).toJSON(), '-PT0.00009S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, 98).toJSON(), 'PT0.000098S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, -98).toJSON(), '-PT0.000098S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, 900).toJSON(), 'PT0.0009S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, -900).toJSON(), '-PT0.0009S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, 987).toJSON(), 'PT0.000987S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, -987).toJSON(), '-PT0.000987S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, 987654).toJSON(), 'PT0.987654S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, -987654).toJSON(), '-PT0.987654S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, 987654321).toJSON(), 'PT987.654321S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, -987654321).toJSON(), '-PT987.654321S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, 0, 1).toJSON(), 'PT0.000000001S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, 0, -1).toJSON(), '-PT0.000000001S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, 0, 10).toJSON(), 'PT0.00000001S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, 0, -10).toJSON(), '-PT0.00000001S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, 0, 12).toJSON(), 'PT0.000000012S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, 0, -12).toJSON(), '-PT0.000000012S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, 0, 100).toJSON(), 'PT0.0000001S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, 0, -100).toJSON(), '-PT0.0000001S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, 0, 123).toJSON(), 'PT0.000000123S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, 0, -123).toJSON(), '-PT0.000000123S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, 0, 123456).toJSON(), 'PT0.000123456S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, 0, -123456).toJSON(), '-PT0.000123456S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, 0, 123456789).toJSON(), 'PT0.123456789S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, 0, -123456789).toJSON(), '-PT0.123456789S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, 0, 1234567891).toJSON(), 'PT1.234567891S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, 0, -1234567891).toJSON(), '-PT1.234567891S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 4, 3, 2, 1).toJSON(), 'PT4.003002001S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, -4, -3, -2, -1).toJSON(), '-PT4.003002001S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 4, 3, 2, 90001).toJSON(), 'PT4.003092001S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, -4, -3, -2, -90001).toJSON(), '-PT4.003092001S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, 4, 3, 2, 90080001).toJSON(), 'PT4.093082001S'); +assert.sameValue(new Temporal.Duration(0, 0, 0, 0, 0, 0, -4, -3, -2, -90080001).toJSON(), '-PT4.093082001S'); +assert.sameValue(new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, 8, 9, 1).toJSON(), 'P1Y2M3W4DT5H6M7.008009001S'); +assert.sameValue(new Temporal.Duration(-1, -2, -3, -4, -5, -6, -7, -8, -9, -1).toJSON(), '-P1Y2M3W4DT5H6M7.008009001S'); +assert.sameValue(new Temporal.Duration(1234, 2345, 3456, 4567, 5678, 6789, 7890, 890, 901, 123).toJSON(), 'P1234Y2345M3456W4567DT5678H6789M7890.890901123S'); +assert.sameValue(new Temporal.Duration(-1234, -2345, -3456, -4567, -5678, -6789, -7890, -890, -901, -123).toJSON(), '-P1234Y2345M3456W4567DT5678H6789M7890.890901123S'); diff --git a/test/staging/Temporal/v8/duration-value-of.js b/test/staging/Temporal/v8/duration-value-of.js new file mode 100644 index 0000000000..4fe7f6fc35 --- /dev/null +++ b/test/staging/Temporal/v8/duration-value-of.js @@ -0,0 +1,13 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from duration-valueOf test + in V8's mjsunit test duration-valueOf.js +features: [Temporal] +---*/ + +let d1 = new Temporal.Duration(); +assert.throws(TypeError, () => d1.valueOf()); diff --git a/test/staging/Temporal/v8/duration-with.js b/test/staging/Temporal/v8/duration-with.js new file mode 100644 index 0000000000..4ee28a5e06 --- /dev/null +++ b/test/staging/Temporal/v8/duration-with.js @@ -0,0 +1,106 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from duration-with test + in V8's mjsunit test duration-with.js +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +let like1 = { + years: 9, + months: 8, + weeks: 7, + days: 6, + hours: 5, + minutes: 4, + seconds: 3, + milliseconds: 2, + microseconds: 1, + nanoseconds: 10 +}; +let like2 = { + years: 9, + hours: 5 +}; +let like3 = { + months: 8, + minutes: 4 +}; +let like4 = { + weeks: 7, + seconds: 3 +}; +let like5 = { + days: 6, + milliseconds: 2 +}; +let like6 = { + microseconds: 987, + nanoseconds: 123 +}; +let like7 = { + years: -9, + months: -8, + weeks: -7, + days: -6, + hours: -5, + minutes: -4, + seconds: -3, + milliseconds: -2, + microseconds: -1, + nanoseconds: -10 +}; +let d1 = new Temporal.Duration(); +TemporalHelpers.assertDuration(d1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); +TemporalHelpers.assertDuration(d1.with(like1), 9, 8, 7, 6, 5, 4, 3, 2, 1, 10); +TemporalHelpers.assertDuration(d1.with(like2), 9, 0, 0, 0, 5, 0, 0, 0, 0, 0); +TemporalHelpers.assertDuration(d1.with(like3), 0, 8, 0, 0, 0, 4, 0, 0, 0, 0); +TemporalHelpers.assertDuration(d1.with(like4), 0, 0, 7, 0, 0, 0, 3, 0, 0, 0); +TemporalHelpers.assertDuration(d1.with(like5), 0, 0, 0, 6, 0, 0, 0, 2, 0, 0); +TemporalHelpers.assertDuration(d1.with(like6), 0, 0, 0, 0, 0, 0, 0, 0, 987, 123); +TemporalHelpers.assertDuration(d1.with(like7), -9, -8, -7, -6, -5, -4, -3, -2, -1, -10); +let d2 = new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); +TemporalHelpers.assertDuration(d2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); +TemporalHelpers.assertDuration(d2.with(like1), 9, 8, 7, 6, 5, 4, 3, 2, 1, 10); +TemporalHelpers.assertDuration(d2.with(like7), -9, -8, -7, -6, -5, -4, -3, -2, -1, -10); +assert.throws(RangeError, () => d2.with({ years: -1 })); +assert.throws(RangeError, () => d2.with({ months: -2 })); +assert.throws(RangeError, () => d2.with({ weeks: -3 })); +assert.throws(RangeError, () => d2.with({ days: -4 })); +assert.throws(RangeError, () => d2.with({ hours: -5 })); +assert.throws(RangeError, () => d2.with({ minutes: -6 })); +assert.throws(RangeError, () => d2.with({ seconds: -7 })); +assert.throws(RangeError, () => d2.with({ milliseconds: -8 })); +assert.throws(RangeError, () => d2.with({ microseconds: -9 })); +assert.throws(RangeError, () => d2.with({ nanoseconds: -10 })); +let d3 = new Temporal.Duration(100000, 200000, 300000, 400000, 500000, 600000, 700000, 800000, 900000, 1000000); +TemporalHelpers.assertDuration(d3, 100000, 200000, 300000, 400000, 500000, 600000, 700000, 800000, 900000, 1000000); +TemporalHelpers.assertDuration(d3.with(like1), 9, 8, 7, 6, 5, 4, 3, 2, 1, 10); +TemporalHelpers.assertDuration(d3.with(like7), -9, -8, -7, -6, -5, -4, -3, -2, -1, -10); +let d4 = new Temporal.Duration(-1, -2, -3, -4, -5, -6, -7, -8, -9, -10); +TemporalHelpers.assertDuration(d4, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10); +TemporalHelpers.assertDuration(d4.with(like1), 9, 8, 7, 6, 5, 4, 3, 2, 1, 10); +assert.throws(RangeError, () => d4.with({ years: 1 })); +assert.throws(RangeError, () => d4.with({ months: 2 })); +assert.throws(RangeError, () => d4.with({ weeks: 3 })); +assert.throws(RangeError, () => d4.with({ days: 4 })); +assert.throws(RangeError, () => d4.with({ hours: 5 })); +assert.throws(RangeError, () => d4.with({ minutes: 6 })); +assert.throws(RangeError, () => d4.with({ seconds: 7 })); +assert.throws(RangeError, () => d4.with({ milliseconds: 8 })); +assert.throws(RangeError, () => d4.with({ microseconds: 9 })); +assert.throws(RangeError, () => d4.with({ nanoseconds: 10 })); +assert.throws(TypeError, () => d1.with({ year: 1 })); +assert.throws(TypeError, () => d1.with({ month: 1 })); +assert.throws(TypeError, () => d1.with({ week: 1 })); +assert.throws(TypeError, () => d1.with({ day: 1 })); +assert.throws(TypeError, () => d1.with({ hour: 1 })); +assert.throws(TypeError, () => d1.with({ minute: 1 })); +assert.throws(TypeError, () => d1.with({ second: 1 })); +assert.throws(TypeError, () => d1.with({ millisecond: 1 })); +assert.throws(TypeError, () => d1.with({ microsecond: 1 })); +assert.throws(TypeError, () => d1.with({ nanosecond: 1 })); diff --git a/test/staging/Temporal/v8/instant-add.js b/test/staging/Temporal/v8/instant-add.js new file mode 100644 index 0000000000..3783968de9 --- /dev/null +++ b/test/staging/Temporal/v8/instant-add.js @@ -0,0 +1,32 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from instant-add test + in V8's mjsunit test instant-add.js +features: [Temporal] +---*/ + +let i1 = new Temporal.Instant(50000n); +assert.sameValue(i1.add(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 3, 2, 1)).epochNanoseconds, 3052001n); +assert.sameValue(i1.add(new Temporal.Duration(0, 0, 0, 0, 0, 0, 4, 3, 2, 1)).epochNanoseconds, BigInt(4 * 1000000000) + 3052001n); +assert.sameValue(i1.add(new Temporal.Duration(0, 0, 0, 0, 0, 5, 4, 3, 2, 1)).epochNanoseconds, BigInt(5 * 60 + 4) * 1000000000n + 3052001n); +assert.sameValue(i1.add(new Temporal.Duration(0, 0, 0, 0, 6, 5, 4, 3, 2, 1)).epochNanoseconds, BigInt(6 * 3600 + 5 * 60 + 4) * 1000000000n + 3052001n); +assert.sameValue(i1.add(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, -3, -2, -1)).epochNanoseconds, -2952001n); +assert.sameValue(i1.add(new Temporal.Duration(0, 0, 0, 0, 0, 0, -4, -3, -2, -1)).epochNanoseconds, BigInt(-4 * 1000000000) - 2952001n); +assert.sameValue(i1.add(new Temporal.Duration(0, 0, 0, 0, 0, -5, -4, -3, -2, -1)).epochNanoseconds, BigInt(5 * 60 + 4) * -1000000000n - 2952001n); +assert.sameValue(i1.add(new Temporal.Duration(0, 0, 0, 0, -6, -5, -4, -3, -2, -1)).epochNanoseconds, BigInt(6 * 3600 + 5 * 60 + 4) * -1000000000n - 2952001n); +let badInstant = { add: i1.add }; +assert.throws(TypeError, () => badInstant.add(new Temporal.Duration(0, 0, 0, 0, 5))); +assert.throws(RangeError, () => i1.add(new Temporal.Duration(1))); +assert.throws(RangeError, () => i1.add(new Temporal.Duration(0, 2))); +assert.throws(RangeError, () => i1.add(new Temporal.Duration(0, 0, 3))); +assert.throws(RangeError, () => i1.add(new Temporal.Duration(0, 0, 0, 4))); +assert.throws(RangeError, () => i1.add(new Temporal.Duration(-1))); +assert.throws(RangeError, () => i1.add(new Temporal.Duration(0, -2))); +assert.throws(RangeError, () => i1.add(new Temporal.Duration(0, 0, -3))); +assert.throws(RangeError, () => i1.add(new Temporal.Duration(0, 0, 0, -4))); +let i2 = new Temporal.Instant(86400n * 99999999999999999n); +assert.throws(RangeError, () => i2.add(new Temporal.Duration(0, 0, 0, 0, 999999999))); diff --git a/test/staging/Temporal/v8/instant-compare.js b/test/staging/Temporal/v8/instant-compare.js new file mode 100644 index 0000000000..b6a65c73f0 --- /dev/null +++ b/test/staging/Temporal/v8/instant-compare.js @@ -0,0 +1,19 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from instant-compare test + in V8's mjsunit test instant-compare.js +features: [Temporal] +---*/ + +let inst1 = new Temporal.Instant(1234567890123456789n); +let inst2 = new Temporal.Instant(1234567890123456000n); +let inst3 = new Temporal.Instant(1234567890123456000n); +assert.sameValue(Temporal.Instant.compare(inst2, inst3), 0); +assert.sameValue(Temporal.Instant.compare(inst1, inst2), 1); +assert.sameValue(Temporal.Instant.compare(inst3, inst1), -1); +assert.throws(RangeError, () => Temporal.Instant.compare(inst1, 'invalid iso8601 string')); +assert.throws(RangeError, () => Temporal.Instant.compare('invalid iso8601 string', inst1)); diff --git a/test/staging/Temporal/v8/instant-constructor.js b/test/staging/Temporal/v8/instant-constructor.js new file mode 100644 index 0000000000..31b5cc7c5c --- /dev/null +++ b/test/staging/Temporal/v8/instant-constructor.js @@ -0,0 +1,41 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from instant-constructor test + in V8's mjsunit test instant-constructor.js +features: [Temporal] +---*/ + +let inst1 = new Temporal.Instant(1234567890123456789n); +assert.sameValue(inst1.epochNanoseconds, 1234567890123456789n); +assert.sameValue(inst1.epochMilliseconds, 1234567890123); +let inst2 = new Temporal.Instant(-1234567890123456789n); +assert.sameValue(inst2.epochNanoseconds, -1234567890123456789n); +assert.sameValue(inst2.epochMilliseconds, -1234567890124); +assert.throws(TypeError, () => Temporal.Instant(1234567890123456789n)); +assert.throws(TypeError, () => { + let inst = new Temporal.Instant(undefined); +}); +assert.throws(TypeError, () => { + let inst = new Temporal.Instant(null); +}); +assert.sameValue(new Temporal.Instant(true).epochNanoseconds, 1n); +assert.sameValue(new Temporal.Instant(false).epochNanoseconds, 0n); +assert.throws(TypeError, () => { + let inst = Temporal.Instant(12345); +}); +assert.sameValue(new Temporal.Instant('1234567890123456789').epochNanoseconds, 1234567890123456789n); +assert.throws(TypeError, () => { + let inst = new Temporal.Instant(Symbol(12345n)); +}); +assert.throws(RangeError, () => { + let inst = new Temporal.Instant(8640000000000000000001n); +}); +assert.throws(RangeError, () => { + let inst = new Temporal.Instant(-8640000000000000000001n); +}); +assert.sameValue(new Temporal.Instant(8640000000000000000000n).epochNanoseconds, 8640000000000000000000n); +assert.sameValue(new Temporal.Instant(-8640000000000000000000n).epochNanoseconds, -8640000000000000000000n); diff --git a/test/staging/Temporal/v8/instant-equals.js b/test/staging/Temporal/v8/instant-equals.js new file mode 100644 index 0000000000..d1ea8cbf8a --- /dev/null +++ b/test/staging/Temporal/v8/instant-equals.js @@ -0,0 +1,18 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from instant-equals test + in V8's mjsunit test instant-equals.js +features: [Temporal] +---*/ + +let inst1 = new Temporal.Instant(1234567890123456789n); +let inst2 = new Temporal.Instant(1234567890123456000n); +let inst3 = new Temporal.Instant(1234567890123456000n); +assert(!inst1.equals(inst2)); +assert(inst2.equals(inst3)); +let badInst = { equals: inst1.equals }; +assert.throws(TypeError, () => badInst.equals(inst1)); diff --git a/test/staging/Temporal/v8/instant-from-epoch-milliseconds.js b/test/staging/Temporal/v8/instant-from-epoch-milliseconds.js new file mode 100644 index 0000000000..a4262798ab --- /dev/null +++ b/test/staging/Temporal/v8/instant-from-epoch-milliseconds.js @@ -0,0 +1,26 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from instant-from-epoch-milliseconds test + in V8's mjsunit test instant-from-epoch-milliseconds.js +features: [Temporal] +---*/ + +let bigint_nano = 567890123456789000000n; +let milli = 567890123456789; +let bigint_milli = BigInt(milli); +let inst1 = new Temporal.Instant(bigint_nano); +assert.throws(TypeError, () => Temporal.Instant.fromEpochMilliseconds(bigint_milli)); +let inst2 = Temporal.Instant.fromEpochMilliseconds(milli); +assert(inst2.equals(inst1)); +let just_fit_neg = -8640000000000000; +let just_fit_pos = 8640000000000000; +let too_big = 8640000000000001; +let too_small = -8640000000000001; +assert.throws(RangeError, () => Temporal.Instant.fromEpochMilliseconds(too_small)); +assert.throws(RangeError, () => Temporal.Instant.fromEpochMilliseconds(too_big)); +assert.sameValue(Temporal.Instant.fromEpochMilliseconds(just_fit_neg).epochMilliseconds, just_fit_neg); +assert.sameValue(Temporal.Instant.fromEpochMilliseconds(just_fit_pos).epochMilliseconds, just_fit_pos); diff --git a/test/staging/Temporal/v8/instant-from-epoch-nanoseconds.js b/test/staging/Temporal/v8/instant-from-epoch-nanoseconds.js new file mode 100644 index 0000000000..cf4a0b10a1 --- /dev/null +++ b/test/staging/Temporal/v8/instant-from-epoch-nanoseconds.js @@ -0,0 +1,27 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from instant-from-epoch-nanoseconds test + in V8's mjsunit test instant-from-epoch-nanoseconds.js +features: [Temporal] +---*/ + +let bigint1 = 1234567890123456789n; +let inst1 = new Temporal.Instant(bigint1); +let inst2 = Temporal.Instant.fromEpochNanoseconds(bigint1); +assert(inst2.equals(inst1)); +let just_fit_neg_bigint = -8640000000000000000000n; +let just_fit_pos_bigint = 8640000000000000000000n; +let too_big_bigint = 8640000000000000000001n; +let too_small_bigint = -8640000000000000000001n; +assert.throws(RangeError, () => { + let inst = Temporal.Instant.fromEpochNanoseconds(too_small_bigint); +}); +assert.throws(RangeError, () => { + let inst = Temporal.Instant.fromEpochNanoseconds(too_big_bigint); +}); +assert.sameValue(Temporal.Instant.fromEpochNanoseconds(just_fit_neg_bigint).epochNanoseconds, just_fit_neg_bigint); +assert.sameValue(Temporal.Instant.fromEpochNanoseconds(just_fit_pos_bigint).epochNanoseconds, just_fit_pos_bigint); diff --git a/test/staging/Temporal/v8/instant-subtract.js b/test/staging/Temporal/v8/instant-subtract.js new file mode 100644 index 0000000000..adc61c9ee6 --- /dev/null +++ b/test/staging/Temporal/v8/instant-subtract.js @@ -0,0 +1,32 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from instant-subtract test + in V8's mjsunit test instant-subtract.js +features: [Temporal] +---*/ + +let i1 = new Temporal.Instant(50000n); +assert.sameValue(i1.subtract(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, -3, -2, -1)).epochNanoseconds, 3052001n); +assert.sameValue(i1.subtract(new Temporal.Duration(0, 0, 0, 0, 0, 0, -4, -3, -2, -1)).epochNanoseconds, BigInt(4 * 1000000000) + 3052001n); +assert.sameValue(i1.subtract(new Temporal.Duration(0, 0, 0, 0, 0, -5, -4, -3, -2, -1)).epochNanoseconds, BigInt(5 * 60 + 4) * 1000000000n + 3052001n); +assert.sameValue(i1.subtract(new Temporal.Duration(0, 0, 0, 0, -6, -5, -4, -3, -2, -1)).epochNanoseconds, BigInt(6 * 3600 + 5 * 60 + 4) * 1000000000n + 3052001n); +assert.sameValue(i1.subtract(new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 3, 2, 1)).epochNanoseconds, -2952001n); +assert.sameValue(i1.subtract(new Temporal.Duration(0, 0, 0, 0, 0, 0, 4, 3, 2, 1)).epochNanoseconds, BigInt(-4 * 1000000000) - 2952001n); +assert.sameValue(i1.subtract(new Temporal.Duration(0, 0, 0, 0, 0, 5, 4, 3, 2, 1)).epochNanoseconds, BigInt(5 * 60 + 4) * -1000000000n - 2952001n); +assert.sameValue(i1.subtract(new Temporal.Duration(0, 0, 0, 0, 6, 5, 4, 3, 2, 1)).epochNanoseconds, BigInt(6 * 3600 + 5 * 60 + 4) * -1000000000n - 2952001n); +let badInstant = { subtract: i1.subtract }; +assert.throws(TypeError, () => badInstant.subtract(new Temporal.Duration(0, 0, 0, 0, 5))); +assert.throws(RangeError, () => i1.subtract(new Temporal.Duration(1))); +assert.throws(RangeError, () => i1.subtract(new Temporal.Duration(0, 2))); +assert.throws(RangeError, () => i1.subtract(new Temporal.Duration(0, 0, 3))); +assert.throws(RangeError, () => i1.subtract(new Temporal.Duration(0, 0, 0, 4))); +assert.throws(RangeError, () => i1.subtract(new Temporal.Duration(-1))); +assert.throws(RangeError, () => i1.subtract(new Temporal.Duration(0, -2))); +assert.throws(RangeError, () => i1.subtract(new Temporal.Duration(0, 0, -3))); +assert.throws(RangeError, () => i1.subtract(new Temporal.Duration(0, 0, 0, -4))); +let i2 = new Temporal.Instant(-86400n * 99999999999999999n); +assert.throws(RangeError, () => i2.subtract(new Temporal.Duration(0, 0, 0, 0, 999999999))); diff --git a/test/staging/Temporal/v8/instant-to-json.js b/test/staging/Temporal/v8/instant-to-json.js new file mode 100644 index 0000000000..51581478e9 --- /dev/null +++ b/test/staging/Temporal/v8/instant-to-json.js @@ -0,0 +1,31 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from instant-to-json test + in V8's mjsunit test instant-to-json.js +features: [Temporal] +---*/ + +assert.sameValue(Temporal.Instant.fromEpochMilliseconds(0).toJSON(), '1970-01-01T00:00:00Z'); +let days_in_ms = 24 * 60 * 60 * 1000; +assert.sameValue(Temporal.Instant.fromEpochMilliseconds(365 * days_in_ms - 1).toJSON(), '1970-12-31T23:59:59.999Z'); +assert.sameValue(Temporal.Instant.fromEpochMilliseconds(365 * days_in_ms).toJSON(), '1971-01-01T00:00:00Z'); +assert.sameValue(Temporal.Instant.fromEpochMilliseconds(2 * 365 * days_in_ms - 1).toJSON(), '1971-12-31T23:59:59.999Z'); +assert.sameValue(Temporal.Instant.fromEpochMilliseconds(2 * 365 * days_in_ms).toJSON(), '1972-01-01T00:00:00Z'); +assert.sameValue(Temporal.Instant.fromEpochMilliseconds((2 * 365 + 58) * days_in_ms).toJSON(), '1972-02-28T00:00:00Z'); +assert.sameValue(Temporal.Instant.fromEpochMilliseconds((2 * 365 + 59) * days_in_ms).toJSON(), '1972-02-29T00:00:00Z'); +assert.sameValue(Temporal.Instant.fromEpochMilliseconds((15 * 365 + 4) * days_in_ms).toJSON(), '1985-01-01T00:00:00Z'); +const year_in_sec = 24 * 60 * 60 * 365; +const number_of_random_test = 500; +for (let i = 0; i < number_of_random_test; i++) { + let ms = Math.floor(Math.random() * year_in_sec * 1000 * 10000) - year_in_sec * 1000 * 5000; + let d = new Date(ms); + const dateout = d.toJSON().substr(0, 19); + const temporalout = Temporal.Instant.fromEpochMilliseconds(ms).toJSON().substr(0, 19); + if (dateout[0] != '0') { + assert.sameValue(temporalout, dateout, ms); + } +} diff --git a/test/staging/Temporal/v8/instant-value-of.js b/test/staging/Temporal/v8/instant-value-of.js new file mode 100644 index 0000000000..5a0f78426d --- /dev/null +++ b/test/staging/Temporal/v8/instant-value-of.js @@ -0,0 +1,13 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from instant-valueOf test + in V8's mjsunit test instant-valueOf.js +features: [Temporal] +---*/ + +let d1 = Temporal.Now.instant(); +assert.throws(TypeError, () => d1.valueOf()); diff --git a/test/staging/Temporal/v8/plain-date-add.js b/test/staging/Temporal/v8/plain-date-add.js new file mode 100644 index 0000000000..e81db05293 --- /dev/null +++ b/test/staging/Temporal/v8/plain-date-add.js @@ -0,0 +1,25 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from plain-date-add test + in V8's mjsunit test plain-date-add.js +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +let d = new Temporal.PlainDate(2021, 7, 20); +TemporalHelpers.assertPlainDate(d.add('P1D'), 2021, 7, 'M07', 21); +TemporalHelpers.assertPlainDate(d.subtract('-P1D'), 2021, 7, 'M07', 21); +TemporalHelpers.assertPlainDate(d.add('-P1D'), 2021, 7, 'M07', 19); +TemporalHelpers.assertPlainDate(d.subtract('P1D'), 2021, 7, 'M07', 19); +TemporalHelpers.assertPlainDate(d.add('P11D'), 2021, 7, 'M07', 31); +TemporalHelpers.assertPlainDate(d.subtract('-P11D'), 2021, 7, 'M07', 31); +TemporalHelpers.assertPlainDate(d.add('P12D'), 2021, 8, 'M08', 1); +TemporalHelpers.assertPlainDate(d.subtract('-P12D'), 2021, 8, 'M08', 1); +let goodDate = new Temporal.PlainDate(2021, 7, 20); +let badDate = { add: goodDate.add }; +assert.throws(TypeError, () => badDate.add('P1D')); +assert.throws(RangeError, () => new Temporal.PlainDate(2021, 7, 20).add('bad duration')); diff --git a/test/staging/Temporal/v8/plain-date-compare.js b/test/staging/Temporal/v8/plain-date-compare.js new file mode 100644 index 0000000000..7fbfc1af02 --- /dev/null +++ b/test/staging/Temporal/v8/plain-date-compare.js @@ -0,0 +1,31 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from plain-date-compare test + in V8's mjsunit test plain-date-compare.js +features: [Temporal] +---*/ + +let t1 = new Temporal.PlainDate(2021, 3, 14); +let t2 = new Temporal.PlainDate(2021, 3, 14); +let t3 = t1; +let t4 = new Temporal.PlainDate(2021, 3, 15); +let t5 = new Temporal.PlainDate(2021, 4, 14); +let t6 = new Temporal.PlainDate(2022, 3, 14); +assert.sameValue(Temporal.PlainDate.compare(t1, t1), 0); +assert.sameValue(Temporal.PlainDate.compare(t1, t2), 0); +assert.sameValue(Temporal.PlainDate.compare(t1, t3), 0); +assert.sameValue(Temporal.PlainDate.compare(t1, '2021-03-14'), 0); +assert.sameValue(Temporal.PlainDate.compare(t1, '2021-03-14T23:59:59'), 0); +assert.sameValue(Temporal.PlainDate.compare(t4, t1), 1); +assert.sameValue(Temporal.PlainDate.compare(t5, t1), 1); +assert.sameValue(Temporal.PlainDate.compare(t6, t1), 1); +assert.sameValue(Temporal.PlainDate.compare(t1, t4), -1); +assert.sameValue(Temporal.PlainDate.compare(t1, t5), -1); +assert.sameValue(Temporal.PlainDate.compare(t1, t6), -1); +assert.sameValue(Temporal.PlainDate.compare('2021-07-21', t1), 1); +assert.throws(RangeError, () => Temporal.PlainDate.compare(t1, 'invalid iso8601 string')); +assert.throws(RangeError, () => Temporal.PlainDate.compare('invalid iso8601 string', t1)); diff --git a/test/staging/Temporal/v8/plain-date-constructor.js b/test/staging/Temporal/v8/plain-date-constructor.js new file mode 100644 index 0000000000..9f1bff5385 --- /dev/null +++ b/test/staging/Temporal/v8/plain-date-constructor.js @@ -0,0 +1,75 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from plain-date-constructor test + in V8's mjsunit test plain-date-constructor.js +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +let d1 = new Temporal.PlainDate(1911, 10, 10); +TemporalHelpers.assertPlainDate(d1, 1911, 10, 'M10', 10); +let d2 = new Temporal.PlainDate(2020, 3, 12); +TemporalHelpers.assertPlainDate(d2, 2020, 3, 'M03', 12); +let d3 = new Temporal.PlainDate(1, 12, 25); +TemporalHelpers.assertPlainDate(d3, 1, 12, 'M12', 25); +let d4 = new Temporal.PlainDate(1970, 1, 1); +TemporalHelpers.assertPlainDate(d4, 1970, 1, 'M01', 1); +let d5 = new Temporal.PlainDate(-10, 12, 1); +TemporalHelpers.assertPlainDate(d5, -10, 12, 'M12', 1); +let d6 = new Temporal.PlainDate(-25406, 1, 1); +TemporalHelpers.assertPlainDate(d6, -25406, 1, 'M01', 1); +let d7 = new Temporal.PlainDate(26890, 12, 31); +TemporalHelpers.assertPlainDate(d7, 26890, 12, 'M12', 31); +assert.throws(TypeError, () => Temporal.PlainDate(2021, 7, 1)); +assert.throws(RangeError, () => new Temporal.PlainDate()); +assert.throws(RangeError, () => new Temporal.PlainDate(2021)); +assert.throws(RangeError, () => new Temporal.PlainDate(2021, 0)); +assert.throws(RangeError, () => new Temporal.PlainDate(2021, 7)); +assert.throws(RangeError, () => new Temporal.PlainDate(2021, 13)); +assert.throws(RangeError, () => new Temporal.PlainDate(2021, 7, 0)); +assert.throws(RangeError, () => new Temporal.PlainDate(2021, 7, 32)); +assert.throws(RangeError, () => new Temporal.PlainDate(2021, -7, 1)); +assert.throws(RangeError, () => new Temporal.PlainDate(2021, -7, -1)); +assert.throws(RangeError, () => new Temporal.PlainDate(2021, 0, 1)); +assert.throws(RangeError, () => new Temporal.PlainDate(2021, 13, 1)); +TemporalHelpers.assertPlainDate(new Temporal.PlainDate(2021, 1, 31), 2021, 1, 'M01', 31); +TemporalHelpers.assertPlainDate(new Temporal.PlainDate(2021, 2, 28), 2021, 2, 'M02', 28); +TemporalHelpers.assertPlainDate(new Temporal.PlainDate(2021, 3, 31), 2021, 3, 'M03', 31); +TemporalHelpers.assertPlainDate(new Temporal.PlainDate(2021, 4, 30), 2021, 4, 'M04', 30); +TemporalHelpers.assertPlainDate(new Temporal.PlainDate(2021, 5, 31), 2021, 5, 'M05', 31); +TemporalHelpers.assertPlainDate(new Temporal.PlainDate(2021, 6, 30), 2021, 6, 'M06', 30); +TemporalHelpers.assertPlainDate(new Temporal.PlainDate(2021, 7, 31), 2021, 7, 'M07', 31); +TemporalHelpers.assertPlainDate(new Temporal.PlainDate(2021, 8, 31), 2021, 8, 'M08', 31); +TemporalHelpers.assertPlainDate(new Temporal.PlainDate(2021, 9, 30), 2021, 9, 'M09', 30); +TemporalHelpers.assertPlainDate(new Temporal.PlainDate(2021, 10, 31), 2021, 10, 'M10', 31); +TemporalHelpers.assertPlainDate(new Temporal.PlainDate(2021, 11, 30), 2021, 11, 'M11', 30); +TemporalHelpers.assertPlainDate(new Temporal.PlainDate(2021, 12, 31), 2021, 12, 'M12', 31); +assert.throws(RangeError, () => new Temporal.PlainDate(1900, 2, 29)); +TemporalHelpers.assertPlainDate(new Temporal.PlainDate(2000, 2, 29), 2000, 2, 'M02', 29); +assert.throws(RangeError, () => new Temporal.PlainDate(2001, 2, 29)); +assert.throws(RangeError, () => new Temporal.PlainDate(2002, 2, 29)); +assert.throws(RangeError, () => new Temporal.PlainDate(2003, 2, 29)); +TemporalHelpers.assertPlainDate(new Temporal.PlainDate(2004, 2, 29), 2004, 2, 'M02', 29); +assert.throws(RangeError, () => new Temporal.PlainDate(2100, 2, 29)); +assert.throws(RangeError, () => new Temporal.PlainDate(2021, 1, 32)); +assert.throws(RangeError, () => new Temporal.PlainDate(2021, 2, 29)); +assert.throws(RangeError, () => new Temporal.PlainDate(2021, 3, 32)); +assert.throws(RangeError, () => new Temporal.PlainDate(2021, 4, 31)); +assert.throws(RangeError, () => new Temporal.PlainDate(2021, 5, 32)); +assert.throws(RangeError, () => new Temporal.PlainDate(2021, 6, 31)); +assert.throws(RangeError, () => new Temporal.PlainDate(2021, 7, 32)); +assert.throws(RangeError, () => new Temporal.PlainDate(2021, 8, 32)); +assert.throws(RangeError, () => new Temporal.PlainDate(2021, 9, 31)); +assert.throws(RangeError, () => new Temporal.PlainDate(2021, 10, 32)); +assert.throws(RangeError, () => new Temporal.PlainDate(2021, 11, 31)); +assert.throws(RangeError, () => new Temporal.PlainDate(2021, 12, 32)); +assert.throws(RangeError, () => new Temporal.PlainDate(Infinity, 12, 1)); +assert.throws(RangeError, () => new Temporal.PlainDate(-Infinity, 12, 1)); +assert.throws(RangeError, () => new Temporal.PlainDate(2021, 12, Infinity)); +assert.throws(RangeError, () => new Temporal.PlainDate(2021, 12, -Infinity)); +assert.throws(RangeError, () => new Temporal.PlainDate(2021, -Infinity, 1)); +assert.throws(RangeError, () => new Temporal.PlainDate(2021, Infinity, 1)); diff --git a/test/staging/Temporal/v8/plain-date-equals.js b/test/staging/Temporal/v8/plain-date-equals.js new file mode 100644 index 0000000000..7043edc769 --- /dev/null +++ b/test/staging/Temporal/v8/plain-date-equals.js @@ -0,0 +1,19 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from plain-date-equals test + in V8's mjsunit test plain-date-equals.js +features: [Temporal] +---*/ + +let d1 = new Temporal.PlainDate(2021, 2, 28); +let d2 = Temporal.PlainDate.from('2021-02-28'); +let d3 = Temporal.PlainDate.from('2021-01-28'); +assert(d1.equals(d2)); +assert(!d1.equals(d3)); +assert(!d2.equals(d3)); +let badDate = { equals: d1.equals }; +assert.throws(TypeError, () => badDate.equals(d1)); diff --git a/test/staging/Temporal/v8/plain-date-from.js b/test/staging/Temporal/v8/plain-date-from.js new file mode 100644 index 0000000000..969da33aa9 --- /dev/null +++ b/test/staging/Temporal/v8/plain-date-from.js @@ -0,0 +1,82 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from plain-date-from test + in V8's mjsunit test plain-date-from.js +features: [Temporal] +---*/ + +let d1 = Temporal.Now.plainDateISO(); +[ + true, + false, + 'string is invalid', + Symbol(), + 123, + 456n, + Infinity, + NaN, + null +].forEach(function (invalidOptions) { + assert.throws(TypeError, () => Temporal.PlainDate.from(d1, invalidOptions)); +}); +assert.throws(RangeError, () => Temporal.PlainDate.from(d1, { overflow: 'invalid overflow' })); +[ + undefined, + {}, + { overflow: 'constrain' }, + { overflow: 'reject' } +].forEach(function (validOptions) { + let d = new Temporal.PlainDate(1, 2, 3); + let d2 = Temporal.PlainDate.from(d, validOptions); + assert.sameValue(d2.year, 1); + assert.sameValue(d2.month, 2); + assert.sameValue(d2.day, 3); + assert.sameValue(d2.calendarId, 'iso8601'); +}); +[ + undefined, + {}, + { overflow: 'constrain' }, + { overflow: 'reject' } +].forEach(function (validOptions) { + let d3 = Temporal.PlainDate.from({ + year: 9, + month: 8, + day: 7 + }, validOptions); + assert.sameValue(d3.year, 9); + assert.sameValue(d3.month, 8); + assert.sameValue(d3.monthCode, 'M08'); + assert.sameValue(d3.day, 7); + assert.sameValue(d3.calendarId, 'iso8601'); +}); +[ + undefined, + {}, + { overflow: 'constrain' } +].forEach(function (validOptions) { + let d4 = Temporal.PlainDate.from({ + year: 9, + month: 14, + day: 32 + }, validOptions); + assert.sameValue(d4.year, 9); + assert.sameValue(d4.month, 12); + assert.sameValue(d4.monthCode, 'M12'); + assert.sameValue(d4.day, 31); + assert.sameValue(d4.calendarId, 'iso8601'); +}); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 9, + month: 14, + day: 30 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainDate.from({ + year: 9, + month: 12, + day: 32 +}, { overflow: 'reject' })); diff --git a/test/staging/Temporal/v8/plain-date-get-iso-fields.js b/test/staging/Temporal/v8/plain-date-get-iso-fields.js new file mode 100644 index 0000000000..1054f970b6 --- /dev/null +++ b/test/staging/Temporal/v8/plain-date-get-iso-fields.js @@ -0,0 +1,26 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from plain-date-get-iso-fields test + in V8's mjsunit test plain-date-get-iso-fields.js +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +let d1 = new Temporal.PlainDate(1911, 10, 10); +TemporalHelpers.assertPlainDate(d1, 1911, 10, 'M10', 10); +let d2 = new Temporal.PlainDate(2020, 3, 12); +TemporalHelpers.assertPlainDate(d2, 2020, 3, 'M03', 12); +let d3 = new Temporal.PlainDate(1, 12, 25); +TemporalHelpers.assertPlainDate(d3, 1, 12, 'M12', 25); +let d4 = new Temporal.PlainDate(1970, 1, 1); +TemporalHelpers.assertPlainDate(d4, 1970, 1, 'M01', 1); +let d5 = new Temporal.PlainDate(-10, 12, 1); +TemporalHelpers.assertPlainDate(d5, -10, 12, 'M12', 1); +let d6 = new Temporal.PlainDate(-25406, 1, 1); +TemporalHelpers.assertPlainDate(d6, -25406, 1, 'M01', 1); +let d7 = new Temporal.PlainDate(26890, 12, 31); +TemporalHelpers.assertPlainDate(d7, 26890, 12, 'M12', 31); diff --git a/test/staging/Temporal/v8/plain-date-time-add.js b/test/staging/Temporal/v8/plain-date-time-add.js new file mode 100644 index 0000000000..e08f3e101a --- /dev/null +++ b/test/staging/Temporal/v8/plain-date-time-add.js @@ -0,0 +1,36 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from plain-date-time-add test + in V8's mjsunit test plain-date-time-add.js +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 1, 2, 3, 4, 5, 6).add('PT9H8M7.080090010S'), 2021, 7, 'M07', 20, 10, 10, 10, 84, 95, 16); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 0, 0, 0, 0, 1, 996).add('PT0.0000071S'), 2021, 7, 'M07', 20, 0, 0, 0, 0, 9, 96); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 0, 0, 0, 1, 996).add('PT0.0071S'), 2021, 7, 'M07', 20, 0, 0, 0, 9, 96, 0); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 0, 0, 1, 996).add('PT7.1S'), 2021, 7, 'M07', 20, 0, 0, 9, 96, 0, 0, 0); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 0, 1, 59).add('PT5M7S'), 2021, 7, 'M07', 20, 0, 7, 6, 0, 0, 0); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 1, 59).add('PT5H7M'), 2021, 7, 'M07', 20, 7, 6, 0, 0, 0, 0); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 19).add('PT8H'), 2021, 7, 'M07', 21, 3, 0, 0, 0, 0, 0); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 21, 52, 53, 994, 995, 996).add('PT5H13M11.404303202S'), 2021, 7, 'M07', 21, 3, 6, 5, 399, 299, 198); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 0, 0, 0, 0, 0, 995).add('PT0.000000006S'), 2021, 7, 'M07', 20, 0, 0, 0, 0, 1, 1); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 0, 0, 0, 0, 0, 995).add('PT0.00000006S'), 2021, 7, 'M07', 20, 0, 0, 0, 0, 1, 55); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 0, 0, 0, 0, 0, 995).add('PT0.0000006S'), 2021, 7, 'M07', 20, 0, 0, 0, 0, 1, 595); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 1, 2, 3, 4, 5, 6).add('-PT0.000000007S'), 2021, 7, 'M07', 20, 1, 2, 3, 4, 4, 999); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 1, 2, 3, 4, 5, 6).add('-PT0.000005007S'), 2021, 7, 'M07', 20, 1, 2, 3, 3, 999, 999); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 1, 2, 3, 4, 5, 6).add('-PT0.004005007S'), 2021, 7, 'M07', 20, 1, 2, 2, 999, 999, 999); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 1, 2, 3, 4, 5, 6).add('-PT0.005006007S'), 2021, 7, 'M07', 20, 1, 2, 2, 998, 998, 999); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 1, 2, 3, 4, 5, 6).add('-PT4.005006007S'), 2021, 7, 'M07', 20, 1, 1, 58, 998, 998, 999); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 1, 2, 3, 4, 5, 6).add('-PT4S'), 2021, 7, 'M07', 20, 1, 1, 59, 4, 5, 6); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 1, 2, 3, 4, 5, 6).add('-PT5M'), 2021, 7, 'M07', 20, 0, 57, 3, 4, 5, 6); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 1, 2, 3, 4, 5, 6).add('-PT1H5M'), 2021, 7, 'M07', 19, 23, 57, 3, 4, 5, 6); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 1, 2, 3, 4, 5, 6).add('-PT1H5M4S'), 2021, 7, 'M07', 19, 23, 56, 59, 4, 5, 6); +let goodDateTime = new Temporal.PlainDateTime(2021, 7, 20, 1, 2, 3); +let badDateTime = { add: goodDateTime.add }; +assert.throws(TypeError, () => badDateTime.add('PT30M')); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, 7, 20, 1, 2, 3).add('bad duration')); diff --git a/test/staging/Temporal/v8/plain-date-time-compare.js b/test/staging/Temporal/v8/plain-date-time-compare.js new file mode 100644 index 0000000000..674e123f6a --- /dev/null +++ b/test/staging/Temporal/v8/plain-date-time-compare.js @@ -0,0 +1,34 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from plain-date-time-compare test + in V8's mjsunit test plain-date-time-compare.js +features: [Temporal] +---*/ + +let t1 = new Temporal.PlainDateTime(2021, 3, 14, 1, 2, 3, 4, 5, 6); +let t2 = new Temporal.PlainDateTime(2021, 3, 14, 1, 2, 3, 4, 5, 6); +let t3 = t1; +let t4 = new Temporal.PlainDateTime(2021, 3, 15, 1, 2, 3, 4, 5, 6); +let t5 = new Temporal.PlainDateTime(2021, 4, 14, 1, 2, 3, 4, 5, 6); +let t6 = new Temporal.PlainDateTime(2022, 3, 14, 1, 2, 3, 4, 5, 6); +let t7 = new Temporal.PlainDateTime(2021, 3, 14, 1, 2, 3, 4, 5, 7); +assert.sameValue(Temporal.PlainDateTime.compare(t1, t1), 0); +assert.sameValue(Temporal.PlainDateTime.compare(t1, t2), 0); +assert.sameValue(Temporal.PlainDateTime.compare(t1, t3), 0); +assert.sameValue(Temporal.PlainDateTime.compare(t1, '2021-03-14T01:02:03'), 1); +assert.sameValue(Temporal.PlainDateTime.compare(t4, t1), 1); +assert.sameValue(Temporal.PlainDateTime.compare(t5, t1), 1); +assert.sameValue(Temporal.PlainDateTime.compare(t6, t1), 1); +assert.sameValue(Temporal.PlainDateTime.compare(t7, t1), 1); +assert.sameValue(Temporal.PlainDateTime.compare(t1, t4), -1); +assert.sameValue(Temporal.PlainDateTime.compare(t1, t5), -1); +assert.sameValue(Temporal.PlainDateTime.compare(t1, t6), -1); +assert.sameValue(Temporal.PlainDateTime.compare(t1, t7), -1); +assert.sameValue(Temporal.PlainDateTime.compare('2021-07-21', t1), 1); +assert.sameValue(Temporal.PlainDateTime.compare(t1, '2021-03-14T01:02:03.004005006'), 0); +assert.throws(RangeError, () => Temporal.PlainDateTime.compare(t1, 'invalid iso8601 string')); +assert.throws(RangeError, () => Temporal.PlainDateTime.compare('invalid iso8601 string', t1)); diff --git a/test/staging/Temporal/v8/plain-date-time-constructor.js b/test/staging/Temporal/v8/plain-date-time-constructor.js new file mode 100644 index 0000000000..3cc6e31f0d --- /dev/null +++ b/test/staging/Temporal/v8/plain-date-time-constructor.js @@ -0,0 +1,102 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from plain-date-time-constructor test + in V8's mjsunit test plain-date-time-constructor.js +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +let d1 = new Temporal.PlainDateTime(1911, 10, 10); +TemporalHelpers.assertPlainDateTime(d1, 1911, 10, 'M10', 10, 0, 0, 0, 0, 0, 0); +let d2 = new Temporal.PlainDateTime(2020, 3, 12); +TemporalHelpers.assertPlainDateTime(d2, 2020, 3, 'M03', 12, 0, 0, 0, 0, 0, 0); +let d3 = new Temporal.PlainDateTime(1, 12, 25); +TemporalHelpers.assertPlainDateTime(d3, 1, 12, 'M12', 25, 0, 0, 0, 0, 0, 0); +let d4 = new Temporal.PlainDateTime(1970, 1, 1); +TemporalHelpers.assertPlainDateTime(d4, 1970, 1, 'M01', 1, 0, 0, 0, 0, 0, 0); +let d5 = new Temporal.PlainDateTime(-10, 12, 1); +TemporalHelpers.assertPlainDateTime(d5, -10, 12, 'M12', 1, 0, 0, 0, 0, 0, 0); +let d6 = new Temporal.PlainDateTime(-25406, 1, 1); +TemporalHelpers.assertPlainDateTime(d6, -25406, 1, 'M01', 1, 0, 0, 0, 0, 0, 0); +let d7 = new Temporal.PlainDateTime(26890, 12, 31); +TemporalHelpers.assertPlainDateTime(d7, 26890, 12, 'M12', 31, 0, 0, 0, 0, 0, 0); +assert.throws(TypeError, () => Temporal.PlainDateTime(2021, 7, 1)); +assert.throws(RangeError, () => new Temporal.PlainDateTime()); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, 0)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, 7)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, 13)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, 7, 0)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, 7, 32)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, -7, 1)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, -7, -1)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, 0, 1)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, 13, 1)); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 1, 31), 2021, 1, 'M01', 31, 0, 0, 0, 0, 0, 0); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 2, 28), 2021, 2, 'M02', 28, 0, 0, 0, 0, 0, 0); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 3, 31), 2021, 3, 'M03', 31, 0, 0, 0, 0, 0, 0); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 4, 30), 2021, 4, 'M04', 30, 0, 0, 0, 0, 0, 0); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 5, 31), 2021, 5, 'M05', 31, 0, 0, 0, 0, 0, 0); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 6, 30), 2021, 6, 'M06', 30, 0, 0, 0, 0, 0, 0); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 31), 2021, 7, 'M07', 31, 0, 0, 0, 0, 0, 0); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 8, 31), 2021, 8, 'M08', 31, 0, 0, 0, 0, 0, 0); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 9, 30), 2021, 9, 'M09', 30, 0, 0, 0, 0, 0, 0); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 10, 31), 2021, 10, 'M10', 31, 0, 0, 0, 0, 0, 0); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 11, 30), 2021, 11, 'M11', 30, 0, 0, 0, 0, 0, 0); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 12, 31), 2021, 12, 'M12', 31, 0, 0, 0, 0, 0, 0); +assert.throws(RangeError, () => new Temporal.PlainDateTime(1900, 2, 29)); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2000, 2, 29), 2000, 2, 'M02', 29, 0, 0, 0, 0, 0, 0); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2001, 2, 29)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2002, 2, 29)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2003, 2, 29)); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2004, 2, 29), 2004, 2, 'M02', 29, 0, 0, 0, 0, 0, 0); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2100, 2, 29)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, 1, 32)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, 2, 29)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, 3, 32)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, 4, 31)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, 5, 32)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, 6, 31)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, 7, 32)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, 8, 32)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, 9, 31)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, 10, 32)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, 11, 31)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, 12, 32)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(Infinity, 12, 1)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(-Infinity, 12, 1)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, 12, Infinity)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, 12, -Infinity)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, -Infinity, 1)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, Infinity, 1)); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 9), 2021, 7, 'M07', 9, 0, 0, 0, 0, 0, 0); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 9, 1, 2, 3, 4, 5, 6), 2021, 7, 'M07', 9, 1, 2, 3, 4, 5, 6); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 9, 1, 2, 3, 4, 5), 2021, 7, 'M07', 9, 1, 2, 3, 4, 5, 0); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 9, 1, 2, 3, 4), 2021, 7, 'M07', 9, 1, 2, 3, 4, 0, 0); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 9, 1, 2, 3), 2021, 7, 'M07', 9, 1, 2, 3, 0, 0, 0); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 9, 1, 2), 2021, 7, 'M07', 9, 1, 2, 0, 0, 0, 0); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 9, 1, 0), 2021, 7, 'M07', 9, 1, 0, 0, 0, 0, 0); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 9, 0, 0, 0, 0, 0, 0), 2021, 7, 'M07', 9, 0, 0, 0, 0, 0, 0); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 9, 23, 59, 59, 999, 999, 999), 2021, 7, 'M07', 9, 23, 59, 59, 999, 999, 999); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 9, true, false, undefined, true), 2021, 7, 'M07', 9, 1, 0, 0, 1, 0, 0); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 9, 11.9, 12.8, 13.7, 14.6, 15.5, 1.999999), 2021, 7, 'M07', 9, 11, 12, 13, 14, 15, 1); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, 7, 9, -Infinity)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, 7, 9, Infinity)); +assert.throws(TypeError, () => new Temporal.PlainDateTime(2021, 7, 9, Symbol(2))); +assert.throws(TypeError, () => new Temporal.PlainDateTime(2021, 7, 9, 3n)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, 7, 9, 24)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, 7, 9, 0, 60)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, 7, 9, 0, 0, 60)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, 7, 9, 0, 0, 0, 1000)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, 7, 9, 0, 0, 0, 0, 1000)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, 7, 9, 0, 0, 0, 0, 0, 1000)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, 7, 9, -1)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, 7, 9, 0, -1)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, 7, 9, 0, 0, -1)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, 7, 9, 0, 0, 0, -1)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, 7, 9, 0, 0, 0, 0, -1)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, 7, 9, 0, 0, 0, 0, 0, -1)); diff --git a/test/staging/Temporal/v8/plain-date-time-equals.js b/test/staging/Temporal/v8/plain-date-time-equals.js new file mode 100644 index 0000000000..510c195678 --- /dev/null +++ b/test/staging/Temporal/v8/plain-date-time-equals.js @@ -0,0 +1,34 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from plain-date-time-equals test + in V8's mjsunit test plain-date-time-equals.js +features: [Temporal] +---*/ + +let d1 = new Temporal.PlainDateTime(2021, 2, 28, 11, 12, 13); +let d2 = Temporal.PlainDateTime.from({ + year: 2021, + month: 2, + day: 28, + hour: 11, + minute: 12, + second: 13 +}); +let d3 = Temporal.PlainDateTime.from({ + year: 2021, + month: 2, + day: 28, + hour: 11, + minute: 12, + second: 13, + nanosecond: 1 +}); +assert(d1.equals(d2)); +assert(!d1.equals(d3)); +assert(!d2.equals(d3)); +let badDate = { equals: d1.equals }; +assert.throws(TypeError, () => badDate.equals(d1)); diff --git a/test/staging/Temporal/v8/plain-date-time-from.js b/test/staging/Temporal/v8/plain-date-time-from.js new file mode 100644 index 0000000000..de7c377a67 --- /dev/null +++ b/test/staging/Temporal/v8/plain-date-time-from.js @@ -0,0 +1,149 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from plain-date-time-from test + in V8's mjsunit test plain-date-time-from.js +features: [Temporal] +---*/ + +let d1 = Temporal.Now.plainDateTimeISO(); +[ + true, + false, + 'string is invalid', + Symbol(), + 123, + 456n, + Infinity, + NaN, + null +].forEach(function (invalidOptions) { + assert.throws(TypeError, () => Temporal.PlainDateTime.from(d1, invalidOptions)); +}); +assert.throws(RangeError, () => Temporal.PlainDateTime.from(d1, { overflow: 'invalid overflow' })); +[ + undefined, + {}, + { overflow: 'constrain' }, + { overflow: 'reject' } +].forEach(function (validOptions) { + let d = new Temporal.PlainDateTime(1, 2, 3, 4, 5, 6, 7, 8, 9); + let d2 = Temporal.PlainDateTime.from(d, validOptions); + assert.sameValue(d2.year, 1); + assert.sameValue(d2.month, 2); + assert.sameValue(d2.monthCode, 'M02'); + assert.sameValue(d2.day, 3); + assert.sameValue(d2.hour, 4); + assert.sameValue(d2.minute, 5); + assert.sameValue(d2.second, 6); + assert.sameValue(d2.millisecond, 7); + assert.sameValue(d2.microsecond, 8); + assert.sameValue(d2.nanosecond, 9); + assert.sameValue(d2.calendarId, 'iso8601'); +}); +[ + undefined, + {}, + { overflow: 'constrain' }, + { overflow: 'reject' } +].forEach(function (validOptions) { + let d3 = Temporal.PlainDateTime.from({ + year: 9, + month: 8, + day: 7, + hour: 6, + minute: 5, + second: 4, + millisecond: 3, + microsecond: 2, + nanosecond: 1 + }, validOptions); + assert.sameValue(d3.year, 9); + assert.sameValue(d3.month, 8); + assert.sameValue(d3.monthCode, 'M08'); + assert.sameValue(d3.day, 7); + assert.sameValue(d3.hour, 6); + assert.sameValue(d3.minute, 5); + assert.sameValue(d3.second, 4); + assert.sameValue(d3.millisecond, 3); + assert.sameValue(d3.microsecond, 2); + assert.sameValue(d3.nanosecond, 1); + assert.sameValue(d3.calendarId, 'iso8601'); +}); +[ + undefined, + {}, + { overflow: 'constrain' } +].forEach(function (validOptions) { + let d4 = Temporal.PlainDateTime.from({ + year: 9, + month: 14, + day: 32, + hour: 24, + minute: 60, + second: 60, + millisecond: 1000, + microsecond: 1000, + nanosecond: 1000 + }, validOptions); + assert.sameValue(d4.year, 9); + assert.sameValue(d4.month, 12); + assert.sameValue(d4.monthCode, 'M12'); + assert.sameValue(d4.day, 31); + assert.sameValue(d4.hour, 23); + assert.sameValue(d4.minute, 59); + assert.sameValue(d4.second, 59); + assert.sameValue(d4.millisecond, 999); + assert.sameValue(d4.microsecond, 999); + assert.sameValue(d4.nanosecond, 999); + assert.sameValue(d4.calendarId, 'iso8601'); +}); +assert.throws(RangeError, () => Temporal.PlainDateTime.from({ + year: 9, + month: 14, + day: 30 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainDateTime.from({ + year: 9, + month: 12, + day: 32 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainDateTime.from({ + year: 9, + month: 12, + day: 31, + hour: 24 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainDateTime.from({ + year: 9, + month: 12, + day: 31, + minute: 60 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainDateTime.from({ + year: 9, + month: 12, + day: 31, + second: 60 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainDateTime.from({ + year: 9, + month: 12, + day: 31, + millisecond: 1000 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainDateTime.from({ + year: 9, + month: 12, + day: 31, + microsecond: 1000 +}, { overflow: 'reject' })); +assert.throws(RangeError, () => Temporal.PlainDateTime.from({ + year: 9, + month: 12, + day: 31, + nanosecond: 1000 +}, { overflow: 'reject' })); diff --git a/test/staging/Temporal/v8/plain-date-time-get-iso-fields.js b/test/staging/Temporal/v8/plain-date-time-get-iso-fields.js new file mode 100644 index 0000000000..759a5b1eb8 --- /dev/null +++ b/test/staging/Temporal/v8/plain-date-time-get-iso-fields.js @@ -0,0 +1,26 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from plain-date-time-get-iso-fields test + in V8's mjsunit test plain-date-time-get-iso-fields.js +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(1, 2, 3, 4, 5, 6, 7, 8, 9), 1, 2, 'M02', 3, 4, 5, 6, 7, 8, 9); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(1, 2, 3, 4, 5, 6, 7, 8), 1, 2, 'M02', 3, 4, 5, 6, 7, 8, 0); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(1, 2, 3, 4, 5, 6, 7), 1, 2, 'M02', 3, 4, 5, 6, 7, 0, 0); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(1, 2, 3, 4, 5, 6), 1, 2, 'M02', 3, 4, 5, 6, 0, 0, 0); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(1, 2, 3, 4, 5), 1, 2, 'M02', 3, 4, 5, 0, 0, 0, 0); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(1, 2, 3, 4), 1, 2, 'M02', 3, 4, 0, 0, 0, 0, 0); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(1, 2, 3), 1, 2, 'M02', 3, 0, 0, 0, 0, 0, 0); +assert.throws(RangeError, () => new Temporal.PlainDateTime(1, 2)); +assert.throws(RangeError, () => new Temporal.PlainDateTime(1)); +assert.throws(RangeError, () => new Temporal.PlainDateTime()); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(-25406, 1, 1), -25406, 1, 'M01', 1, 0, 0, 0, 0, 0, 0); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(29345, 12, 31, 23, 59, 59, 999, 999, 999), 29345, 12, 'M12', 31, 23, 59, 59, 999, 999, 999); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(false, true, true, undefined, true), 0, 1, 'M01', 1, 0, 1, 0, 0, 0, 0, 0); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(11.9, 12.8, 13.7, 14.6, 15.5, 16.6, 17.7, 18.8, 1.999999), 11, 12, 'M12', 13, 14, 15, 16, 17, 18, 1); diff --git a/test/staging/Temporal/v8/plain-date-time-subtract.js b/test/staging/Temporal/v8/plain-date-time-subtract.js new file mode 100644 index 0000000000..a3d660e390 --- /dev/null +++ b/test/staging/Temporal/v8/plain-date-time-subtract.js @@ -0,0 +1,36 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from plain-date-time-subtract test + in V8's mjsunit test plain-date-time-subtract.js +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 1, 2, 3, 4, 5, 6).subtract('-PT9H8M7.080090010S'), 2021, 7, 'M07', 20, 10, 10, 10, 84, 95, 16); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 0, 0, 0, 0, 1, 996).subtract('-PT0.0000071S'), 2021, 7, 'M07', 20, 0, 0, 0, 0, 9, 96); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 0, 0, 0, 1, 996).subtract('-PT0.0071S'), 2021, 7, 'M07', 20, 0, 0, 0, 9, 96, 0); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 0, 0, 1, 996).subtract('-PT7.1S'), 2021, 7, 'M07', 20, 0, 0, 9, 96, 0, 0, 0); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 0, 1, 59).subtract('-PT5M7S'), 2021, 7, 'M07', 20, 0, 7, 6, 0, 0, 0); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 1, 59).subtract('-PT5H7M'), 2021, 7, 'M07', 20, 7, 6, 0, 0, 0, 0); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 19).subtract('-PT8H'), 2021, 7, 'M07', 21, 3, 0, 0, 0, 0, 0); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 21, 52, 53, 994, 995, 996).subtract('-PT5H13M11.404303202S'), 2021, 7, 'M07', 21, 3, 6, 5, 399, 299, 198); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 0, 0, 0, 0, 0, 995).subtract('-PT0.000000006S'), 2021, 7, 'M07', 20, 0, 0, 0, 0, 1, 1); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 0, 0, 0, 0, 0, 995).subtract('-PT0.00000006S'), 2021, 7, 'M07', 20, 0, 0, 0, 0, 1, 55); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 0, 0, 0, 0, 0, 995).subtract('-PT0.0000006S'), 2021, 7, 'M07', 20, 0, 0, 0, 0, 1, 595); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 1, 2, 3, 4, 5, 6).subtract('PT0.000000007S'), 2021, 7, 'M07', 20, 1, 2, 3, 4, 4, 999); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 1, 2, 3, 4, 5, 6).subtract('PT0.000005007S'), 2021, 7, 'M07', 20, 1, 2, 3, 3, 999, 999); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 1, 2, 3, 4, 5, 6).subtract('PT0.004005007S'), 2021, 7, 'M07', 20, 1, 2, 2, 999, 999, 999); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 1, 2, 3, 4, 5, 6).subtract('PT0.005006007S'), 2021, 7, 'M07', 20, 1, 2, 2, 998, 998, 999); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 1, 2, 3, 4, 5, 6).subtract('PT4.005006007S'), 2021, 7, 'M07', 20, 1, 1, 58, 998, 998, 999); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 1, 2, 3, 4, 5, 6).subtract('PT4S'), 2021, 7, 'M07', 20, 1, 1, 59, 4, 5, 6); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 1, 2, 3, 4, 5, 6).subtract('PT5M'), 2021, 7, 'M07', 20, 0, 57, 3, 4, 5, 6); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 1, 2, 3, 4, 5, 6).subtract('PT1H5M'), 2021, 7, 'M07', 19, 23, 57, 3, 4, 5, 6); +TemporalHelpers.assertPlainDateTime(new Temporal.PlainDateTime(2021, 7, 20, 1, 2, 3, 4, 5, 6).subtract('PT1H5M4S'), 2021, 7, 'M07', 19, 23, 56, 59, 4, 5, 6); +let goodDateTime = new Temporal.PlainDateTime(2021, 7, 20, 1, 2, 3); +let badDateTime = { subtract: goodDateTime.subtract }; +assert.throws(TypeError, () => badDateTime.subtract('PT30M')); +assert.throws(RangeError, () => new Temporal.PlainDateTime(2021, 7, 20, 1, 2, 3).subtract('bad duration')); diff --git a/test/staging/Temporal/v8/plain-date-time-to-json.js b/test/staging/Temporal/v8/plain-date-time-to-json.js new file mode 100644 index 0000000000..07adf4e2f6 --- /dev/null +++ b/test/staging/Temporal/v8/plain-date-time-to-json.js @@ -0,0 +1,52 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from plain-date-time-to-json test + in V8's mjsunit test plain-date-time-to-json.js +features: [Temporal] +---*/ + +assert.sameValue(new Temporal.PlainDateTime(2021, 7, 1).toJSON(), '2021-07-01T00:00:00'); +assert.sameValue(new Temporal.PlainDateTime(9999, 12, 31).toJSON(), '9999-12-31T00:00:00'); +assert.sameValue(new Temporal.PlainDateTime(1000, 1, 1).toJSON(), '1000-01-01T00:00:00'); +assert.sameValue(new Temporal.PlainDateTime(10000, 1, 1).toJSON(), '+010000-01-01T00:00:00'); +assert.sameValue(new Temporal.PlainDateTime(25021, 7, 1).toJSON(), '+025021-07-01T00:00:00'); +assert.sameValue(new Temporal.PlainDateTime(999, 12, 31).toJSON(), '0999-12-31T00:00:00'); +assert.sameValue(new Temporal.PlainDateTime(99, 8, 1).toJSON(), '0099-08-01T00:00:00'); +assert.sameValue(new Temporal.PlainDateTime(-20, 9, 30).toJSON(), '-000020-09-30T00:00:00'); +assert.sameValue(new Temporal.PlainDateTime(-2021, 7, 1).toJSON(), '-002021-07-01T00:00:00'); +assert.sameValue(new Temporal.PlainDateTime(-22021, 7, 1).toJSON(), '-022021-07-01T00:00:00'); +assert.sameValue(new Temporal.PlainDateTime(2021, 7, 1, 2, 3, 4).toJSON(), '2021-07-01T02:03:04'); +assert.sameValue(new Temporal.PlainDateTime(2021, 7, 1, 0, 3, 4).toJSON(), '2021-07-01T00:03:04'); +assert.sameValue(new Temporal.PlainDateTime(2021, 7, 1, 0, 0, 4).toJSON(), '2021-07-01T00:00:04'); +assert.sameValue(new Temporal.PlainDateTime(2021, 7, 1, 0, 0, 0).toJSON(), '2021-07-01T00:00:00'); +assert.sameValue(new Temporal.PlainDateTime(2021, 7, 1, 2, 0, 0).toJSON(), '2021-07-01T02:00:00'); +assert.sameValue(new Temporal.PlainDateTime(2021, 7, 1, 2, 3, 0).toJSON(), '2021-07-01T02:03:00'); +assert.sameValue(new Temporal.PlainDateTime(2021, 7, 1, 23, 59, 59).toJSON(), '2021-07-01T23:59:59'); +assert.sameValue(new Temporal.PlainDateTime(2021, 7, 1, 0, 59, 59).toJSON(), '2021-07-01T00:59:59'); +assert.sameValue(new Temporal.PlainDateTime(2021, 7, 1, 0, 59, 59, 0, 0, 1).toJSON(), '2021-07-01T00:59:59.000000001'); +assert.sameValue(new Temporal.PlainDateTime(2021, 7, 1, 0, 59, 59, 0, 8, 9).toJSON(), '2021-07-01T00:59:59.000008009'); +assert.sameValue(new Temporal.PlainDateTime(2021, 7, 1, 0, 59, 59, 7, 8, 9).toJSON(), '2021-07-01T00:59:59.007008009'); +assert.sameValue(new Temporal.PlainDateTime(2021, 7, 1, 0, 59, 59, 0, 0, 90).toJSON(), '2021-07-01T00:59:59.00000009'); +assert.sameValue(new Temporal.PlainDateTime(2021, 7, 1, 0, 59, 59, 0, 0, 900).toJSON(), '2021-07-01T00:59:59.0000009'); +assert.sameValue(new Temporal.PlainDateTime(2021, 7, 1, 0, 59, 59, 0, 8).toJSON(), '2021-07-01T00:59:59.000008'); +assert.sameValue(new Temporal.PlainDateTime(2021, 7, 1, 0, 59, 59, 0, 8, 0).toJSON(), '2021-07-01T00:59:59.000008'); +assert.sameValue(new Temporal.PlainDateTime(2021, 7, 1, 0, 59, 59, 0, 80).toJSON(), '2021-07-01T00:59:59.00008'); +assert.sameValue(new Temporal.PlainDateTime(2021, 7, 1, 0, 59, 59, 0, 80, 0).toJSON(), '2021-07-01T00:59:59.00008'); +assert.sameValue(new Temporal.PlainDateTime(2021, 7, 1, 0, 59, 59, 0, 800).toJSON(), '2021-07-01T00:59:59.0008'); +assert.sameValue(new Temporal.PlainDateTime(2021, 7, 1, 0, 59, 59, 0, 800, 0).toJSON(), '2021-07-01T00:59:59.0008'); +assert.sameValue(new Temporal.PlainDateTime(2021, 7, 1, 0, 59, 59, 7, 0, 0).toJSON(), '2021-07-01T00:59:59.007'); +assert.sameValue(new Temporal.PlainDateTime(2021, 7, 1, 0, 59, 59, 7, 0).toJSON(), '2021-07-01T00:59:59.007'); +assert.sameValue(new Temporal.PlainDateTime(2021, 7, 1, 0, 59, 59, 7).toJSON(), '2021-07-01T00:59:59.007'); +assert.sameValue(new Temporal.PlainDateTime(2021, 7, 1, 0, 59, 59, 70, 0, 0).toJSON(), '2021-07-01T00:59:59.07'); +assert.sameValue(new Temporal.PlainDateTime(2021, 7, 1, 0, 59, 59, 70, 0).toJSON(), '2021-07-01T00:59:59.07'); +assert.sameValue(new Temporal.PlainDateTime(2021, 7, 1, 0, 59, 59, 70).toJSON(), '2021-07-01T00:59:59.07'); +assert.sameValue(new Temporal.PlainDateTime(2021, 7, 1, 0, 59, 59, 700, 0, 0).toJSON(), '2021-07-01T00:59:59.7'); +assert.sameValue(new Temporal.PlainDateTime(2021, 7, 1, 0, 59, 59, 700, 0).toJSON(), '2021-07-01T00:59:59.7'); +assert.sameValue(new Temporal.PlainDateTime(2021, 7, 1, 0, 59, 59, 700).toJSON(), '2021-07-01T00:59:59.7'); +assert.sameValue(new Temporal.PlainDateTime(2021, 7, 1, 0, 59, 59, 0, 876).toJSON(), '2021-07-01T00:59:59.000876'); +assert.sameValue(new Temporal.PlainDateTime(2021, 7, 1, 0, 59, 59, 876).toJSON(), '2021-07-01T00:59:59.876'); +assert.sameValue(new Temporal.PlainDateTime(2021, 7, 1, 0, 59, 59, 0, 0, 876).toJSON(), '2021-07-01T00:59:59.000000876'); diff --git a/test/staging/Temporal/v8/plain-date-time-to-plain-date.js b/test/staging/Temporal/v8/plain-date-time-to-plain-date.js new file mode 100644 index 0000000000..d1d90acf43 --- /dev/null +++ b/test/staging/Temporal/v8/plain-date-time-to-plain-date.js @@ -0,0 +1,16 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from plain-date-time-to-plain-date test + in V8's mjsunit test plain-date-time-to-plain-date.js +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +let d1 = new Temporal.PlainDateTime(2021, 12, 11, 1, 2, 3, 4, 5, 6); +let badDateTime = { toPlainDate: d1.toPlainDate }; +assert.throws(TypeError, () => badDateTime.toPlainDate()); +TemporalHelpers.assertPlainDate(d1.toPlainDate(), 2021, 12, 'M12', 11); diff --git a/test/staging/Temporal/v8/plain-date-time-to-plain-time.js b/test/staging/Temporal/v8/plain-date-time-to-plain-time.js new file mode 100644 index 0000000000..3b486849d0 --- /dev/null +++ b/test/staging/Temporal/v8/plain-date-time-to-plain-time.js @@ -0,0 +1,16 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from plain-date-time-to-plain-time test + in V8's mjsunit test plain-date-time-to-plain-time.js +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +let d1 = new Temporal.PlainDateTime(2021, 12, 11, 1, 2, 3, 4, 5, 6); +let badDateTime = { toPlainTime: d1.toPlainTime }; +assert.throws(TypeError, () => badDateTime.toPlainTime()); +TemporalHelpers.assertPlainTime(d1.toPlainTime(), 1, 2, 3, 4, 5, 6); diff --git a/test/staging/Temporal/v8/plain-date-time-value-of.js b/test/staging/Temporal/v8/plain-date-time-value-of.js new file mode 100644 index 0000000000..546a91fcb0 --- /dev/null +++ b/test/staging/Temporal/v8/plain-date-time-value-of.js @@ -0,0 +1,13 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from plain-date-time-valueOf test + in V8's mjsunit test plain-date-time-valueOf.js +features: [Temporal] +---*/ + +let d1 = Temporal.Now.plainDateTimeISO(); +assert.throws(TypeError, () => d1.valueOf()); diff --git a/test/staging/Temporal/v8/plain-date-time-with-calendar.js b/test/staging/Temporal/v8/plain-date-time-with-calendar.js new file mode 100644 index 0000000000..d9b051e51e --- /dev/null +++ b/test/staging/Temporal/v8/plain-date-time-with-calendar.js @@ -0,0 +1,22 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from plain-date-time-with-calendar test + in V8's mjsunit test plain-date-time-with-calendar.js +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +let d1 = new Temporal.PlainDateTime(1911, 10, 10, 4, 5, 6, 7, 8, 9); +let badDateTime = { withCalendar: d1.withCalendar }; +assert.throws(TypeError, () => badDateTime.withCalendar('iso8601')); + +let d2 = d1.withCalendar('roc'); +assert.sameValue('roc', d2.calendarId); +TemporalHelpers.assertPlainDateTime(d2, 0, 10, 'M10', 10, 4, 5, 6, 7, 8, 9, '', 'broc', 1); +let d3 = d2.withCalendar('iso8601'); +assert.sameValue('iso8601', d3.calendarId); +TemporalHelpers.assertPlainDateTime(d3, 1911, 10, 'M10', 10, 4, 5, 6, 7, 8, 9); diff --git a/test/staging/Temporal/v8/plain-date-time-with-plain-time.js b/test/staging/Temporal/v8/plain-date-time-with-plain-time.js new file mode 100644 index 0000000000..d80be907e0 --- /dev/null +++ b/test/staging/Temporal/v8/plain-date-time-with-plain-time.js @@ -0,0 +1,34 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from plain-date-time-with-plain-time test + in V8's mjsunit test plain-date-time-with-plain-time.js +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +let d1 = new Temporal.PlainDateTime(1911, 10, 10, 4, 5, 6, 7, 8, 9); +let badDate = { withPlainTime: d1.withPlainTime }; +assert.throws(TypeError, () => badDate.withPlainTime()); +let timeRecord = { + hour: 9, + minute: 8, + second: 7, + millisecond: 6, + microsecond: 5, + nanosecond: 4 +}; +TemporalHelpers.assertPlainDateTime(d1.withPlainTime(timeRecord), 1911, 10, 'M10', 10, 9, 8, 7, 6, 5, 4); + +let d3 = new Temporal.PlainDateTime(2020, 3, 15, 4, 5, 6, 7, 8, 9, 'roc'); +TemporalHelpers.assertPlainDateTime(d3.withPlainTime(timeRecord), 109, 3, 'M03', 15, 9, 8, 7, 6, 5, 4, '', 'roc', 109); +assert.throws(TypeError, () => d1.withPlainTime(null)); +assert.throws(TypeError, () => d1.withPlainTime(true)); +assert.throws(TypeError, () => d1.withPlainTime(false)); +assert.throws(TypeError, () => d1.withPlainTime(Infinity)); +assert.throws(RangeError, () => d1.withPlainTime('invalid iso8601 string')); +assert.throws(TypeError, () => d1.withPlainTime(123)); +assert.throws(TypeError, () => d1.withPlainTime(456n)); diff --git a/test/staging/Temporal/v8/plain-date-time-with.js b/test/staging/Temporal/v8/plain-date-time-with.js new file mode 100644 index 0000000000..8ab01888a7 --- /dev/null +++ b/test/staging/Temporal/v8/plain-date-time-with.js @@ -0,0 +1,56 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from plain-date-time-with test + in V8's mjsunit test plain-date-time-with.js +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +let d1 = new Temporal.PlainDateTime(1911, 11, 10, 4, 5, 6, 7, 8, 9); +let badDate = { with: d1.with }; +assert.throws(TypeError, () => badDate.with()); +assert.throws(TypeError, () => d1.with(null)); +assert.throws(TypeError, () => d1.with(undefined)); +assert.throws(TypeError, () => d1.with('string is invalid')); +assert.throws(TypeError, () => d1.with(true)); +assert.throws(TypeError, () => d1.with(false)); +assert.throws(TypeError, () => d1.with(NaN)); +assert.throws(TypeError, () => d1.with(Infinity)); +assert.throws(TypeError, () => d1.with(123)); +assert.throws(TypeError, () => d1.with(456n)); +assert.throws(TypeError, () => d1.with(Symbol())); +let date = Temporal.Now.plainDateISO(); +assert.throws(TypeError, () => d1.with(date)); +let dateTime = Temporal.Now.plainDateTimeISO(); +assert.throws(TypeError, () => d1.with(dateTime)); +let time = Temporal.Now.plainTimeISO(); +assert.throws(TypeError, () => d1.with(time)); +let ym = new Temporal.PlainYearMonth(2021, 7); +assert.throws(TypeError, () => d1.with(ym)); +let md = new Temporal.PlainMonthDay(12, 25); +assert.throws(TypeError, () => d1.with(md)); +assert.throws(TypeError, () => d1.with({ calendar: 'iso8601' })); +assert.throws(TypeError, () => d1.with({ timeZone: 'UTC' })); +assert.throws(TypeError, () => d1.with({ day: 3 }, null)); +assert.throws(TypeError, () => d1.with({ day: 3 }, 'string is invalid')); +assert.throws(TypeError, () => d1.with({ day: 3 }, true)); +assert.throws(TypeError, () => d1.with({ day: 3 }, false)); +assert.throws(TypeError, () => d1.with({ day: 3 }, 123)); +assert.throws(TypeError, () => d1.with({ day: 3 }, 456n)); +assert.throws(TypeError, () => d1.with({ day: 3 }, Symbol())); +assert.throws(TypeError, () => d1.with({ day: 3 }, NaN)); +assert.throws(TypeError, () => d1.with({ day: 3 }, Infinity)); +TemporalHelpers.assertPlainDateTime(d1.with({ year: 2021 }), 2021, 11, 'M11', 10, 4, 5, 6, 7, 8, 9); +TemporalHelpers.assertPlainDateTime(d1.with({ month: 3 }), 1911, 3, 'M03', 10, 4, 5, 6, 7, 8, 9); +TemporalHelpers.assertPlainDateTime(d1.with({ monthCode: 'M05' }), 1911, 5, 'M05', 10, 4, 5, 6, 7, 8, 9); +TemporalHelpers.assertPlainDateTime(d1.with({ day: 1 }), 1911, 11, 'M11', 1, 4, 5, 6, 7, 8, 9); +TemporalHelpers.assertPlainDateTime(d1.with({ hour: 2 }), 1911, 11, 'M11', 10, 2, 5, 6, 7, 8, 9); +TemporalHelpers.assertPlainDateTime(d1.with({ minute: 3 }), 1911, 11, 'M11', 10, 4, 3, 6, 7, 8, 9); +TemporalHelpers.assertPlainDateTime(d1.with({ second: 4 }), 1911, 11, 'M11', 10, 4, 5, 4, 7, 8, 9); +TemporalHelpers.assertPlainDateTime(d1.with({ millisecond: 5 }), 1911, 11, 'M11', 10, 4, 5, 6, 5, 8, 9); +TemporalHelpers.assertPlainDateTime(d1.with({ microsecond: 6 }), 1911, 11, 'M11', 10, 4, 5, 6, 7, 6, 9); +TemporalHelpers.assertPlainDateTime(d1.with({ nanosecond: 7 }), 1911, 11, 'M11', 10, 4, 5, 6, 7, 8, 7); diff --git a/test/staging/Temporal/v8/plain-date-to-json.js b/test/staging/Temporal/v8/plain-date-to-json.js new file mode 100644 index 0000000000..97639e329e --- /dev/null +++ b/test/staging/Temporal/v8/plain-date-to-json.js @@ -0,0 +1,21 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from plain-date-to-json test + in V8's mjsunit test plain-date-to-json.js +features: [Temporal] +---*/ + +assert.sameValue(new Temporal.PlainDate(2021, 7, 1).toJSON(), '2021-07-01'); +assert.sameValue(new Temporal.PlainDate(9999, 12, 31).toJSON(), '9999-12-31'); +assert.sameValue(new Temporal.PlainDate(1000, 1, 1).toJSON(), '1000-01-01'); +assert.sameValue(new Temporal.PlainDate(99, 8, 1).toJSON(), '0099-08-01'); +assert.sameValue(new Temporal.PlainDate(999, 12, 31).toJSON(), '0999-12-31'); +assert.sameValue(new Temporal.PlainDate(10000, 1, 1).toJSON(), '+010000-01-01'); +assert.sameValue(new Temporal.PlainDate(25021, 7, 1).toJSON(), '+025021-07-01'); +assert.sameValue(new Temporal.PlainDate(-20, 9, 30).toJSON(), '-000020-09-30'); +assert.sameValue(new Temporal.PlainDate(-2021, 7, 1).toJSON(), '-002021-07-01'); +assert.sameValue(new Temporal.PlainDate(-22021, 7, 1).toJSON(), '-022021-07-01'); diff --git a/test/staging/Temporal/v8/plain-date-to-plain-date-time.js b/test/staging/Temporal/v8/plain-date-to-plain-date-time.js new file mode 100644 index 0000000000..c47043159e --- /dev/null +++ b/test/staging/Temporal/v8/plain-date-to-plain-date-time.js @@ -0,0 +1,40 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from plain-date-to-plain-date-time test + in V8's mjsunit test plain-date-to-plain-date-time.js +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +let d1 = new Temporal.PlainDate(2021, 12, 11); +let badDate = { toPlainDateTime: d1.toPlainDateTime }; +assert.throws(TypeError, () => badDate.toPlainDateTime()); +assert.throws(TypeError, () => d1.toPlainDateTime(null)); +assert.throws(RangeError, () => d1.toPlainDateTime('string is invalid')); +assert.throws(TypeError, () => d1.toPlainDateTime(true)); +assert.throws(TypeError, () => d1.toPlainDateTime(false)); +assert.throws(TypeError, () => d1.toPlainDateTime(NaN)); +assert.throws(TypeError, () => d1.toPlainDateTime(Infinity)); +assert.throws(TypeError, () => d1.toPlainDateTime(123)); +assert.throws(TypeError, () => d1.toPlainDateTime(456n)); +assert.throws(TypeError, () => d1.toPlainDateTime(Symbol())); +assert.throws(TypeError, () => d1.toPlainDateTime({})); +TemporalHelpers.assertPlainDateTime(d1.toPlainDateTime({ hour: 23 }), 2021, 12, 'M12', 11, 23, 0, 0, 0, 0, 0); +TemporalHelpers.assertPlainDateTime(d1.toPlainDateTime({ minute: 23 }), 2021, 12, 'M12', 11, 0, 23, 0, 0, 0, 0); +TemporalHelpers.assertPlainDateTime(d1.toPlainDateTime({ second: 23 }), 2021, 12, 'M12', 11, 0, 0, 23, 0, 0, 0); +TemporalHelpers.assertPlainDateTime(d1.toPlainDateTime({ millisecond: 23 }), 2021, 12, 'M12', 11, 0, 0, 0, 23, 0, 0); +TemporalHelpers.assertPlainDateTime(d1.toPlainDateTime({ microsecond: 23 }), 2021, 12, 'M12', 11, 0, 0, 0, 0, 23, 0); +TemporalHelpers.assertPlainDateTime(d1.toPlainDateTime({ nanosecond: 23 }), 2021, 12, 'M12', 11, 0, 0, 0, 0, 0, 23); +TemporalHelpers.assertPlainDateTime(d1.toPlainDateTime(), 2021, 12, 'M12', 11, 0, 0, 0, 0, 0, 0); +TemporalHelpers.assertPlainDateTime(d1.toPlainDateTime({ + hour: 9, + minute: 8, + second: 7, + millisecond: 6, + microsecond: 5, + nanosecond: 4 +}), 2021, 12, 'M12', 11, 9, 8, 7, 6, 5, 4); diff --git a/test/staging/Temporal/v8/plain-date-to-plain-month-day.js b/test/staging/Temporal/v8/plain-date-to-plain-month-day.js new file mode 100644 index 0000000000..a0b5f44d4e --- /dev/null +++ b/test/staging/Temporal/v8/plain-date-to-plain-month-day.js @@ -0,0 +1,16 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from plain-date-to-plain-month-day test + in V8's mjsunit test plain-date-to-plain-month-day.js +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +let d1 = new Temporal.PlainDate(2021, 12, 11); +let badDateTime = { toPlainMonthDay: d1.toPlainMonthDay }; +assert.throws(TypeError, () => badDateTime.toPlainMonthDay()); +TemporalHelpers.assertPlainMonthDay(d1.toPlainMonthDay(), 'M12', 11); diff --git a/test/staging/Temporal/v8/plain-date-to-plain-year-month.js b/test/staging/Temporal/v8/plain-date-to-plain-year-month.js new file mode 100644 index 0000000000..d39a20ff88 --- /dev/null +++ b/test/staging/Temporal/v8/plain-date-to-plain-year-month.js @@ -0,0 +1,16 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from plain-date-to-plain-year-month test + in V8's mjsunit test plain-date-to-plain-year-month.js +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +let d1 = new Temporal.PlainDate(2021, 12, 11); +let badDate = { toPlainYearMonth: d1.toPlainYearMonth }; +assert.throws(TypeError, () => badDate.toPlainYearMonth()); +TemporalHelpers.assertPlainYearMonth(d1.toPlainYearMonth(), 2021, 12, 'M12'); diff --git a/test/staging/Temporal/v8/plain-date-value-of.js b/test/staging/Temporal/v8/plain-date-value-of.js new file mode 100644 index 0000000000..8025df786c --- /dev/null +++ b/test/staging/Temporal/v8/plain-date-value-of.js @@ -0,0 +1,13 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from plain-date-valueOf test + in V8's mjsunit test plain-date-valueOf.js +features: [Temporal] +---*/ + +let d1 = Temporal.Now.plainDateISO(); +assert.throws(TypeError, () => d1.valueOf()); diff --git a/test/staging/Temporal/v8/plain-date-with-calendar.js b/test/staging/Temporal/v8/plain-date-with-calendar.js new file mode 100644 index 0000000000..2edbb15eb0 --- /dev/null +++ b/test/staging/Temporal/v8/plain-date-with-calendar.js @@ -0,0 +1,22 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from plain-date-with-calendar test + in V8's mjsunit test plain-date-with-calendar.js +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +let d1 = new Temporal.PlainDate(1911, 10, 10); +let badDate = { withCalendar: d1.withCalendar }; +assert.throws(TypeError, () => badDate.withCalendar('iso8601')); + +let d2 = d1.withCalendar('roc'); +assert.sameValue('roc', d2.calendarId); +TemporalHelpers.assertPlainDate(d2, 0, 10, 'M10', 10, '', 'broc', 1); +let d3 = d2.withCalendar('iso8601'); +assert.sameValue('iso8601', d3.calendarId); +TemporalHelpers.assertPlainDate(d3, 1911, 10, 'M10', 10); diff --git a/test/staging/Temporal/v8/plain-date-with.js b/test/staging/Temporal/v8/plain-date-with.js new file mode 100644 index 0000000000..b715dc2f8a --- /dev/null +++ b/test/staging/Temporal/v8/plain-date-with.js @@ -0,0 +1,58 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: pending +description: > + Automatically ported from plain-date-with test + in V8's mjsunit test plain-date-with.js +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +let d1 = new Temporal.PlainDate(1911, 10, 10); +TemporalHelpers.assertPlainDate(d1.with({ year: 2021 }), 2021, 10, 'M10', 10); +TemporalHelpers.assertPlainDate(d1.with({ month: 11 }), 1911, 11, 'M11', 10); +TemporalHelpers.assertPlainDate(d1.with({ monthCode: 'M05' }), 1911, 5, 'M05', 10); +TemporalHelpers.assertPlainDate(d1.with({ day: 30 }), 1911, 10, 'M10', 30); +TemporalHelpers.assertPlainDate(d1.with({ + year: 2021, + hour: 30 +}), 2021, 10, 'M10', 10); +TemporalHelpers.assertPlainDate(d1.with({ + month: 11, + minute: 71 +}), 1911, 11, 'M11', 10); +TemporalHelpers.assertPlainDate(d1.with({ + monthCode: 'M05', + second: 90 +}), 1911, 5, 'M05', 10); +TemporalHelpers.assertPlainDate(d1.with({ + day: 30, + era: 'BC' +}), 1911, 10, 'M10', 30); + +let d2 = new Temporal.PlainDate(2021, 7, 20, 'roc'); +TemporalHelpers.assertPlainDate(d2, 110, 7, 'M07', 20, '', 'roc', 110); +TemporalHelpers.assertPlainDate(d2.with({ year: 1912 }), 1912, 7, 'M07', 20, '', 'roc', 1912); +TemporalHelpers.assertPlainDate(d2.with({ year: 1987 }), 1987, 7, 'M07', 20, '', 'roc', 1987); +assert.throws(TypeError, () => d1.with(new Temporal.PlainDate(2021, 7, 1))); +assert.throws(TypeError, () => d1.with(new Temporal.PlainDateTime(2021, 7, 1, 12, 13))); +assert.throws(TypeError, () => d1.with(new Temporal.PlainTime(1, 12, 13))); +assert.throws(TypeError, () => d1.with(new Temporal.PlainYearMonth(1991, 12))); +assert.throws(TypeError, () => d1.with(new Temporal.PlainMonthDay(5, 12))); +assert.throws(TypeError, () => d1.with('2012-05-13')); +assert.throws(TypeError, () => d1.with({ calendar: 'iso8601' })); +assert.throws(TypeError, () => d1.with({ timeZone: 'UTC' })); +assert.throws(TypeError, () => d1.with(true)); +assert.throws(TypeError, () => d1.with(false)); +assert.throws(TypeError, () => d1.with(NaN)); +assert.throws(TypeError, () => d1.with(Infinity)); +assert.throws(TypeError, () => d1.with(1234)); +assert.throws(TypeError, () => d1.with(567n)); +assert.throws(TypeError, () => d1.with(Symbol())); +assert.throws(TypeError, () => d1.with('string')); +assert.throws(TypeError, () => d1.with({})); +assert.throws(TypeError, () => d1.with([])); +let badDate = { with: d1.with }; +assert.throws(TypeError, () => badDate.with({ day: 3 })); diff --git a/test/staging/built-ins/RegExp/named-groups/duplicate-named-groups-replace.js b/test/staging/built-ins/RegExp/named-groups/duplicate-named-groups-replace.js index cf4d9e5368..72abd134ff 100644 --- a/test/staging/built-ins/RegExp/named-groups/duplicate-named-groups-replace.js +++ b/test/staging/built-ins/RegExp/named-groups/duplicate-named-groups-replace.js @@ -4,25 +4,24 @@ /*--- description: Test replace function with duplicate names in alteration. features: [regexp-duplicate-named-groups] -includes: [compareArray.js] ---*/ -assert.compareArray( +assert.sameValue( '2xyy', 'xxyy'.replace(/(?:(?:(?x)|(?y))\k)/, '2$')); -assert.compareArray( +assert.sameValue( 'x2zyyxxy', 'xzzyyxxy'.replace( /(?:(?:(?x)|(?y)|(a)|(?b)|(?z))\k)/, '2$')); -assert.compareArray( +assert.sameValue( '2x(x,)yy', 'xxyy'.replace(/(?:(?:(?x)|(?y))\k)/, '2$($1,$2)')); -assert.compareArray( +assert.sameValue( 'x2z(,,,,z)yyxxy', 'xzzyyxxy'.replace( /(?:(?:(?x)|(?y)|(a)|(?b)|(?z))\k)/, '2$($1,$2,$3,$4,$5)')); -assert.compareArray( +assert.sameValue( '2x2y', 'xxyy'.replace(/(?:(?:(?x)|(?y))\k)/g, '2$')); -assert.compareArray( +assert.sameValue( 'x2z2y2xy', 'xzzyyxxy'.replace( /(?:(?:(?x)|(?y)|(a)|(?b)|(?z))\k)/g, '2$')); diff --git a/test/staging/built-ins/RegExp/named-groups/duplicate-named-groups-search.js b/test/staging/built-ins/RegExp/named-groups/duplicate-named-groups-search.js index 3796b5bc41..7d3b31b3b4 100644 --- a/test/staging/built-ins/RegExp/named-groups/duplicate-named-groups-search.js +++ b/test/staging/built-ins/RegExp/named-groups/duplicate-named-groups-search.js @@ -4,10 +4,9 @@ /*--- description: Test search function with duplicate names in alteration. features: [regexp-duplicate-named-groups] -includes: [compareArray.js] ---*/ -assert.compareArray(3, 'abcxyz'.search(/(?x)|(?y)/)); -assert.compareArray(3, 'abcxyz'.search(/(?y)|(?x)/)); -assert.compareArray(1, 'aybcxyz'.search(/(?x)|(?y)/)); -assert.compareArray(1, 'aybcxyz'.search(/(?y)|(?x)/)); +assert.sameValue(3, 'abcxyz'.search(/(?x)|(?y)/)); +assert.sameValue(3, 'abcxyz'.search(/(?y)|(?x)/)); +assert.sameValue(1, 'aybcxyz'.search(/(?x)|(?y)/)); +assert.sameValue(1, 'aybcxyz'.search(/(?y)|(?x)/)); diff --git a/test/staging/sm/Math/acosh-exact.js b/test/staging/sm/Math/acosh-exact.js index 4d783d66f9..233aa31d47 100644 --- a/test/staging/sm/Math/acosh-exact.js +++ b/test/staging/sm/Math/acosh-exact.js @@ -5,6 +5,7 @@ description: | pending esid: pending +includes: [sm/non262-Math-shell.js] ---*/ // Properties of Math.acosh that are guaranteed by the spec. diff --git a/test/staging/sm/Math/atanh-exact.js b/test/staging/sm/Math/atanh-exact.js index 810c103961..0794af8e5a 100644 --- a/test/staging/sm/Math/atanh-exact.js +++ b/test/staging/sm/Math/atanh-exact.js @@ -5,6 +5,7 @@ description: | pending esid: pending +includes: [sm/non262-Math-shell.js] ---*/ // Properties of Math.atanh that are guaranteed by the spec. diff --git a/test/staging/sm/Math/log1p-exact.js b/test/staging/sm/Math/log1p-exact.js index 424dcf2159..c8949028dd 100644 --- a/test/staging/sm/Math/log1p-exact.js +++ b/test/staging/sm/Math/log1p-exact.js @@ -5,6 +5,7 @@ description: | pending esid: pending +includes: [sm/non262-Math-shell.js] ---*/ // Properties of Math.log1p that are guaranteed by the spec. diff --git a/test/staging/sm/Math/trunc.js b/test/staging/sm/Math/trunc.js index 048b8062db..cbc0670667 100644 --- a/test/staging/sm/Math/trunc.js +++ b/test/staging/sm/Math/trunc.js @@ -5,6 +5,7 @@ description: | pending esid: pending +includes: [sm/non262-Math-shell.js] ---*/ // If x is NaN, the result is NaN. assert.sameValue(Math.trunc(NaN), NaN); diff --git a/test/staging/sm/String/AdvanceStringIndex.js b/test/staging/sm/String/AdvanceStringIndex.js index b474c0bee9..ab00180990 100644 --- a/test/staging/sm/String/AdvanceStringIndex.js +++ b/test/staging/sm/String/AdvanceStringIndex.js @@ -21,19 +21,19 @@ assert.compareArray("\uD83D\uDC38\uD83D\uDC39X\uD83D\uDC3A".match(/\uD83D\uDC38| // ==== String.prototype.replace ==== // empty string replacement (optimized) -assert.compareArray("\uD83D\uDC38\uD83D\uDC39X\uD83D\uDC3A".replace(/\uD83D|X|/gu, ""), +assert.sameValue("\uD83D\uDC38\uD83D\uDC39X\uD83D\uDC3A".replace(/\uD83D|X|/gu, ""), "\uD83D\uDC38\uD83D\uDC39\uD83D\uDC3A"); -assert.compareArray("\uD83D\uDC38\uD83D\uDC39X\uD83D\uDC3A".replace(/\uDC38|X|/gu, ""), +assert.sameValue("\uD83D\uDC38\uD83D\uDC39X\uD83D\uDC3A".replace(/\uDC38|X|/gu, ""), "\uD83D\uDC38\uD83D\uDC39\uD83D\uDC3A"); -assert.compareArray("\uD83D\uDC38\uD83D\uDC39X\uD83D\uDC3A".replace(/\uD83D\uDC38|X|/gu, ""), +assert.sameValue("\uD83D\uDC38\uD83D\uDC39X\uD83D\uDC3A".replace(/\uD83D\uDC38|X|/gu, ""), "\uD83D\uDC39\uD83D\uDC3A"); // non-empty string replacement -assert.compareArray("\uD83D\uDC38\uD83D\uDC39X\uD83D\uDC3A".replace(/\uD83D|X|/gu, "x"), +assert.sameValue("\uD83D\uDC38\uD83D\uDC39X\uD83D\uDC3A".replace(/\uD83D|X|/gu, "x"), "x\uD83D\uDC38x\uD83D\uDC39xx\uD83D\uDC3Ax"); -assert.compareArray("\uD83D\uDC38\uD83D\uDC39X\uD83D\uDC3A".replace(/\uDC38|X|/gu, "x"), +assert.sameValue("\uD83D\uDC38\uD83D\uDC39X\uD83D\uDC3A".replace(/\uDC38|X|/gu, "x"), "x\uD83D\uDC38x\uD83D\uDC39xx\uD83D\uDC3Ax"); -assert.compareArray("\uD83D\uDC38\uD83D\uDC39X\uD83D\uDC3A".replace(/\uD83D\uDC38|X|/gu, "x"), +assert.sameValue("\uD83D\uDC38\uD83D\uDC39X\uD83D\uDC3A".replace(/\uD83D\uDC38|X|/gu, "x"), "xx\uD83D\uDC39xx\uD83D\uDC3Ax"); // ==== String.prototype.split ==== diff --git a/test/staging/top-level-await/grandparent-tla_FIXTURE.js b/test/staging/top-level-await/grandparent-tla_FIXTURE.js index d3b0af5d4c..174a8ebf73 100644 --- a/test/staging/top-level-await/grandparent-tla_FIXTURE.js +++ b/test/staging/top-level-await/grandparent-tla_FIXTURE.js @@ -1,4 +1,4 @@ // Copyright (C) 2024 the V8 project authors. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. -import "parent-tla_FIXTURE.js"; +import "./parent-tla_FIXTURE.js"; diff --git a/test/staging/top-level-await/parent-tla_FIXTURE.js b/test/staging/top-level-await/parent-tla_FIXTURE.js index a32e5e36f4..d51e5af2bc 100644 --- a/test/staging/top-level-await/parent-tla_FIXTURE.js +++ b/test/staging/top-level-await/parent-tla_FIXTURE.js @@ -1,4 +1,4 @@ // Copyright (C) 2024 the V8 project authors. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. -import "tla_FIXTURE.js" +import "./tla_FIXTURE.js" diff --git a/test/staging/top-level-await/tla-hang-entry.js b/test/staging/top-level-await/tla-hang-entry.js index 1d8fef194d..4be921760b 100644 --- a/test/staging/top-level-await/tla-hang-entry.js +++ b/test/staging/top-level-await/tla-hang-entry.js @@ -7,7 +7,7 @@ flags: [module, async] features: [top-level-await] ---*/ -import "parent-tla_FIXTURE.js"; -await import("grandparent-tla_FIXTURE.js"); +import "./parent-tla_FIXTURE.js"; +await import("./grandparent-tla_FIXTURE.js"); $DONE(); diff --git a/tools/lint/lib/checks/esid.py b/tools/lint/lib/checks/esid.py index fbe1f4fc41..9c8deb9e31 100644 --- a/tools/lint/lib/checks/esid.py +++ b/tools/lint/lib/checks/esid.py @@ -13,7 +13,8 @@ class CheckEsid(Check): # https://url.spec.whatwg.org/#fragment-state # However, that must also include "%" self.esidRegex = re.compile( - u"^[a-z0-9!$%&'()*+,\-./:;=?@_~\u00a0-\U0010fffd]+$", re.IGNORECASE + u"^[a-z0-9!$%&'()*+,\\-./:;=?@_~\u00a0-\U0010fffd]+$", + re.IGNORECASE ) def run(self, name, meta, source):