mirror of
https://github.com/tc39/test262.git
synced 2025-12-05 21:09:47 +01:00
Merge branch 'main' into web-features-init
This commit is contained in:
commit
c61bcf856f
@ -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.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.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.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).
|
`$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.
|
`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.
|
||||||
|
|
||||||
|
|||||||
14
features.txt
14
features.txt
@ -11,6 +11,10 @@
|
|||||||
#
|
#
|
||||||
# https://github.com/tc39/process-document
|
# https://github.com/tc39/process-document
|
||||||
|
|
||||||
|
# Intl Era Monthcode
|
||||||
|
# https://github.com/tc39/proposal-intl-era-monthcode
|
||||||
|
Intl.Era-monthcode
|
||||||
|
|
||||||
# Intl.Locale Info
|
# Intl.Locale Info
|
||||||
# https://github.com/tc39/proposal-intl-locale-info
|
# https://github.com/tc39/proposal-intl-locale-info
|
||||||
Intl.Locale-info
|
Intl.Locale-info
|
||||||
@ -50,20 +54,12 @@ json-parse-with-source
|
|||||||
# https://github.com/tc39/proposal-explicit-resource-management
|
# https://github.com/tc39/proposal-explicit-resource-management
|
||||||
explicit-resource-management
|
explicit-resource-management
|
||||||
|
|
||||||
# Math.sumPrecise
|
|
||||||
# https://github.com/tc39/proposal-math-sum
|
|
||||||
Math.sumPrecise
|
|
||||||
|
|
||||||
# Source Phase Imports
|
# Source Phase Imports
|
||||||
## https://github.com/tc39/proposal-source-phase-imports
|
## https://github.com/tc39/proposal-source-phase-imports
|
||||||
source-phase-imports
|
source-phase-imports
|
||||||
## test262 special specifier
|
## test262 special specifier
|
||||||
source-phase-imports-module-source
|
source-phase-imports-module-source
|
||||||
|
|
||||||
# Uint8Array Base64
|
|
||||||
# https://github.com/tc39/proposal-arraybuffer-base64
|
|
||||||
uint8array-base64
|
|
||||||
|
|
||||||
# Atomics.pause
|
# Atomics.pause
|
||||||
# https://github.com/tc39/proposal-atomics-microwait
|
# https://github.com/tc39/proposal-atomics-microwait
|
||||||
Atomics.pause
|
Atomics.pause
|
||||||
@ -184,6 +180,7 @@ json-superset
|
|||||||
let
|
let
|
||||||
logical-assignment-operators
|
logical-assignment-operators
|
||||||
Map
|
Map
|
||||||
|
Math.sumPrecise
|
||||||
new.target
|
new.target
|
||||||
numeric-separator-literal
|
numeric-separator-literal
|
||||||
object-rest
|
object-rest
|
||||||
@ -255,6 +252,7 @@ TypedArray
|
|||||||
TypedArray.prototype.at
|
TypedArray.prototype.at
|
||||||
u180e
|
u180e
|
||||||
Uint8Array
|
Uint8Array
|
||||||
|
uint8array-base64
|
||||||
Uint16Array
|
Uint16Array
|
||||||
Uint32Array
|
Uint32Array
|
||||||
Uint8ClampedArray
|
Uint8ClampedArray
|
||||||
|
|||||||
@ -101,6 +101,45 @@ assert.throws = function (expectedErrorConstructor, func, message) {
|
|||||||
throw new Test262Error(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) {
|
assert._formatIdentityFreeValue = function formatIdentityFreeValue(value) {
|
||||||
switch (value === null ? 'null' : typeof value) {
|
switch (value === null ? 'null' : typeof value) {
|
||||||
case 'string':
|
case 'string':
|
||||||
|
|||||||
@ -2,49 +2,6 @@
|
|||||||
// This code is governed by the BSD license found in the LICENSE file.
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
/*---
|
/*---
|
||||||
description: |
|
description: |
|
||||||
Compare the contents of two arrays
|
Deprecated now that compareArray is defined in assert.js.
|
||||||
defines: [compareArray]
|
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}`);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
/*---
|
/*---
|
||||||
defines: [assertNear]
|
defines: [assertNear, ONE_PLUS_EPSILON, ONE_MINUS_EPSILON]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
// The nearest representable values to +1.0.
|
// 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
|
ENDIAN = 0; // try little-endian first
|
||||||
if (diff(2, 4) === 0x100000) // exact wrong answer we'll get on a big-endian platform
|
if (diff(2, 4) === 0x100000) // exact wrong answer we'll get on a big-endian platform
|
||||||
ENDIAN = 1;
|
ENDIAN = 1;
|
||||||
assert.sameValue(diff(2,4), 0x10000000000000);
|
// For test262-harness compatibility,
|
||||||
assert.sameValue(diff(0, Number.MIN_VALUE), 1);
|
// avoid `assert.sameValue` while still defining functions.
|
||||||
assert.sameValue(diff(1, ONE_PLUS_EPSILON), 1);
|
// https://github.com/bocoup/test262-stream/issues/34
|
||||||
assert.sameValue(diff(1, ONE_MINUS_EPSILON), 1);
|
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) {
|
var assertNear = function assertNear(a, b, tolerance=1) {
|
||||||
if (!Number.isFinite(b)) {
|
if (!Number.isFinite(b)) {
|
||||||
|
|||||||
105
test/built-ins/Object/assign/target-Array.js
Normal file
105
test/built-ins/Object/assign/target-Array.js
Normal file
@ -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");
|
||||||
|
}
|
||||||
@ -11,6 +11,8 @@ features: [promise-with-resolvers]
|
|||||||
var instance = Promise.withResolvers();
|
var instance = Promise.withResolvers();
|
||||||
|
|
||||||
assert.sameValue(typeof instance.resolve, 'function', 'type of resolve property');
|
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(instance.resolve.length, 1, 'length of resolve property');
|
||||||
assert.sameValue(typeof instance.reject, 'function', 'type of reject 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');
|
assert.sameValue(instance.reject.length, 1, 'length of reject property');
|
||||||
|
|||||||
@ -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");
|
||||||
@ -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");
|
||||||
@ -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");
|
||||||
32
test/built-ins/Temporal/Duration/prototype/add/argument-propertybag-optional-properties.js
vendored
Normal file
32
test/built-ins/Temporal/Duration/prototype/add/argument-propertybag-optional-properties.js
vendored
Normal file
@ -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");
|
||||||
19
test/built-ins/Temporal/Duration/prototype/add/float64-representable-integer.js
vendored
Normal file
19
test/built-ins/Temporal/Duration/prototype/add/float64-representable-integer.js
vendored
Normal file
@ -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");
|
||||||
24
test/built-ins/Temporal/Duration/prototype/round/float64-representable-integer.js
vendored
Normal file
24
test/built-ins/Temporal/Duration/prototype/round/float64-representable-integer.js
vendored
Normal file
@ -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");
|
||||||
@ -14,7 +14,7 @@ const instance = new Temporal.Duration(1, 0, 0, 0, 24);
|
|||||||
const wrongTypeTests = [
|
const wrongTypeTests = [
|
||||||
[null, "null"],
|
[null, "null"],
|
||||||
[true, "boolean"],
|
[true, "boolean"],
|
||||||
[1, "number that doesn't convert to a valid ISO string"],
|
[1, "number"],
|
||||||
[1n, "bigint"],
|
[1n, "bigint"],
|
||||||
[19970327, "large number"],
|
[19970327, "large number"],
|
||||||
[-19970327, "negative number"],
|
[-19970327, "negative number"],
|
||||||
@ -32,6 +32,6 @@ for (const [calendar, description] of wrongTypeTests) {
|
|||||||
assert.throws(
|
assert.throws(
|
||||||
TypeError,
|
TypeError,
|
||||||
() => instance.round({ largestUnit: "years", relativeTo }),
|
() => instance.round({ largestUnit: "years", relativeTo }),
|
||||||
`${description} does not convert to a valid ISO string`
|
`${description} is not a valid calendar`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,6 +24,6 @@ badOffsets.forEach((offset) => {
|
|||||||
assert.throws(
|
assert.throws(
|
||||||
typeof(offset) === 'string' ? RangeError : TypeError,
|
typeof(offset) === 'string' ? RangeError : TypeError,
|
||||||
() => instance.round({ largestUnit: "years", relativeTo }),
|
() => instance.round({ largestUnit: "years", relativeTo }),
|
||||||
`"${offset} is not a valid offset string`
|
`"${offset}" is not a valid offset string`
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
38
test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-optional-properties.js
vendored
Normal file
38
test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-optional-properties.js
vendored
Normal file
@ -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");
|
||||||
@ -17,7 +17,7 @@ const primitiveTests = [
|
|||||||
[null, 'null'],
|
[null, 'null'],
|
||||||
[true, 'boolean'],
|
[true, 'boolean'],
|
||||||
['', 'empty string'],
|
['', 'empty string'],
|
||||||
[1, "number that doesn't convert to a valid ISO string"],
|
[1, 'number'],
|
||||||
[1n, 'bigint']
|
[1n, 'bigint']
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
32
test/built-ins/Temporal/Duration/prototype/subtract/argument-propertybag-optional-properties.js
vendored
Normal file
32
test/built-ins/Temporal/Duration/prototype/subtract/argument-propertybag-optional-properties.js
vendored
Normal file
@ -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");
|
||||||
19
test/built-ins/Temporal/Duration/prototype/subtract/float64-representable-integer.js
vendored
Normal file
19
test/built-ins/Temporal/Duration/prototype/subtract/float64-representable-integer.js
vendored
Normal file
@ -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");
|
||||||
38
test/built-ins/Temporal/Duration/prototype/toJSON/large-with-small-units.js
vendored
Normal file
38
test/built-ins/Temporal/Duration/prototype/toJSON/large-with-small-units.js
vendored
Normal file
@ -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"
|
||||||
|
);
|
||||||
38
test/built-ins/Temporal/Duration/prototype/toString/large-with-small-units.js
vendored
Normal file
38
test/built-ins/Temporal/Duration/prototype/toString/large-with-small-units.js
vendored
Normal file
@ -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"
|
||||||
|
);
|
||||||
37
test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-optional-properties.js
vendored
Normal file
37
test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-optional-properties.js
vendored
Normal file
@ -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");
|
||||||
@ -17,7 +17,7 @@ const primitiveTests = [
|
|||||||
[null, 'null'],
|
[null, 'null'],
|
||||||
[true, 'boolean'],
|
[true, 'boolean'],
|
||||||
['', 'empty string'],
|
['', 'empty string'],
|
||||||
[1, "number that doesn't convert to a valid ISO string"],
|
[1, 'number'],
|
||||||
[1n, 'bigint']
|
[1n, 'bigint']
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
52
test/built-ins/Temporal/Instant/prototype/add/add-large-subseconds.js
vendored
Normal file
52
test/built-ins/Temporal/Instant/prototype/add/add-large-subseconds.js
vendored
Normal file
@ -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})));
|
||||||
31
test/built-ins/Temporal/Instant/prototype/add/argument-propertybag-optional-properties.js
vendored
Normal file
31
test/built-ins/Temporal/Instant/prototype/add/argument-propertybag-optional-properties.js
vendored
Normal file
@ -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");
|
||||||
20
test/built-ins/Temporal/Instant/prototype/since/float64-representable-integer.js
vendored
Normal file
20
test/built-ins/Temporal/Instant/prototype/since/float64-representable-integer.js
vendored
Normal file
@ -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");
|
||||||
31
test/built-ins/Temporal/Instant/prototype/subtract/argument-propertybag-optional-properties.js
vendored
Normal file
31
test/built-ins/Temporal/Instant/prototype/subtract/argument-propertybag-optional-properties.js
vendored
Normal file
@ -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");
|
||||||
52
test/built-ins/Temporal/Instant/prototype/subtract/subtract-large-subseconds.js
vendored
Normal file
52
test/built-ins/Temporal/Instant/prototype/subtract/subtract-large-subseconds.js
vendored
Normal file
@ -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})));
|
||||||
12
test/built-ins/Temporal/Instant/prototype/toString/fractionalseconddigits-negative.js
vendored
Normal file
12
test/built-ins/Temporal/Instant/prototype/toString/fractionalseconddigits-negative.js
vendored
Normal file
@ -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");
|
||||||
20
test/built-ins/Temporal/Instant/prototype/until/float64-representable-integer.js
vendored
Normal file
20
test/built-ins/Temporal/Instant/prototype/until/float64-representable-integer.js
vendored
Normal file
@ -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");
|
||||||
31
test/built-ins/Temporal/PlainDate/prototype/add/argument-propertybag-optional-properties.js
vendored
Normal file
31
test/built-ins/Temporal/PlainDate/prototype/add/argument-propertybag-optional-properties.js
vendored
Normal file
@ -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");
|
||||||
15
test/built-ins/Temporal/PlainDate/prototype/add/overflow-adding-months-to-max-year.js
vendored
Normal file
15
test/built-ins/Temporal/PlainDate/prototype/add/overflow-adding-months-to-max-year.js
vendored
Normal file
@ -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()));
|
||||||
@ -5,7 +5,7 @@
|
|||||||
esid: sec-temporal.plaindate.prototype.since
|
esid: sec-temporal.plaindate.prototype.since
|
||||||
description: >
|
description: >
|
||||||
Appropriate error thrown when a calendar property from a property bag cannot
|
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]
|
features: [BigInt, Symbol, Temporal]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
|
|||||||
31
test/built-ins/Temporal/PlainDate/prototype/subtract/argument-propertybag-optional-properties.js
vendored
Normal file
31
test/built-ins/Temporal/PlainDate/prototype/subtract/argument-propertybag-optional-properties.js
vendored
Normal file
@ -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");
|
||||||
@ -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()));
|
||||||
@ -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");
|
||||||
@ -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");
|
||||||
@ -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");
|
||||||
@ -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");
|
||||||
53
test/built-ins/Temporal/PlainDateTime/prototype/add/add-large-subseconds.js
vendored
Normal file
53
test/built-ins/Temporal/PlainDateTime/prototype/add/add-large-subseconds.js
vendored
Normal file
@ -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})));
|
||||||
31
test/built-ins/Temporal/PlainDateTime/prototype/add/argument-propertybag-optional-properties.js
vendored
Normal file
31
test/built-ins/Temporal/PlainDateTime/prototype/add/argument-propertybag-optional-properties.js
vendored
Normal file
@ -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");
|
||||||
15
test/built-ins/Temporal/PlainDateTime/prototype/add/overflow-adding-months-to-max-year.js
vendored
Normal file
15
test/built-ins/Temporal/PlainDateTime/prototype/add/overflow-adding-months-to-max-year.js
vendored
Normal file
@ -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()));
|
||||||
@ -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");
|
||||||
@ -5,7 +5,7 @@
|
|||||||
esid: sec-temporal.plaindatetime.prototype.since
|
esid: sec-temporal.plaindatetime.prototype.since
|
||||||
description: >
|
description: >
|
||||||
Appropriate error thrown when a calendar property from a property bag cannot
|
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]
|
features: [BigInt, Symbol, Temporal]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
|
|||||||
@ -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");
|
||||||
20
test/built-ins/Temporal/PlainDateTime/prototype/since/float64-representable-integer.js
vendored
Normal file
20
test/built-ins/Temporal/PlainDateTime/prototype/since/float64-representable-integer.js
vendored
Normal file
@ -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");
|
||||||
@ -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");
|
||||||
@ -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()));
|
||||||
53
test/built-ins/Temporal/PlainDateTime/prototype/subtract/subtract-large-subseconds.js
vendored
Normal file
53
test/built-ins/Temporal/PlainDateTime/prototype/subtract/subtract-large-subseconds.js
vendored
Normal file
@ -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})));
|
||||||
12
test/built-ins/Temporal/PlainDateTime/prototype/toString/fractionalseconddigits-negative.js
vendored
Normal file
12
test/built-ins/Temporal/PlainDateTime/prototype/toString/fractionalseconddigits-negative.js
vendored
Normal file
@ -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");
|
||||||
@ -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");
|
||||||
20
test/built-ins/Temporal/PlainDateTime/prototype/until/float64-representable-integer.js
vendored
Normal file
20
test/built-ins/Temporal/PlainDateTime/prototype/until/float64-representable-integer.js
vendored
Normal file
@ -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");
|
||||||
@ -14,7 +14,7 @@ const instance = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456,
|
|||||||
const wrongTypeTests = [
|
const wrongTypeTests = [
|
||||||
[null, "null"],
|
[null, "null"],
|
||||||
[true, "boolean"],
|
[true, "boolean"],
|
||||||
[1, "number that doesn't convert to a valid ISO string"],
|
[1, "number"],
|
||||||
[1n, "bigint"],
|
[1n, "bigint"],
|
||||||
[19970327, "large number"],
|
[19970327, "large number"],
|
||||||
[-19970327, "negative number"],
|
[-19970327, "negative number"],
|
||||||
@ -28,6 +28,6 @@ for (const [arg, description] of wrongTypeTests) {
|
|||||||
assert.throws(
|
assert.throws(
|
||||||
TypeError,
|
TypeError,
|
||||||
() => instance.withCalendar(arg),
|
() => instance.withCalendar(arg),
|
||||||
`${description} does not convert to a valid ISO string`
|
`${description} is not a valid calendar`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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");
|
||||||
@ -9,7 +9,9 @@ features: [Temporal]
|
|||||||
|
|
||||||
["m1", "M1", "m01"].forEach((monthCode) => {
|
["m1", "M1", "m01"].forEach((monthCode) => {
|
||||||
assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ monthCode, day: 17 }),
|
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 }),
|
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) => {
|
["M00", "M19", "M99", "M13", "M00L", "M05L", "M13L"].forEach((monthCode) => {
|
||||||
assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ monthCode, day: 17 }),
|
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(
|
assert.throws(
|
||||||
|
|||||||
@ -14,7 +14,7 @@ const instance = new Temporal.PlainMonthDay(5, 2);
|
|||||||
const wrongTypeTests = [
|
const wrongTypeTests = [
|
||||||
[null, "null"],
|
[null, "null"],
|
||||||
[true, "boolean"],
|
[true, "boolean"],
|
||||||
[1, "number that doesn't convert to a valid ISO string"],
|
[1, "number"],
|
||||||
[1n, "bigint"],
|
[1n, "bigint"],
|
||||||
[19970327, "large number"],
|
[19970327, "large number"],
|
||||||
[-19970327, "negative number"],
|
[-19970327, "negative number"],
|
||||||
@ -29,6 +29,6 @@ for (const [calendar, description] of wrongTypeTests) {
|
|||||||
assert.throws(
|
assert.throws(
|
||||||
TypeError,
|
TypeError,
|
||||||
() => instance.equals(arg),
|
() => instance.equals(arg),
|
||||||
`${description} does not convert to a valid ISO string`
|
`${description} is not a valid calendar`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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");
|
||||||
@ -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");
|
||||||
65
test/built-ins/Temporal/PlainTime/prototype/add/add-large-subseconds.js
vendored
Normal file
65
test/built-ins/Temporal/PlainTime/prototype/add/add-large-subseconds.js
vendored
Normal file
@ -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);
|
||||||
31
test/built-ins/Temporal/PlainTime/prototype/add/argument-propertybag-optional-properties.js
vendored
Normal file
31
test/built-ins/Temporal/PlainTime/prototype/add/argument-propertybag-optional-properties.js
vendored
Normal file
@ -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");
|
||||||
27
test/built-ins/Temporal/PlainTime/prototype/equals/argument-propertybag-optional-properties.js
vendored
Normal file
27
test/built-ins/Temporal/PlainTime/prototype/equals/argument-propertybag-optional-properties.js
vendored
Normal file
@ -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");
|
||||||
28
test/built-ins/Temporal/PlainTime/prototype/since/argument-propertybag-optional-properties.js
vendored
Normal file
28
test/built-ins/Temporal/PlainTime/prototype/since/argument-propertybag-optional-properties.js
vendored
Normal file
@ -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");
|
||||||
31
test/built-ins/Temporal/PlainTime/prototype/subtract/argument-propertybag-optional-properties.js
vendored
Normal file
31
test/built-ins/Temporal/PlainTime/prototype/subtract/argument-propertybag-optional-properties.js
vendored
Normal file
@ -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");
|
||||||
65
test/built-ins/Temporal/PlainTime/prototype/subtract/subtract-large-subseconds.js
vendored
Normal file
65
test/built-ins/Temporal/PlainTime/prototype/subtract/subtract-large-subseconds.js
vendored
Normal file
@ -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);
|
||||||
28
test/built-ins/Temporal/PlainTime/prototype/until/argument-propertybag-optional-properties.js
vendored
Normal file
28
test/built-ins/Temporal/PlainTime/prototype/until/argument-propertybag-optional-properties.js
vendored
Normal file
@ -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");
|
||||||
31
test/built-ins/Temporal/PlainYearMonth/prototype/add/argument-propertybag-optional-properties.js
vendored
Normal file
31
test/built-ins/Temporal/PlainYearMonth/prototype/add/argument-propertybag-optional-properties.js
vendored
Normal file
@ -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");
|
||||||
15
test/built-ins/Temporal/PlainYearMonth/prototype/add/overflow-adding-months-to-max-year.js
vendored
Normal file
15
test/built-ins/Temporal/PlainYearMonth/prototype/add/overflow-adding-months-to-max-year.js
vendored
Normal file
@ -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()));
|
||||||
@ -14,7 +14,7 @@ const instance = new Temporal.PlainYearMonth(2000, 5);
|
|||||||
const wrongTypeTests = [
|
const wrongTypeTests = [
|
||||||
[null, "null"],
|
[null, "null"],
|
||||||
[true, "boolean"],
|
[true, "boolean"],
|
||||||
[1, "number that doesn't convert to a valid ISO string"],
|
[1, "number"],
|
||||||
[1n, "bigint"],
|
[1n, "bigint"],
|
||||||
[19970327, "large positive number"],
|
[19970327, "large positive number"],
|
||||||
[-19970327, "negative number"],
|
[-19970327, "negative number"],
|
||||||
@ -29,6 +29,6 @@ for (const [calendar, description] of wrongTypeTests) {
|
|||||||
assert.throws(
|
assert.throws(
|
||||||
TypeError,
|
TypeError,
|
||||||
() => instance.equals(arg),
|
() => instance.equals(arg),
|
||||||
`${description} does not convert to a valid ISO string`
|
`${description} is not a valid calendar`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
esid: sec-temporal.plainyearmonth.prototype.since
|
esid: sec-temporal.plainyearmonth.prototype.since
|
||||||
description: >
|
description: >
|
||||||
Appropriate error thrown when a calendar property from a property bag cannot
|
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]
|
features: [BigInt, Symbol, Temporal]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
@ -14,7 +14,7 @@ const instance = new Temporal.PlainYearMonth(2000, 5);
|
|||||||
const wrongTypeTests = [
|
const wrongTypeTests = [
|
||||||
[null, "null"],
|
[null, "null"],
|
||||||
[true, "boolean"],
|
[true, "boolean"],
|
||||||
[1, "number that doesn't convert to a valid ISO string"],
|
[1, "number"],
|
||||||
[1n, "bigint"],
|
[1n, "bigint"],
|
||||||
[19970327, "large positive number"],
|
[19970327, "large positive number"],
|
||||||
[-19970327, "negative number"],
|
[-19970327, "negative number"],
|
||||||
@ -29,6 +29,6 @@ for (const [calendar, description] of wrongTypeTests) {
|
|||||||
assert.throws(
|
assert.throws(
|
||||||
TypeError,
|
TypeError,
|
||||||
() => instance.since(arg),
|
() => instance.since(arg),
|
||||||
`${description} does not convert to a valid ISO string`
|
`${description} is not a valid calendar`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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");
|
||||||
@ -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()));
|
||||||
@ -14,7 +14,7 @@ const instance = new Temporal.PlainYearMonth(2000, 5);
|
|||||||
const wrongTypeTests = [
|
const wrongTypeTests = [
|
||||||
[null, "null"],
|
[null, "null"],
|
||||||
[true, "boolean"],
|
[true, "boolean"],
|
||||||
[1, "number that doesn't convert to a valid ISO string"],
|
[1, "number"],
|
||||||
[1n, "bigint"],
|
[1n, "bigint"],
|
||||||
[19970327, "large positive number"],
|
[19970327, "large positive number"],
|
||||||
[-19970327, "large negative number"],
|
[-19970327, "large negative number"],
|
||||||
@ -29,6 +29,6 @@ for (const [calendar, description] of wrongTypeTests) {
|
|||||||
assert.throws(
|
assert.throws(
|
||||||
TypeError,
|
TypeError,
|
||||||
() => instance.until(arg),
|
() => instance.until(arg),
|
||||||
`${description} does not convert to a valid ISO string`
|
`${description} is not a valid calendar`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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");
|
||||||
@ -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");
|
||||||
53
test/built-ins/Temporal/ZonedDateTime/prototype/add/add-large-subseconds.js
vendored
Normal file
53
test/built-ins/Temporal/ZonedDateTime/prototype/add/add-large-subseconds.js
vendored
Normal file
@ -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})));
|
||||||
31
test/built-ins/Temporal/ZonedDateTime/prototype/add/argument-propertybag-optional-properties.js
vendored
Normal file
31
test/built-ins/Temporal/ZonedDateTime/prototype/add/argument-propertybag-optional-properties.js
vendored
Normal file
@ -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");
|
||||||
15
test/built-ins/Temporal/ZonedDateTime/prototype/add/overflow-adding-months-to-max-year.js
vendored
Normal file
15
test/built-ins/Temporal/ZonedDateTime/prototype/add/overflow-adding-months-to-max-year.js
vendored
Normal file
@ -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()));
|
||||||
@ -12,10 +12,10 @@ features: [BigInt, Symbol, Temporal]
|
|||||||
const timeZone = "UTC";
|
const timeZone = "UTC";
|
||||||
const instance = new Temporal.ZonedDateTime(0n, timeZone);
|
const instance = new Temporal.ZonedDateTime(0n, timeZone);
|
||||||
|
|
||||||
const primitiveTests = [
|
const wrongTypeTests = [
|
||||||
[null, "null"],
|
[null, "null"],
|
||||||
[true, "boolean"],
|
[true, "boolean"],
|
||||||
[1, "number that doesn't convert to a valid ISO string"],
|
[1, "number"],
|
||||||
[1n, "bigint"],
|
[1n, "bigint"],
|
||||||
[19970327, "large number"],
|
[19970327, "large number"],
|
||||||
[-19970327, "negative number"],
|
[-19970327, "negative number"],
|
||||||
@ -25,11 +25,11 @@ const primitiveTests = [
|
|||||||
[new Temporal.Duration(), "duration instance"],
|
[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 };
|
const arg = { year: 2019, monthCode: "M11", day: 1, calendar };
|
||||||
assert.throws(
|
assert.throws(
|
||||||
TypeError,
|
TypeError,
|
||||||
() => instance.equals(arg),
|
() => instance.equals(arg),
|
||||||
`${description} does not convert to a valid ISO string`
|
`${description} is not a valid calendar`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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");
|
||||||
@ -5,7 +5,7 @@
|
|||||||
esid: sec-temporal.zoneddatetime.prototype.since
|
esid: sec-temporal.zoneddatetime.prototype.since
|
||||||
description: >
|
description: >
|
||||||
Appropriate error thrown when a calendar property from a property bag cannot
|
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]
|
features: [BigInt, Symbol, Temporal]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
@ -15,7 +15,7 @@ const instance = new Temporal.ZonedDateTime(0n, timeZone);
|
|||||||
const wrongTypeTests = [
|
const wrongTypeTests = [
|
||||||
[null, "null"],
|
[null, "null"],
|
||||||
[true, "boolean"],
|
[true, "boolean"],
|
||||||
[1, "number that doesn't convert to a valid ISO string"],
|
[1, "number"],
|
||||||
[1n, "bigint"],
|
[1n, "bigint"],
|
||||||
[19970327, "large number"],
|
[19970327, "large number"],
|
||||||
[-19970327, "negative number"],
|
[-19970327, "negative number"],
|
||||||
@ -30,6 +30,6 @@ for (const [calendar, description] of wrongTypeTests) {
|
|||||||
assert.throws(
|
assert.throws(
|
||||||
TypeError,
|
TypeError,
|
||||||
() => instance.since(arg),
|
() => instance.since(arg),
|
||||||
`${description} does not convert to a valid ISO string`
|
`${description} is not a valid calendar`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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");
|
||||||
20
test/built-ins/Temporal/ZonedDateTime/prototype/since/float64-representable-integer.js
vendored
Normal file
20
test/built-ins/Temporal/ZonedDateTime/prototype/since/float64-representable-integer.js
vendored
Normal file
@ -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");
|
||||||
@ -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");
|
||||||
@ -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()));
|
||||||
53
test/built-ins/Temporal/ZonedDateTime/prototype/subtract/subtract-large-subseconds.js
vendored
Normal file
53
test/built-ins/Temporal/ZonedDateTime/prototype/subtract/subtract-large-subseconds.js
vendored
Normal file
@ -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})));
|
||||||
12
test/built-ins/Temporal/ZonedDateTime/prototype/toString/fractionalseconddigits-negative.js
vendored
Normal file
12
test/built-ins/Temporal/ZonedDateTime/prototype/toString/fractionalseconddigits-negative.js
vendored
Normal file
@ -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");
|
||||||
@ -15,7 +15,7 @@ const instance = new Temporal.ZonedDateTime(0n, timeZone);
|
|||||||
const wrongTypeTests = [
|
const wrongTypeTests = [
|
||||||
[null, "null"],
|
[null, "null"],
|
||||||
[true, "boolean"],
|
[true, "boolean"],
|
||||||
[1, "number that doesn't convert to a valid ISO string"],
|
[1, "number"],
|
||||||
[1n, "bigint"],
|
[1n, "bigint"],
|
||||||
[19970327, "large number"],
|
[19970327, "large number"],
|
||||||
[-19970327, "negative number"],
|
[-19970327, "negative number"],
|
||||||
@ -30,6 +30,6 @@ for (const [calendar, description] of wrongTypeTests) {
|
|||||||
assert.throws(
|
assert.throws(
|
||||||
TypeError,
|
TypeError,
|
||||||
() => instance.until(arg),
|
() => instance.until(arg),
|
||||||
`${description} does not convert to a valid ISO string`
|
`${description} is not a valid calendar`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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");
|
||||||
20
test/built-ins/Temporal/ZonedDateTime/prototype/until/float64-representable-integer.js
vendored
Normal file
20
test/built-ins/Temporal/ZonedDateTime/prototype/until/float64-representable-integer.js
vendored
Normal file
@ -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");
|
||||||
@ -4,7 +4,8 @@
|
|||||||
/*---
|
/*---
|
||||||
esid: sec-temporal.zoneddatetime.prototype.withcalendar
|
esid: sec-temporal.zoneddatetime.prototype.withcalendar
|
||||||
description: >
|
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]
|
features: [BigInt, Symbol, Temporal]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
@ -13,7 +14,7 @@ const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "
|
|||||||
const wrongTypeTests = [
|
const wrongTypeTests = [
|
||||||
[null, "null"],
|
[null, "null"],
|
||||||
[true, "boolean"],
|
[true, "boolean"],
|
||||||
[1, "number that doesn't convert to a valid ISO string"],
|
[1, "number"],
|
||||||
[1n, "bigint"],
|
[1n, "bigint"],
|
||||||
[-19761118, "negative number"],
|
[-19761118, "negative number"],
|
||||||
[19761118, "large positive number"],
|
[19761118, "large positive number"],
|
||||||
@ -27,6 +28,6 @@ for (const [arg, description] of wrongTypeTests) {
|
|||||||
assert.throws(
|
assert.throws(
|
||||||
TypeError,
|
TypeError,
|
||||||
() => instance.withCalendar(arg),
|
() => instance.withCalendar(arg),
|
||||||
`${description} does not convert to a valid ISO string`
|
`${description} is not a valid calendar`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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");
|
||||||
@ -17,8 +17,15 @@ var localArgs = function() {
|
|||||||
"use strict";
|
"use strict";
|
||||||
return arguments;
|
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 localThrowTypeError = Object.getOwnPropertyDescriptor(localArgs, "callee").get;
|
||||||
var otherThrowTypeError = Object.getOwnPropertyDescriptor(otherArgs, "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.notSameValue(localThrowTypeError, otherThrowTypeError);
|
||||||
|
assert.sameValue(otherThrowTypeError, otherThrowTypeError2);
|
||||||
|
|||||||
48
test/built-ins/Uint8Array/prototype/setFromBase64/trailing-garbage-empty.js
vendored
Normal file
48
test/built-ins/Uint8Array/prototype/setFromBase64/trailing-garbage-empty.js
vendored
Normal file
@ -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}"`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
83
test/built-ins/Uint8Array/prototype/setFromBase64/trailing-garbage.js
vendored
Normal file
83
test/built-ins/Uint8Array/prototype/setFromBase64/trailing-garbage.js
vendored
Normal file
@ -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}"`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -20,9 +20,9 @@ function assertThrows(func, errorMessage) {
|
|||||||
assert(caught, `Expected ${func} to throw, but it didn't.`);
|
assert(caught, `Expected ${func} to throw, but it didn't.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
assertThrows(() => assert.compareArray(), "Actual argument shouldn't be nullish. ");
|
assertThrows(() => assert.compareArray(), "Actual argument [undefined] shouldn't be primitive. ");
|
||||||
assertThrows(() => assert.compareArray(null, []), "Actual argument shouldn't be nullish. ");
|
assertThrows(() => assert.compareArray(null, []), "Actual argument [null] shouldn't be primitive. ");
|
||||||
assertThrows(() => assert.compareArray(null, [], "foo"), "Actual argument shouldn't be nullish. foo");
|
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([]), "Expected argument [undefined] shouldn't be primitive. ");
|
||||||
assertThrows(() => assert.compareArray([], undefined, "foo"), "Expected argument shouldn't be nullish. foo");
|
assertThrows(() => assert.compareArray([], undefined, "foo"), "Expected argument [undefined] shouldn't be primitive. foo");
|
||||||
|
|||||||
@ -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");
|
||||||
|
}
|
||||||
@ -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)
|
||||||
|
}
|
||||||
@ -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)
|
||||||
|
}
|
||||||
@ -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)
|
||||||
|
}
|
||||||
@ -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)
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user