diff --git a/js/src/tests/jstests.list b/js/src/tests/jstests.list index 3df6cbaa1004..2a2a3ef0e2b5 100644 --- a/js/src/tests/jstests.list +++ b/js/src/tests/jstests.list @@ -671,6 +671,12 @@ fails-if(!xulRuntime.shell) script test262/built-ins/SharedArrayBuffer/prototype skip script test262/intl402/NumberFormat/prototype/format/format-rounding-priority-more-precision.js +# Update required for https://github.com/tc39/ecma262/pull/2550 +# See bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1769088 +skip script test262/built-ins/Date/year-zero.js +skip script test262/built-ins/Date/parse/year-zero.js + + ############################################## # Enable Iterator Helpers tests in the shell # ############################################## diff --git a/js/src/tests/test262/GIT-INFO b/js/src/tests/test262/GIT-INFO index 7529353c55c4..99de56951093 100644 --- a/js/src/tests/test262/GIT-INFO +++ b/js/src/tests/test262/GIT-INFO @@ -1,8 +1,5 @@ -commit d7c0a2076c2b0c1531aef7069d4abe70eec44ee3 -Author: Shu-yu Guo -Date: Mon Apr 4 16:36:56 2022 -0700 +commit 2e7cdfbe18eae4309677033673bb4b5ac6b1de40 +Author: legendecas +Date: Mon May 2 22:56:46 2022 +0800 - Remove check for per-comparator call detach check in TypedArray.prototype.sort - - This updates tests in line with the normative change in - https://github.com/tc39/ecma262/pull/2723 + Fix generator clean fail on .DS_Store diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/create-species-non-ctor.js b/js/src/tests/test262/built-ins/Array/prototype/concat/create-species-non-ctor.js index 21010d86f1e4..fb102a60529c 100644 --- a/js/src/tests/test262/built-ins/Array/prototype/concat/create-species-non-ctor.js +++ b/js/src/tests/test262/built-ins/Array/prototype/concat/create-species-non-ctor.js @@ -18,9 +18,16 @@ info: | b. If C is null, let C be undefined. [...] 9. If IsConstructor(C) is false, throw a TypeError exception. -features: [Symbol.species] +includes: [isConstructor.js] +features: [Symbol.species, Reflect.construct] ---*/ +assert.sameValue( + isConstructor(parseInt), + false, + 'precondition: isConstructor(parseInt) must return false' +); + var a = []; a.constructor = {}; diff --git a/js/src/tests/test262/built-ins/Array/prototype/filter/create-species-non-ctor.js b/js/src/tests/test262/built-ins/Array/prototype/filter/create-species-non-ctor.js index 43908b773e87..fff049a2c637 100644 --- a/js/src/tests/test262/built-ins/Array/prototype/filter/create-species-non-ctor.js +++ b/js/src/tests/test262/built-ins/Array/prototype/filter/create-species-non-ctor.js @@ -19,9 +19,16 @@ info: | b. If C is null, let C be undefined. [...] 9. If IsConstructor(C) is false, throw a TypeError exception. -features: [Symbol.species] +includes: [isConstructor.js] +features: [Symbol.species, Reflect.construct] ---*/ +assert.sameValue( + isConstructor(parseInt), + false, + 'precondition: isConstructor(parseInt) must return false' +); + var a = []; var callCount = 0; var cb = function() { @@ -33,7 +40,7 @@ a.constructor[Symbol.species] = parseInt; assert.throws(TypeError, function() { a.filter(cb); -}); +}, 'a.filter(cb) throws a TypeError exception'); assert.sameValue(callCount, 0); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Array/prototype/map/create-species-non-ctor.js b/js/src/tests/test262/built-ins/Array/prototype/map/create-species-non-ctor.js index 7b9b805afb2d..35d80e9cd775 100644 --- a/js/src/tests/test262/built-ins/Array/prototype/map/create-species-non-ctor.js +++ b/js/src/tests/test262/built-ins/Array/prototype/map/create-species-non-ctor.js @@ -19,9 +19,16 @@ info: | b. If C is null, let C be undefined. [...] 9. If IsConstructor(C) is false, throw a TypeError exception. -features: [Symbol.species] +includes: [isConstructor.js] +features: [Symbol.species, Reflect.construct] ---*/ +assert.sameValue( + isConstructor(parseInt), + false, + 'precondition: isConstructor(parseInt) must return false' +); + var a = []; var callCount = 0; var cb = function() { @@ -33,7 +40,7 @@ a.constructor[Symbol.species] = parseInt; assert.throws(TypeError, function() { a.map(cb); -}); +}, 'a.map(cb) throws a TypeError exception'); assert.sameValue(callCount, 0); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Array/prototype/slice/create-species-non-ctor.js b/js/src/tests/test262/built-ins/Array/prototype/slice/create-species-non-ctor.js index a964b21749d5..bb254dfbada3 100644 --- a/js/src/tests/test262/built-ins/Array/prototype/slice/create-species-non-ctor.js +++ b/js/src/tests/test262/built-ins/Array/prototype/slice/create-species-non-ctor.js @@ -19,9 +19,16 @@ info: | b. If C is null, let C be undefined. [...] 9. If IsConstructor(C) is false, throw a TypeError exception. -features: [Symbol.species] +includes: [isConstructor.js] +features: [Symbol.species, Reflect.construct] ---*/ +assert.sameValue( + isConstructor(parseInt), + false, + 'precondition: isConstructor(parseInt) must return false' +); + var a = []; a.constructor = {}; @@ -29,6 +36,6 @@ a.constructor[Symbol.species] = parseInt; assert.throws(TypeError, function() { a.slice(); -}); +}, 'a.slice() throws a TypeError exception'); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Array/prototype/splice/create-species-non-ctor.js b/js/src/tests/test262/built-ins/Array/prototype/splice/create-species-non-ctor.js index d9229922768f..826fe92b141c 100644 --- a/js/src/tests/test262/built-ins/Array/prototype/splice/create-species-non-ctor.js +++ b/js/src/tests/test262/built-ins/Array/prototype/splice/create-species-non-ctor.js @@ -19,9 +19,16 @@ info: | b. If C is null, let C be undefined. [...] 9. If IsConstructor(C) is false, throw a TypeError exception. -features: [Symbol.species] +includes: [isConstructor.js] +features: [Symbol.species, Reflect.construct] ---*/ +assert.sameValue( + isConstructor(parseInt), + false, + 'precondition: isConstructor(parseInt) must return false' +); + var a = []; a.constructor = {}; @@ -29,6 +36,6 @@ a.constructor[Symbol.species] = parseInt; assert.throws(TypeError, function() { a.splice(); -}); +}, 'a.splice() throws a TypeError exception'); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Date/parse/year-zero.js b/js/src/tests/test262/built-ins/Date/parse/year-zero.js new file mode 100644 index 000000000000..f04147e59026 --- /dev/null +++ b/js/src/tests/test262/built-ins/Date/parse/year-zero.js @@ -0,0 +1,22 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-expanded-years +description: Negative zero, as an extended year, is rejected +info: | + The year 0 is considered positive and must be prefixed with a + sign. The + representation of the year 0 as -000000 is invalid. +---*/ + +const invalidStrings = [ + "-000000-03-31T00:45Z", + "-000000-03-31T01:45", + "-000000-03-31T01:45:00+01:00" +]; + +for (const str of invalidStrings) { + assert.sameValue(Date.parse(str), NaN, "reject minus zero as extended year"); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Date/year-zero.js b/js/src/tests/test262/built-ins/Date/year-zero.js new file mode 100644 index 000000000000..d00d7ceeb7f5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Date/year-zero.js @@ -0,0 +1,22 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-expanded-years +description: Negative zero, as an extended year, is rejected +info: | + The year 0 is considered positive and must be prefixed with a + sign. The + representation of the year 0 as -000000 is invalid. +---*/ + +const invalidStrings = [ + "-000000-03-31T00:45Z", + "-000000-03-31T01:45", + "-000000-03-31T01:45:00+01:00" +]; + +for (const str of invalidStrings) { + assert.sameValue(+new Date(str), NaN, "reject minus zero as extended year"); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Error/constructor.js b/js/src/tests/test262/built-ins/Error/constructor.js index b61fbd339338..a171fe89fbee 100644 --- a/js/src/tests/test262/built-ins/Error/constructor.js +++ b/js/src/tests/test262/built-ins/Error/constructor.js @@ -12,7 +12,7 @@ info: | esid: sec-error-message features: [error-cause] -includes: [deepEqual.js] +includes: [compareArray.js] ---*/ var message = "my-message"; @@ -34,6 +34,6 @@ new Error( }, ); -assert.deepEqual(sequence, [ "toString", "cause" ], "accessing own properties on sequence"); +assert.compareArray(sequence, [ "toString", "cause" ], "accessing own properties on sequence"); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Error/shell.js b/js/src/tests/test262/built-ins/Error/shell.js index b36293881a43..54371b778989 100644 --- a/js/src/tests/test262/built-ins/Error/shell.js +++ b/js/src/tests/test262/built-ins/Error/shell.js @@ -1,333 +1,4 @@ // GENERATED, DO NOT EDIT -// file: deepEqual.js -// Copyright 2019 Ron Buckton. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -description: > - Compare two values structurally -defines: [assert.deepEqual] ----*/ - -assert.deepEqual = function(actual, expected, message) { - var format = assert.deepEqual.format; - assert( - assert.deepEqual._compare(actual, expected), - `Expected ${format(actual)} to be structurally equal to ${format(expected)}. ${(message || '')}` - ); -}; - -assert.deepEqual.format = function(value, seen) { - switch (typeof value) { - case 'string': - return typeof JSON !== "undefined" ? JSON.stringify(value) : `"${value}"`; - case 'number': - case 'boolean': - case 'symbol': - case 'bigint': - return value.toString(); - case 'undefined': - return 'undefined'; - case 'function': - return `[Function${value.name ? `: ${value.name}` : ''}]`; - case 'object': - if (value === null) return 'null'; - if (value instanceof Date) return `Date "${value.toISOString()}"`; - if (value instanceof RegExp) return value.toString(); - if (!seen) { - seen = { - counter: 0, - map: new Map() - }; - } - - let usage = seen.map.get(value); - if (usage) { - usage.used = true; - return `[Ref: #${usage.id}]`; - } - - usage = { id: ++seen.counter, used: false }; - seen.map.set(value, usage); - - if (typeof Set !== "undefined" && value instanceof Set) { - return `Set {${Array.from(value).map(value => assert.deepEqual.format(value, seen)).join(', ')}}${usage.used ? ` as #${usage.id}` : ''}`; - } - if (typeof Map !== "undefined" && value instanceof Map) { - return `Map {${Array.from(value).map(pair => `${assert.deepEqual.format(pair[0], seen)} => ${assert.deepEqual.format(pair[1], seen)}}`).join(', ')}}${usage.used ? ` as #${usage.id}` : ''}`; - } - if (Array.isArray ? Array.isArray(value) : value instanceof Array) { - return `[${value.map(value => assert.deepEqual.format(value, seen)).join(', ')}]${usage.used ? ` as #${usage.id}` : ''}`; - } - let tag = Symbol.toStringTag in value ? value[Symbol.toStringTag] : 'Object'; - if (tag === 'Object' && Object.getPrototypeOf(value) === null) { - tag = '[Object: null prototype]'; - } - return `${tag ? `${tag} ` : ''}{ ${Object.keys(value).map(key => `${key.toString()}: ${assert.deepEqual.format(value[key], seen)}`).join(', ')} }${usage.used ? ` as #${usage.id}` : ''}`; - default: - return typeof value; - } -}; - -assert.deepEqual._compare = (function () { - var EQUAL = 1; - var NOT_EQUAL = -1; - var UNKNOWN = 0; - - function deepEqual(a, b) { - return compareEquality(a, b) === EQUAL; - } - - function compareEquality(a, b, cache) { - return compareIf(a, b, isOptional, compareOptionality) - || compareIf(a, b, isPrimitiveEquatable, comparePrimitiveEquality) - || compareIf(a, b, isObjectEquatable, compareObjectEquality, cache) - || NOT_EQUAL; - } - - function compareIf(a, b, test, compare, cache) { - return !test(a) - ? !test(b) ? UNKNOWN : NOT_EQUAL - : !test(b) ? NOT_EQUAL : cacheComparison(a, b, compare, cache); - } - - function tryCompareStrictEquality(a, b) { - return a === b ? EQUAL : UNKNOWN; - } - - function tryCompareTypeOfEquality(a, b) { - return typeof a !== typeof b ? NOT_EQUAL : UNKNOWN; - } - - function tryCompareToStringTagEquality(a, b) { - var aTag = Symbol.toStringTag in a ? a[Symbol.toStringTag] : undefined; - var bTag = Symbol.toStringTag in b ? b[Symbol.toStringTag] : undefined; - return aTag !== bTag ? NOT_EQUAL : UNKNOWN; - } - - function isOptional(value) { - return value === undefined - || value === null; - } - - function compareOptionality(a, b) { - return tryCompareStrictEquality(a, b) - || NOT_EQUAL; - } - - function isPrimitiveEquatable(value) { - switch (typeof value) { - case 'string': - case 'number': - case 'bigint': - case 'boolean': - case 'symbol': - return true; - default: - return isBoxed(value); - } - } - - function comparePrimitiveEquality(a, b) { - if (isBoxed(a)) a = a.valueOf(); - if (isBoxed(b)) b = b.valueOf(); - return tryCompareStrictEquality(a, b) - || tryCompareTypeOfEquality(a, b) - || compareIf(a, b, isNaNEquatable, compareNaNEquality) - || NOT_EQUAL; - } - - function isNaNEquatable(value) { - return typeof value === 'number'; - } - - function compareNaNEquality(a, b) { - return isNaN(a) && isNaN(b) ? EQUAL : NOT_EQUAL; - } - - function isObjectEquatable(value) { - return typeof value === 'object'; - } - - function compareObjectEquality(a, b, cache) { - if (!cache) cache = new Map(); - return getCache(cache, a, b) - || setCache(cache, a, b, EQUAL) // consider equal for now - || cacheComparison(a, b, tryCompareStrictEquality, cache) - || cacheComparison(a, b, tryCompareToStringTagEquality, cache) - || compareIf(a, b, isValueOfEquatable, compareValueOfEquality) - || compareIf(a, b, isToStringEquatable, compareToStringEquality) - || compareIf(a, b, isArrayLikeEquatable, compareArrayLikeEquality, cache) - || compareIf(a, b, isStructurallyEquatable, compareStructuralEquality, cache) - || compareIf(a, b, isIterableEquatable, compareIterableEquality, cache) - || cacheComparison(a, b, fail, cache); - } - - function isBoxed(value) { - return value instanceof String - || value instanceof Number - || value instanceof Boolean - || typeof Symbol === 'function' && value instanceof Symbol - || typeof BigInt === 'function' && value instanceof BigInt; - } - - function isValueOfEquatable(value) { - return value instanceof Date; - } - - function compareValueOfEquality(a, b) { - return compareIf(a.valueOf(), b.valueOf(), isPrimitiveEquatable, comparePrimitiveEquality) - || NOT_EQUAL; - } - - function isToStringEquatable(value) { - return value instanceof RegExp; - } - - function compareToStringEquality(a, b) { - return compareIf(a.toString(), b.toString(), isPrimitiveEquatable, comparePrimitiveEquality) - || NOT_EQUAL; - } - - function isArrayLikeEquatable(value) { - return (Array.isArray ? Array.isArray(value) : value instanceof Array) - || (typeof Uint8Array === 'function' && value instanceof Uint8Array) - || (typeof Uint8ClampedArray === 'function' && value instanceof Uint8ClampedArray) - || (typeof Uint16Array === 'function' && value instanceof Uint16Array) - || (typeof Uint32Array === 'function' && value instanceof Uint32Array) - || (typeof Int8Array === 'function' && value instanceof Int8Array) - || (typeof Int16Array === 'function' && value instanceof Int16Array) - || (typeof Int32Array === 'function' && value instanceof Int32Array) - || (typeof Float32Array === 'function' && value instanceof Float32Array) - || (typeof Float64Array === 'function' && value instanceof Float64Array) - || (typeof BigUint64Array === 'function' && value instanceof BigUint64Array) - || (typeof BigInt64Array === 'function' && value instanceof BigInt64Array); - } - - function compareArrayLikeEquality(a, b, cache) { - if (a.length !== b.length) return NOT_EQUAL; - for (var i = 0; i < a.length; i++) { - if (compareEquality(a[i], b[i], cache) === NOT_EQUAL) { - return NOT_EQUAL; - } - } - return EQUAL; - } - - function isStructurallyEquatable(value) { - return !(typeof Promise === 'function' && value instanceof Promise // only comparable by reference - || typeof WeakMap === 'function' && value instanceof WeakMap // only comparable by reference - || typeof WeakSet === 'function' && value instanceof WeakSet // only comparable by reference - || typeof Map === 'function' && value instanceof Map // comparable via @@iterator - || typeof Set === 'function' && value instanceof Set); // comparable via @@iterator - } - - function compareStructuralEquality(a, b, cache) { - var aKeys = []; - for (var key in a) aKeys.push(key); - - var bKeys = []; - for (var key in b) bKeys.push(key); - - if (aKeys.length !== bKeys.length) { - return NOT_EQUAL; - } - - aKeys.sort(); - bKeys.sort(); - - for (var i = 0; i < aKeys.length; i++) { - var aKey = aKeys[i]; - var bKey = bKeys[i]; - if (compareEquality(aKey, bKey, cache) === NOT_EQUAL) { - return NOT_EQUAL; - } - if (compareEquality(a[aKey], b[bKey], cache) === NOT_EQUAL) { - return NOT_EQUAL; - } - } - - return compareIf(a, b, isIterableEquatable, compareIterableEquality, cache) - || EQUAL; - } - - function isIterableEquatable(value) { - return typeof Symbol === 'function' - && typeof value[Symbol.iterator] === 'function'; - } - - function compareIteratorEquality(a, b, cache) { - if (typeof Map === 'function' && a instanceof Map && b instanceof Map || - typeof Set === 'function' && a instanceof Set && b instanceof Set) { - if (a.size !== b.size) return NOT_EQUAL; // exit early if we detect a difference in size - } - - var ar, br; - while (true) { - ar = a.next(); - br = b.next(); - if (ar.done) { - if (br.done) return EQUAL; - if (b.return) b.return(); - return NOT_EQUAL; - } - if (br.done) { - if (a.return) a.return(); - return NOT_EQUAL; - } - if (compareEquality(ar.value, br.value, cache) === NOT_EQUAL) { - if (a.return) a.return(); - if (b.return) b.return(); - return NOT_EQUAL; - } - } - } - - function compareIterableEquality(a, b, cache) { - return compareIteratorEquality(a[Symbol.iterator](), b[Symbol.iterator](), cache); - } - - function cacheComparison(a, b, compare, cache) { - var result = compare(a, b, cache); - if (cache && (result === EQUAL || result === NOT_EQUAL)) { - setCache(cache, a, b, /** @type {EQUAL | NOT_EQUAL} */(result)); - } - return result; - } - - function fail() { - return NOT_EQUAL; - } - - function setCache(cache, left, right, result) { - var otherCache; - - otherCache = cache.get(left); - if (!otherCache) cache.set(left, otherCache = new Map()); - otherCache.set(right, result); - - otherCache = cache.get(right); - if (!otherCache) cache.set(right, otherCache = new Map()); - otherCache.set(left, result); - } - - function getCache(cache, left, right) { - var otherCache; - var result; - - otherCache = cache.get(left); - result = otherCache && otherCache.get(right); - if (result) return result; - - otherCache = cache.get(right); - result = otherCache && otherCache.get(left); - if (result) return result; - - return UNKNOWN; - } - - return deepEqual; -})(); - // file: isConstructor.js // Copyright (C) 2017 André Bargull. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. diff --git a/js/src/tests/test262/built-ins/Function/prototype/bind/instance-length-tointeger.js b/js/src/tests/test262/built-ins/Function/prototype/bind/instance-length-tointeger.js index 5a1518cb0806..3d170b7222d0 100644 --- a/js/src/tests/test262/built-ins/Function/prototype/bind/instance-length-tointeger.js +++ b/js/src/tests/test262/built-ins/Function/prototype/bind/instance-length-tointeger.js @@ -13,12 +13,15 @@ info: | 5. Let targetHasLength be ? HasOwnProperty(Target, "length"). 6. If targetHasLength is true, then a. Let targetLen be ? Get(Target, "length"). - b. If Type(targetLen) is not Number, let L be 0. - c. Else, - i. Set targetLen to ! ToInteger(targetLen). - ii. Let L be the larger of 0 and the result of targetLen minus the number of elements of args. - 7. Else, let L be 0. - 8. Perform ! SetFunctionLength(F, L). + b. If Type(targetLen) is Number, then + i. If targetLen is +∞𝔽, set L to +∞. + ii. Else if targetLen is -∞𝔽, set L to 0. + iii. Else, + 1. Let targetLenAsInt be ! ToIntegerOrInfinity(targetLen). + 2. Assert: targetLenAsInt is finite. + 3. Let argCount be the number of elements in args. + 4. Set L to max(targetLenAsInt - argCount, 0). + 7. Perform ! SetFunctionLength(F, L). [...] ToInteger ( argument ) @@ -40,10 +43,12 @@ Object.defineProperty(fn, "length", {value: -0}); assert.sameValue(fn.bind().length, 0); Object.defineProperty(fn, "length", {value: Infinity}); -assert.sameValue(fn.bind().length, Infinity); +assert.sameValue(fn.bind().length, Infinity, "target length of infinity, zero bound arguments"); +assert.sameValue(fn.bind(0, 0).length, Infinity, "target length of infinity, one bound argument"); Object.defineProperty(fn, "length", {value: -Infinity}); -assert.sameValue(fn.bind().length, 0); +assert.sameValue(fn.bind().length, 0, "target length of negative infinity, zero bound arguments"); +assert.sameValue(fn.bind(0, 0).length, 0, "target length of negative infinity, one bound argument"); Object.defineProperty(fn, "length", {value: 3.66}); assert.sameValue(fn.bind().length, 3); diff --git a/js/src/tests/test262/built-ins/NativeErrors/AggregateError/newtarget-proto-custom.js b/js/src/tests/test262/built-ins/NativeErrors/AggregateError/newtarget-proto-custom.js index 906392720a72..0cf7359a592a 100644 --- a/js/src/tests/test262/built-ins/NativeErrors/AggregateError/newtarget-proto-custom.js +++ b/js/src/tests/test262/built-ins/NativeErrors/AggregateError/newtarget-proto-custom.js @@ -27,7 +27,7 @@ info: | a. Let realm be ? GetFunctionRealm(constructor). b. Set proto to realm's intrinsic object named intrinsicDefaultProto. Return proto. -features: [AggregateError] +features: [AggregateError, Reflect.construct] ---*/ var custom = { x: 42 }; diff --git a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/shell.js b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/shell.js index 1c0f4dad1409..57380c98e069 100644 --- a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/shell.js +++ b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/shell.js @@ -53,7 +53,7 @@ function printStringCodePoints(string) { function testPropertyEscapes(regExp, string, expression) { if (!regExp.test(string)) { for (const symbol of string) { - printCodePoint(symbol.codePointAt(0)); + const hex = printCodePoint(symbol.codePointAt(0)); assert( regExp.test(symbol), `\`${ expression }\` should match U+${ hex } (\`${ symbol }\`)` diff --git a/js/src/tests/test262/built-ins/RegExp/property-escapes/generated/shell.js b/js/src/tests/test262/built-ins/RegExp/property-escapes/generated/shell.js index 1c0f4dad1409..57380c98e069 100644 --- a/js/src/tests/test262/built-ins/RegExp/property-escapes/generated/shell.js +++ b/js/src/tests/test262/built-ins/RegExp/property-escapes/generated/shell.js @@ -53,7 +53,7 @@ function printStringCodePoints(string) { function testPropertyEscapes(regExp, string, expression) { if (!regExp.test(string)) { for (const symbol of string) { - printCodePoint(symbol.codePointAt(0)); + const hex = printCodePoint(symbol.codePointAt(0)); assert( regExp.test(symbol), `\`${ expression }\` should match U+${ hex } (\`${ symbol }\`)` diff --git a/js/src/tests/test262/built-ins/RegExp/prototype/Symbol.matchAll/shell.js b/js/src/tests/test262/built-ins/RegExp/prototype/Symbol.matchAll/shell.js index 1ad30bb1df39..af23da7e1214 100644 --- a/js/src/tests/test262/built-ins/RegExp/prototype/Symbol.matchAll/shell.js +++ b/js/src/tests/test262/built-ins/RegExp/prototype/Symbol.matchAll/shell.js @@ -90,7 +90,7 @@ function printStringCodePoints(string) { function testPropertyEscapes(regExp, string, expression) { if (!regExp.test(string)) { for (const symbol of string) { - printCodePoint(symbol.codePointAt(0)); + const hex = printCodePoint(symbol.codePointAt(0)); assert( regExp.test(symbol), `\`${ expression }\` should match U+${ hex } (\`${ symbol }\`)` diff --git a/js/src/tests/test262/built-ins/RegExp/prototype/toString/S15.10.6.4_A6.js b/js/src/tests/test262/built-ins/RegExp/prototype/toString/S15.10.6.4_A6.js index 233154b78a9a..42adb4757d62 100644 --- a/js/src/tests/test262/built-ins/RegExp/prototype/toString/S15.10.6.4_A6.js +++ b/js/src/tests/test262/built-ins/RegExp/prototype/toString/S15.10.6.4_A6.js @@ -5,6 +5,8 @@ info: RegExp.prototype.toString has not prototype property es5id: 15.10.6.4_A6 description: Checking RegExp.prototype.toString.prototype +includes: [isConstructor.js] +features: [Reflect.construct] ---*/ assert.sameValue( RegExp.prototype.toString.prototype, @@ -12,4 +14,10 @@ assert.sameValue( 'The value of RegExp.prototype.toString.prototype is expected to equal undefined' ); +assert.sameValue( + isConstructor(RegExp.prototype.toString), + false, + 'isConstructor(RegExp.prototype.toString) must return false' +); + reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/RegExp/prototype/toString/S15.10.6.4_A7.js b/js/src/tests/test262/built-ins/RegExp/prototype/toString/S15.10.6.4_A7.js index 854653c6ffcf..334fcc1f4dd3 100644 --- a/js/src/tests/test262/built-ins/RegExp/prototype/toString/S15.10.6.4_A7.js +++ b/js/src/tests/test262/built-ins/RegExp/prototype/toString/S15.10.6.4_A7.js @@ -5,6 +5,8 @@ info: RegExp.prototype.toString can't be used as constructor es5id: 15.10.6.4_A7 description: Checking if creating the RegExp.prototype.toString object fails +includes: [isConstructor.js] +features: [Reflect.construct] ---*/ var __FACTORY = RegExp.prototype.toString; @@ -20,6 +22,12 @@ try { ); } +assert.sameValue( + isConstructor(RegExp.prototype.toString), + false, + 'isConstructor(RegExp.prototype.toString) must return false' +); + // TODO: Convert to assert.throws() format. reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/RegExpStringIteratorPrototype/next/shell.js b/js/src/tests/test262/built-ins/RegExpStringIteratorPrototype/next/shell.js index 1ad30bb1df39..af23da7e1214 100644 --- a/js/src/tests/test262/built-ins/RegExpStringIteratorPrototype/next/shell.js +++ b/js/src/tests/test262/built-ins/RegExpStringIteratorPrototype/next/shell.js @@ -90,7 +90,7 @@ function printStringCodePoints(string) { function testPropertyEscapes(regExp, string, expression) { if (!regExp.test(string)) { for (const symbol of string) { - printCodePoint(symbol.codePointAt(0)); + const hex = printCodePoint(symbol.codePointAt(0)); assert( regExp.test(symbol), `\`${ expression }\` should match U+${ hex } (\`${ symbol }\`)` diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/globalthis-orginary-object.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/globalthis-ordinary-object.js similarity index 82% rename from js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/globalthis-orginary-object.js rename to js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/globalthis-ordinary-object.js index aff781f8042c..10324ef4d1e8 100644 --- a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/globalthis-orginary-object.js +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/globalthis-ordinary-object.js @@ -66,4 +66,28 @@ assert.sameValue( 'globalThis.constructor is Object' ); +assert.sameValue( + r.evaluate(` + let result; + try { + globalThis.__proto__ = {x: 2}; + result = true; + } catch (e) { + result = false; + } + result; + `), + true, + 'Can assign to globalThis.__proto__ directly' +); + +assert.sameValue( + r.evaluate(` + Reflect.set(globalThis, '__proto__', {x: 1}) && + Reflect.setPrototypeOf(globalThis.__proto__, {x: 2}); + `), + true, + 'Can set an ordinary globalThis.__proto__' +); + reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/exportName-tostring.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/throws-if-exportname-not-string.js similarity index 82% rename from js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/exportName-tostring.js rename to js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/throws-if-exportname-not-string.js index 8b6aab028dbf..1e2a67a50a66 100644 --- a/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/exportName-tostring.js +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/throws-if-exportname-not-string.js @@ -4,7 +4,7 @@ /*--- esid: sec-shadowrealm.prototype.importvalue description: > - ShadowRealm.prototype.importValue coerces exportName to string. + ShadowRealm.prototype.importValue throws if exportName is not a string. features: [ShadowRealm] ---*/ @@ -24,10 +24,10 @@ const exportName = { } }; -assert.throws(Test262Error, () => { +assert.throws(TypeError, () => { r.importValue('', exportName); }); -assert.sameValue(count, 1); +assert.sameValue(count, 0); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/String/prototype/matchAll/shell.js b/js/src/tests/test262/built-ins/String/prototype/matchAll/shell.js index 1ad30bb1df39..af23da7e1214 100644 --- a/js/src/tests/test262/built-ins/String/prototype/matchAll/shell.js +++ b/js/src/tests/test262/built-ins/String/prototype/matchAll/shell.js @@ -90,7 +90,7 @@ function printStringCodePoints(string) { function testPropertyEscapes(regExp, string, expression) { if (!regExp.test(string)) { for (const symbol of string) { - printCodePoint(symbol.codePointAt(0)); + const hex = printCodePoint(symbol.codePointAt(0)); assert( regExp.test(symbol), `\`${ expression }\` should match U+${ hex } (\`${ symbol }\`)` diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-number.js new file mode 100644 index 000000000000..6067e4229573 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-number.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.from +description: A number is converted to a string, then to Temporal.Calendar +features: [Temporal] +---*/ + +const arg = 19761118; + +const result = Temporal.Calendar.from(arg); +assert.sameValue(result.id, "iso8601", "19761118 is a valid ISO string for Calendar"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => Temporal.Calendar.from(arg), + `Number ${arg} does not convert to a valid ISO string for Calendar` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-string-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-string-leap-second.js new file mode 100644 index 000000000000..da5f1a2f20d3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-string-leap-second.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.from +description: Leap second is a valid ISO string for Calendar +features: [Temporal] +---*/ + +let arg = "2016-12-31T23:59:60"; +const result1 = Temporal.Calendar.from(arg); +assert.sameValue( + result1.id, + "iso8601", + "leap second is a valid ISO string for Calendar" +); + +arg = { calendar: "2016-12-31T23:59:60" }; +const result2 = Temporal.Calendar.from(arg); +assert.sameValue( + result2.id, + "iso8601", + "leap second is a valid ISO string for Calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-wrong-type.js new file mode 100644 index 000000000000..aa6cf18fa803 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-wrong-type.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.from +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for Calendar +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => Temporal.Calendar.from(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => Temporal.Calendar.from(arg), `${description} is not a valid object and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/from/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/Calendar/from/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/from/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-number.js new file mode 100644 index 000000000000..4e397a570425 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-number.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dateadd +description: A number is converted to a string, then to Temporal.PlainDate +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const arg = 19761118; + +const result = instance.dateAdd(arg, new Temporal.Duration()); +TemporalHelpers.assertPlainDate(result, 1976, 11, "M11", 18, "19761118 is a valid ISO string for PlainDate"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.dateAdd(arg, new Temporal.Duration()), + `Number ${arg} does not convert to a valid ISO string for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..61515aa7678f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dateadd +description: Leap second is a valid ISO string for a calendar in a property bag +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.dateAdd(arg, new Temporal.Duration()); +TemporalHelpers.assertPlainDate( + result1, + 1976, 11, "M11", 18, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.dateAdd(arg, new Temporal.Duration()); +TemporalHelpers.assertPlainDate( + result2, + 1976, 11, "M11", 18, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..8e4a02f9215e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-number.js @@ -0,0 +1,45 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dateadd +description: A number as calendar in a property bag is converted to a string, then to a calendar +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.dateAdd(arg, new Temporal.Duration()); +TemporalHelpers.assertPlainDate(result1, 1976, 11, "M11", 18, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.dateAdd(arg, new Temporal.Duration()); +TemporalHelpers.assertPlainDate(result2, 1976, 11, "M11", 18, "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + assert.throws( + RangeError, + () => instance.dateAdd(arg, new Temporal.Duration()), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.dateAdd(arg, new Temporal.Duration()), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..17503632d5cb --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dateadd +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.Calendar("iso8601"); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.dateAdd(arg, new Temporal.Duration()), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.dateAdd(arg, new Temporal.Duration()), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.dateAdd(arg, new Temporal.Duration()), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.dateAdd(arg, new Temporal.Duration()), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.dateAdd(arg, new Temporal.Duration()), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..3d69c679904a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dateadd +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.dateAdd(arg, new Temporal.Duration()), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-invalid.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-invalid.js index febd13f9b03d..45608a195867 100644 --- a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-invalid.js +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-invalid.js @@ -56,7 +56,7 @@ const instance = new Temporal.Calendar("iso8601"); for (const arg of invalidStrings) { assert.throws( RangeError, - () => instance.dateAdd(arg), + () => instance.dateAdd(arg, new Temporal.Duration()), `"${arg}" should not be a valid ISO string for a PlainDate` ); } diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-with-utc-designator.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-with-utc-designator.js index 2507334ac3d7..4568ed877287 100644 --- a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-with-utc-designator.js +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-with-utc-designator.js @@ -16,7 +16,7 @@ const instance = new Temporal.Calendar("iso8601"); invalidStrings.forEach((arg) => { assert.throws( RangeError, - () => instance.dateAdd(arg), + () => instance.dateAdd(arg, new Temporal.Duration()), "String with UTC designator should not be valid as a PlainDate" ); }); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-wrong-type.js new file mode 100644 index 000000000000..ca26f7a4ee78 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dateadd +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.dateAdd(arg, new Temporal.Duration()), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.dateAdd(arg, new Temporal.Duration()), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/leap-second.js new file mode 100644 index 000000000000..7fca2be0eafd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/leap-second.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dateadd +description: Leap second is a valid ISO string for PlainDate +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.dateAdd(arg, new Temporal.Duration()); +TemporalHelpers.assertPlainDate( + result1, + 2016, 12, "M12", 31, + "leap second is a valid ISO string for PlainDate" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.dateAdd(arg, new Temporal.Duration()); +TemporalHelpers.assertPlainDate( + result2, + 2016, 12, "M12", 31, + "second: 60 is ignored in property bag for PlainDate" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/options-wrong-type.js new file mode 100644 index 000000000000..f0e3bec30ad0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dateadd +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.Calendar("iso8601"); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.dateAdd(new Temporal.PlainDate(1976, 11, 18), new Temporal.Duration(1), value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/year-zero.js index adb012979744..ebf9ac31bb7a 100644 --- a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/year-zero.js @@ -8,13 +8,19 @@ description: Negative zero, as an extended year, is rejected features: [Temporal, arrow-function] ---*/ -const arg = "-000000-10-31"; +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; const instance = new Temporal.Calendar("iso8601"); - -assert.throws( +invalidStrings.forEach((arg) => { + assert.throws( RangeError, - () => { instance.dateAdd(arg); }, + () => instance.dateAdd(arg, new Temporal.Duration()), "reject minus zero as extended year" -); + ); +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/options-wrong-type.js new file mode 100644 index 000000000000..1595039a4f8b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.datefromfields +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.Calendar("iso8601"); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.dateFromFields({ year: 1976, month: 11, day: 18 }, value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-number.js new file mode 100644 index 000000000000..4e7331f86131 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-number.js @@ -0,0 +1,40 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dateuntil +description: A number is converted to a string, then to Temporal.PlainDate +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const arg = 19761118; + +const result1 = instance.dateUntil(arg, new Temporal.PlainDate(1976, 11, 19)); +TemporalHelpers.assertDuration(result1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "19761118 is a valid ISO string for PlainDate (first argument)"); +const result2 = instance.dateUntil(new Temporal.PlainDate(1976, 11, 19), arg); +TemporalHelpers.assertDuration(result2, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "19761118 is a valid ISO string for PlainDate (second argument)"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 18)), + `Number ${arg} does not convert to a valid ISO string for PlainDate (first argument)` + ); + assert.throws( + RangeError, + () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 18), arg), + `Number ${arg} does not convert to a valid ISO string for PlainDate (second argument)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..df692ceec487 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,28 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dateuntil +description: Leap second is a valid ISO string for a calendar in a property bag +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.dateUntil(arg, new Temporal.PlainDate(1976, 11, 19)); +TemporalHelpers.assertDuration(result1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "leap second is a valid ISO string for calendar (first argument)"); +const result2 = instance.dateUntil(new Temporal.PlainDate(1976, 11, 19), arg); +TemporalHelpers.assertDuration(result2, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "leap second is a valid ISO string for calendar (second argument)"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result3 = instance.dateUntil(arg, new Temporal.PlainDate(1976, 11, 19)); +TemporalHelpers.assertDuration(result3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "leap second is a valid ISO string for calendar (nested property, first argument)"); +const result4 = instance.dateUntil(new Temporal.PlainDate(1976, 11, 19), arg); +TemporalHelpers.assertDuration(result4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "leap second is a valid ISO string for calendar (nested property, second argument)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..9e48cdb50061 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-number.js @@ -0,0 +1,59 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dateuntil +description: A number as calendar in a property bag is converted to a string, then to a calendar +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.dateUntil(arg, new Temporal.PlainDate(1976, 11, 19)); +TemporalHelpers.assertDuration(result1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar (first argument)"); +const result2 = instance.dateUntil(new Temporal.PlainDate(1976, 11, 19), arg); +TemporalHelpers.assertDuration(result2, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar (second argument)"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result3 = instance.dateUntil(arg, new Temporal.PlainDate(1976, 11, 19)); +TemporalHelpers.assertDuration(result3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar (nested property, first argument)"); +const result4 = instance.dateUntil(new Temporal.PlainDate(1976, 11, 19), arg); +TemporalHelpers.assertDuration(result4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar (nested property, second argument)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + assert.throws( + RangeError, + () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)), + `Number ${calendar} does not convert to a valid ISO string for calendar (first argument)` + ); + assert.throws( + RangeError, + () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (second argument)` + ); + arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property, first argument)` + ); + assert.throws( + RangeError, + () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property, second argument)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..153288248fed --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,55 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dateuntil +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.Calendar("iso8601"); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)), `${description} does not convert to a valid ISO string (first argument)`); + assert.throws(RangeError, () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg), `${description} does not convert to a valid ISO string (second argument)`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)), `${description} does not convert to a valid ISO string (nested property, first argument)`); + assert.throws(RangeError, () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg), `${description} does not convert to a valid ISO string (nested property, second argument)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)), `${description} is not a valid property bag and does not convert to a string (first argument)`); + assert.throws(TypeError, () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg), `${description} is not a valid property bag and does not convert to a string (second argument)`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)), `${description} is not a valid property bag and does not convert to a string (nested property, first argument)`); + assert.throws(TypeError, () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg), `${description} is not a valid property bag and does not convert to a string (nested property, second argument)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)), `nested undefined calendar property is always a RangeError (first argument)`); +assert.throws(RangeError, () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg), `nested undefined calendar property is always a RangeError (second argument)`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..e227d7389515 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dateuntil +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)), + "reject minus zero as extended year (first argument)" + ); + assert.throws( + RangeError, + () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg), + "reject minus zero as extended year (second argument)" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-wrong-type.js new file mode 100644 index 000000000000..7765e0384d2b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-wrong-type.js @@ -0,0 +1,42 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dateuntil +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.Calendar("iso8601"); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)), `${description} does not convert to a valid ISO string (first argument)`); + assert.throws(RangeError, () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg), `${description} does not convert to a valid ISO string (first argument)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)), `${description} is not a valid property bag and does not convert to a string (second argument)`); + assert.throws(TypeError, () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg), `${description} is not a valid property bag and does not convert to a string (second argument)`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/leap-second.js new file mode 100644 index 000000000000..cd9435d73d04 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/leap-second.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dateuntil +description: Leap second is a valid ISO string for PlainDate +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +let arg = "2016-12-31T23:59:60"; +let result = instance.dateUntil(arg, new Temporal.PlainDate(2017, 1, 1)); +TemporalHelpers.assertDuration(result, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "leap second is a valid ISO string for PlainDate (first argument)"); +result = instance.dateUntil(new Temporal.PlainDate(2017, 1, 1), arg); +TemporalHelpers.assertDuration(result, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "leap second is a valid ISO string for PlainDate (second argument)"); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +result = instance.dateUntil(arg, new Temporal.PlainDate(2017, 1, 1)); +TemporalHelpers.assertDuration(result, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "second: 60 is ignored in property bag for PlainDate (first argument)"); +result = instance.dateUntil(new Temporal.PlainDate(2017, 1, 1), arg); +TemporalHelpers.assertDuration(result, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "second: 60 is ignored in property bag for PlainDate (second argument)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/options-wrong-type.js new file mode 100644 index 000000000000..deb5807e246a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dateuntil +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.Calendar("iso8601"); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.dateUntil(new Temporal.PlainDate(1976, 11, 18), new Temporal.PlainDate(1984, 5, 31), value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/year-zero.js index e21fbd049925..085e0717cfc7 100644 --- a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/year-zero.js @@ -10,18 +10,25 @@ features: [Temporal] const calendar = new Temporal.Calendar("iso8601"); const date = new Temporal.PlainDate(2000, 5, 2); -const bad = "-000000-03-14"; +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; -assert.throws( - RangeError, - () => calendar.dateUntil(bad, date), - "cannot use minus zero as extended date (first argument)" -); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => calendar.dateUntil(arg, date), + "cannot use minus zero as extended date (first argument)" + ); -assert.throws( - RangeError, - () => calendar.dateUntil(date, bad), - "cannot use minus zero as extended date (second argument)" -); + assert.throws( + RangeError, + () => calendar.dateUntil(date, arg), + "cannot use minus zero as extended date (second argument)" + ); +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-number.js new file mode 100644 index 000000000000..0d32a0c92289 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-number.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.day +description: A number is converted to a string, then to Temporal.PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const arg = 19761118; + +const result = instance.day(arg); +assert.sameValue(result, 18, "19761118 is a valid ISO string for PlainDate"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.day(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..e44efd899dea --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,31 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.day +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.day(arg); +assert.sameValue( + result1, + 18, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.day(arg); +assert.sameValue( + result2, + 18, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..d20d595da5f3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-number.js @@ -0,0 +1,44 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.day +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.day(arg); +assert.sameValue(result1, 18, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.day(arg); +assert.sameValue(result2, 18, "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + assert.throws( + RangeError, + () => instance.day(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.day(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..e74f0884f7ce --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.day +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.Calendar("iso8601"); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.day(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.day(arg), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.day(arg), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.day(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.day(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..7a29209bce89 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.day +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.day(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-wrong-type.js new file mode 100644 index 000000000000..0644cf7ccae0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.day +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.day(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.day(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/leap-second.js new file mode 100644 index 000000000000..5438835f5a7e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/leap-second.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.day +description: Leap second is a valid ISO string for PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.day(arg); +assert.sameValue( + result1, + 31, + "leap second is a valid ISO string for PlainDate" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.day(arg); +assert.sameValue( + result2, + 31, + "second: 60 is ignored in property bag for PlainDate" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/year-zero.js index 5c8e46cd1499..71c80d23f61a 100644 --- a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/year-zero.js @@ -8,13 +8,19 @@ description: Negative zero, as an extended year, is rejected features: [Temporal, arrow-function] ---*/ -const arg = "-000000-10-31"; +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; const instance = new Temporal.Calendar("iso8601"); - -assert.throws( +invalidStrings.forEach((arg) => { + assert.throws( RangeError, - () => { instance.day(arg); }, + () => instance.day(arg), "reject minus zero as extended year" -); + ); +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-number.js new file mode 100644 index 000000000000..f5f45225e38a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-number.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dayofweek +description: A number is converted to a string, then to Temporal.PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const arg = 19761118; + +const result = instance.dayOfWeek(arg); +assert.sameValue(result, 4, "19761118 is a valid ISO string for PlainDate"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.dayOfWeek(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..daa66528c187 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,31 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dayofweek +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.dayOfWeek(arg); +assert.sameValue( + result1, + 4, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.dayOfWeek(arg); +assert.sameValue( + result2, + 4, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..a939edc72574 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-number.js @@ -0,0 +1,44 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dayofweek +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.dayOfWeek(arg); +assert.sameValue(result1, 4, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.dayOfWeek(arg); +assert.sameValue(result2, 4, "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + assert.throws( + RangeError, + () => instance.dayOfWeek(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.dayOfWeek(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..20d252c371f4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dayofweek +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.Calendar("iso8601"); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.dayOfWeek(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.dayOfWeek(arg), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.dayOfWeek(arg), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.dayOfWeek(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.dayOfWeek(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..0c0012006caf --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dayofweek +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.dayOfWeek(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-wrong-type.js new file mode 100644 index 000000000000..f29edf6aaed7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dayofweek +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.dayOfWeek(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.dayOfWeek(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/leap-second.js new file mode 100644 index 000000000000..31b44a6c823c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/leap-second.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dayofweek +description: Leap second is a valid ISO string for PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.dayOfWeek(arg); +assert.sameValue( + result1, + 6, + "leap second is a valid ISO string for PlainDate" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.dayOfWeek(arg); +assert.sameValue( + result2, + 6, + "second: 60 is ignored in property bag for PlainDate" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/year-zero.js index 4813d393bc9d..0a81bab67238 100644 --- a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/year-zero.js @@ -8,13 +8,19 @@ description: Negative zero, as an extended year, is rejected features: [Temporal, arrow-function] ---*/ -const arg = "-000000-10-31"; +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; const instance = new Temporal.Calendar("iso8601"); - -assert.throws( +invalidStrings.forEach((arg) => { + assert.throws( RangeError, - () => { instance.dayOfWeek(arg); }, + () => instance.dayOfWeek(arg), "reject minus zero as extended year" -); + ); +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-number.js new file mode 100644 index 000000000000..b5f97c68cfb1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-number.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dayofyear +description: A number is converted to a string, then to Temporal.PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const arg = 19761118; + +const result = instance.dayOfYear(arg); +assert.sameValue(result, 323, "19761118 is a valid ISO string for PlainDate"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.dayOfYear(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..f40f60b2691d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,31 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dayofyear +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.dayOfYear(arg); +assert.sameValue( + result1, + 323, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.dayOfYear(arg); +assert.sameValue( + result2, + 323, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..dd89b9f401b3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-number.js @@ -0,0 +1,44 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dayofyear +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.dayOfYear(arg); +assert.sameValue(result1, 323, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.dayOfYear(arg); +assert.sameValue(result2, 323, "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + assert.throws( + RangeError, + () => instance.dayOfYear(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.dayOfYear(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..f6e4baece769 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dayofyear +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.Calendar("iso8601"); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.dayOfYear(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.dayOfYear(arg), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.dayOfYear(arg), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.dayOfYear(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.dayOfYear(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..3ad481707fac --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dayofyear +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.dayOfYear(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-wrong-type.js new file mode 100644 index 000000000000..9b12533701d3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dayofyear +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.dayOfYear(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.dayOfYear(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/leap-second.js new file mode 100644 index 000000000000..242299d75e32 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/leap-second.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.dayofyear +description: Leap second is a valid ISO string for PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.dayOfYear(arg); +assert.sameValue( + result1, + 366, + "leap second is a valid ISO string for PlainDate" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.dayOfYear(arg); +assert.sameValue( + result2, + 366, + "second: 60 is ignored in property bag for PlainDate" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/year-zero.js index dd6c5564e7f2..51543e03c0b7 100644 --- a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/year-zero.js @@ -8,13 +8,19 @@ description: Negative zero, as an extended year, is rejected features: [Temporal, arrow-function] ---*/ -const arg = "-000000-10-31"; +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; const instance = new Temporal.Calendar("iso8601"); - -assert.throws( +invalidStrings.forEach((arg) => { + assert.throws( RangeError, - () => { instance.dayOfYear(arg); }, + () => instance.dayOfYear(arg), "reject minus zero as extended year" -); + ); +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-number.js new file mode 100644 index 000000000000..62b98d7a9488 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-number.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.daysinmonth +description: A number is converted to a string, then to Temporal.PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const arg = 19761118; + +const result = instance.daysInMonth(arg); +assert.sameValue(result, 30, "19761118 is a valid ISO string for PlainDate"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.daysInMonth(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..5f1cb805fd58 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,31 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.daysinmonth +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.daysInMonth(arg); +assert.sameValue( + result1, + 30, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.daysInMonth(arg); +assert.sameValue( + result2, + 30, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..ff8a04645b70 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-number.js @@ -0,0 +1,44 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.daysinmonth +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.daysInMonth(arg); +assert.sameValue(result1, 30, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.daysInMonth(arg); +assert.sameValue(result2, 30, "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + assert.throws( + RangeError, + () => instance.daysInMonth(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.daysInMonth(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..043baab71d45 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.daysinmonth +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.Calendar("iso8601"); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.daysInMonth(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.daysInMonth(arg), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.daysInMonth(arg), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.daysInMonth(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.daysInMonth(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..39c58394166b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.daysinmonth +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.daysInMonth(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-wrong-type.js new file mode 100644 index 000000000000..9e43a5f0311d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.daysinmonth +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.daysInMonth(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.daysInMonth(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/leap-second.js new file mode 100644 index 000000000000..fbe398944d16 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/leap-second.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.daysinmonth +description: Leap second is a valid ISO string for PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.daysInMonth(arg); +assert.sameValue( + result1, + 31, + "leap second is a valid ISO string for PlainDate" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.daysInMonth(arg); +assert.sameValue( + result2, + 31, + "second: 60 is ignored in property bag for PlainDate" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/year-zero.js index 72dad31bd3c2..fa887a46e927 100644 --- a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/year-zero.js @@ -8,13 +8,19 @@ description: Negative zero, as an extended year, is rejected features: [Temporal, arrow-function] ---*/ -const arg = "-000000-10-31"; +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; const instance = new Temporal.Calendar("iso8601"); - -assert.throws( +invalidStrings.forEach((arg) => { + assert.throws( RangeError, - () => { instance.daysInMonth(arg); }, + () => instance.daysInMonth(arg), "reject minus zero as extended year" -); + ); +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-number.js new file mode 100644 index 000000000000..184c1952ffb1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-number.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.daysinweek +description: A number is converted to a string, then to Temporal.PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const arg = 19761118; + +const result = instance.daysInWeek(arg); +assert.sameValue(result, 7, "19761118 is a valid ISO string for PlainDate"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.daysInWeek(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..ce17da50a3ef --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,31 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.daysinweek +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.daysInWeek(arg); +assert.sameValue( + result1, + 7, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.daysInWeek(arg); +assert.sameValue( + result2, + 7, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..9c8044c63383 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-number.js @@ -0,0 +1,44 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.daysinweek +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.daysInWeek(arg); +assert.sameValue(result1, 7, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.daysInWeek(arg); +assert.sameValue(result2, 7, "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + assert.throws( + RangeError, + () => instance.daysInWeek(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.daysInWeek(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..62cad9b23b7f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.daysinweek +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.Calendar("iso8601"); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.daysInWeek(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.daysInWeek(arg), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.daysInWeek(arg), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.daysInWeek(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.daysInWeek(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..611aa364760d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.daysinweek +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.daysInWeek(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-wrong-type.js new file mode 100644 index 000000000000..81ece23888d6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.daysinweek +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.daysInWeek(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.daysInWeek(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/leap-second.js new file mode 100644 index 000000000000..084bbbe6e412 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/leap-second.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.daysinweek +description: Leap second is a valid ISO string for PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.daysInWeek(arg); +assert.sameValue( + result1, + 7, + "leap second is a valid ISO string for PlainDate" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.daysInWeek(arg); +assert.sameValue( + result2, + 7, + "second: 60 is ignored in property bag for PlainDate" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/year-zero.js index faa2bf7d6959..62970bbb7db4 100644 --- a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/year-zero.js @@ -8,13 +8,19 @@ description: Negative zero, as an extended year, is rejected features: [Temporal, arrow-function] ---*/ -const arg = "-000000-10-31"; +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; const instance = new Temporal.Calendar("iso8601"); - -assert.throws( +invalidStrings.forEach((arg) => { + assert.throws( RangeError, - () => { instance.daysInWeek(arg); }, + () => instance.daysInWeek(arg), "reject minus zero as extended year" -); + ); +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-number.js new file mode 100644 index 000000000000..51b3bb26ace2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-number.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.daysinyear +description: A number is converted to a string, then to Temporal.PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const arg = 19761118; + +const result = instance.daysInYear(arg); +assert.sameValue(result, 366, "19761118 is a valid ISO string for PlainDate"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.daysInYear(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..8ff437c8a848 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,31 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.daysinyear +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.daysInYear(arg); +assert.sameValue( + result1, + 366, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.daysInYear(arg); +assert.sameValue( + result2, + 366, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..2c0fe356db4f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-number.js @@ -0,0 +1,44 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.daysinyear +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.daysInYear(arg); +assert.sameValue(result1, 366, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.daysInYear(arg); +assert.sameValue(result2, 366, "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + assert.throws( + RangeError, + () => instance.daysInYear(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.daysInYear(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..37330243ae9d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.daysinyear +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.Calendar("iso8601"); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.daysInYear(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.daysInYear(arg), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.daysInYear(arg), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.daysInYear(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.daysInYear(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..f8ef34a4db06 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.daysinyear +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.daysInYear(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-wrong-type.js new file mode 100644 index 000000000000..40900bb96f15 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.daysinyear +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.daysInYear(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.daysInYear(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/leap-second.js new file mode 100644 index 000000000000..27f3739a8f33 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/leap-second.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.daysinyear +description: Leap second is a valid ISO string for PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.daysInYear(arg); +assert.sameValue( + result1, + 366, + "leap second is a valid ISO string for PlainDate" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.daysInYear(arg); +assert.sameValue( + result2, + 366, + "second: 60 is ignored in property bag for PlainDate" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/year-zero.js index a5a1616412b8..89d87d7882fb 100644 --- a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/year-zero.js @@ -8,13 +8,19 @@ description: Negative zero, as an extended year, is rejected features: [Temporal, arrow-function] ---*/ -const arg = "-000000-10-31"; +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; const instance = new Temporal.Calendar("iso8601"); - -assert.throws( +invalidStrings.forEach((arg) => { + assert.throws( RangeError, - () => { instance.daysInYear(arg); }, + () => instance.daysInYear(arg), "reject minus zero as extended year" -); + ); +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/branding.js new file mode 100644 index 000000000000..da9639b197dd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/branding.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.id +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const descriptor = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "id"); +const id = descriptor.get; + +assert.sameValue(typeof id, "function"); + +assert.throws(TypeError, () => id.call(undefined), "undefined"); +assert.throws(TypeError, () => id.call(null), "null"); +assert.throws(TypeError, () => id.call(true), "true"); +assert.throws(TypeError, () => id.call(""), "empty string"); +assert.throws(TypeError, () => id.call(Symbol()), "symbol"); +assert.throws(TypeError, () => id.call(1), "1"); +assert.throws(TypeError, () => id.call({}), "plain object"); +assert.throws(TypeError, () => id.call(Temporal.Calendar), "Temporal.Calendar"); +assert.throws(TypeError, () => id.call(Temporal.Calendar.prototype), "Temporal.Calendar.prototype"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DurationFormat/instance/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/browser.js similarity index 100% rename from js/src/tests/test262/intl402/DurationFormat/instance/browser.js rename to js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/browser.js diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/prop-desc.js new file mode 100644 index 000000000000..82f37250bf84 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/prop-desc.js @@ -0,0 +1,17 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-get-temporal.calendar.prototype.id +description: The "id" property of Temporal.Calendar.prototype +features: [Temporal] +---*/ + +const descriptor = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "id"); +assert.sameValue(typeof descriptor.get, "function"); +assert.sameValue(descriptor.set, undefined); +assert.sameValue(descriptor.enumerable, false); +assert.sameValue(descriptor.configurable, true); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DurationFormat/instance/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/shell.js similarity index 100% rename from js/src/tests/test262/intl402/DurationFormat/instance/shell.js rename to js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/shell.js diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-number.js new file mode 100644 index 000000000000..b95b289ba741 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-number.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.inleapyear +description: A number is converted to a string, then to Temporal.PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const arg = 19761118; + +const result = instance.inLeapYear(arg); +assert.sameValue(result, true, "19761118 is a valid ISO string for PlainDate"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.inLeapYear(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..ca9eaef00665 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,31 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.inleapyear +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.inLeapYear(arg); +assert.sameValue( + result1, + true, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.inLeapYear(arg); +assert.sameValue( + result2, + true, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..59e1116e1962 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-number.js @@ -0,0 +1,44 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.inleapyear +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.inLeapYear(arg); +assert.sameValue(result1, true, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.inLeapYear(arg); +assert.sameValue(result2, true, "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + assert.throws( + RangeError, + () => instance.inLeapYear(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.inLeapYear(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..c2dccc644091 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.inleapyear +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.Calendar("iso8601"); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.inLeapYear(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.inLeapYear(arg), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.inLeapYear(arg), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.inLeapYear(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.inLeapYear(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..8117471211ac --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.inleapyear +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.inLeapYear(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-wrong-type.js new file mode 100644 index 000000000000..730c318839e1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.inleapyear +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.inLeapYear(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.inLeapYear(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/leap-second.js new file mode 100644 index 000000000000..dc4638be2bf1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/leap-second.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.inleapyear +description: Leap second is a valid ISO string for PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.inLeapYear(arg); +assert.sameValue( + result1, + true, + "leap second is a valid ISO string for PlainDate" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.inLeapYear(arg); +assert.sameValue( + result2, + true, + "second: 60 is ignored in property bag for PlainDate" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/year-zero.js index bf7c4d923a70..4706173e1646 100644 --- a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/year-zero.js @@ -8,13 +8,19 @@ description: Negative zero, as an extended year, is rejected features: [Temporal, arrow-function] ---*/ -const arg = "-000000-10-31"; +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; const instance = new Temporal.Calendar("iso8601"); - -assert.throws( +invalidStrings.forEach((arg) => { + assert.throws( RangeError, - () => { instance.inLeapYear(arg); }, + () => instance.inLeapYear(arg), "reject minus zero as extended year" -); + ); +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-number.js new file mode 100644 index 000000000000..83810e8a2346 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-number.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.month +description: A number is converted to a string, then to Temporal.PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const arg = 19761118; + +const result = instance.month(arg); +assert.sameValue(result, 11, "19761118 is a valid ISO string for PlainDate"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.month(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..35f6ed0d4260 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,31 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.month +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.month(arg); +assert.sameValue( + result1, + 11, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.month(arg); +assert.sameValue( + result2, + 11, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..53398e531bc5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-number.js @@ -0,0 +1,44 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.month +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.month(arg); +assert.sameValue(result1, 11, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.month(arg); +assert.sameValue(result2, 11, "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + assert.throws( + RangeError, + () => instance.month(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.month(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..102d2f20e303 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.month +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.Calendar("iso8601"); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.month(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.month(arg), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.month(arg), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.month(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.month(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..f5741c4283c3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.month +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.month(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-wrong-type.js new file mode 100644 index 000000000000..679b695387ab --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.month +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.month(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.month(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/leap-second.js new file mode 100644 index 000000000000..9be9b828c367 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/leap-second.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.month +description: Leap second is a valid ISO string for PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.month(arg); +assert.sameValue( + result1, + 12, + "leap second is a valid ISO string for PlainDate" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.month(arg); +assert.sameValue( + result2, + 12, + "second: 60 is ignored in property bag for PlainDate" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/year-zero.js index ca88a7a03f8a..928e40d6f4c9 100644 --- a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/year-zero.js @@ -8,13 +8,19 @@ description: Negative zero, as an extended year, is rejected features: [Temporal, arrow-function] ---*/ -const arg = "-000000-10-31"; +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; const instance = new Temporal.Calendar("iso8601"); - -assert.throws( +invalidStrings.forEach((arg) => { + assert.throws( RangeError, - () => { instance.month(arg); }, + () => instance.month(arg), "reject minus zero as extended year" -); + ); +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-number.js new file mode 100644 index 000000000000..9a49756189a5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-number.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.monthcode +description: A number is converted to a string, then to Temporal.PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const arg = 19761118; + +const result = instance.monthCode(arg); +assert.sameValue(result, "M11", "19761118 is a valid ISO string for PlainDate"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.monthCode(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..3c4d18bd60ae --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,31 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.monthcode +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.monthCode(arg); +assert.sameValue( + result1, + "M11", + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.monthCode(arg); +assert.sameValue( + result2, + "M11", + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..7a6a41b4599c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-number.js @@ -0,0 +1,44 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.monthcode +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.monthCode(arg); +assert.sameValue(result1, "M11", "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.monthCode(arg); +assert.sameValue(result2, "M11", "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + assert.throws( + RangeError, + () => instance.monthCode(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.monthCode(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..0cd0de20b196 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.monthcode +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.Calendar("iso8601"); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.monthCode(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.monthCode(arg), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.monthCode(arg), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.monthCode(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.monthCode(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..e79fc0f84666 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.monthcode +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.monthCode(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-wrong-type.js new file mode 100644 index 000000000000..36deb691ede7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.monthcode +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.monthCode(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.monthCode(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/leap-second.js new file mode 100644 index 000000000000..5dd69d7cdb22 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/leap-second.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.monthcode +description: Leap second is a valid ISO string for PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.monthCode(arg); +assert.sameValue( + result1, + "M12", + "leap second is a valid ISO string for PlainDate" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.monthCode(arg); +assert.sameValue( + result2, + "M12", + "second: 60 is ignored in property bag for PlainDate" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/year-zero.js index f7d565add63c..24a0423c9a21 100644 --- a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/year-zero.js @@ -8,13 +8,19 @@ description: Negative zero, as an extended year, is rejected features: [Temporal, arrow-function] ---*/ -const arg = "-000000-10-31"; +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; const instance = new Temporal.Calendar("iso8601"); - -assert.throws( +invalidStrings.forEach((arg) => { + assert.throws( RangeError, - () => { instance.monthCode(arg); }, + () => instance.monthCode(arg), "reject minus zero as extended year" -); + ); +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/options-wrong-type.js new file mode 100644 index 000000000000..59b8730d2d6f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.monthdayfromfields +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.Calendar("iso8601"); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.monthDayFromFields({ monthCode: "M12", day: 15 }, value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-number.js new file mode 100644 index 000000000000..c4876c92193a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-number.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.monthsinyear +description: A number is converted to a string, then to Temporal.PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const arg = 19761118; + +const result = instance.monthsInYear(arg); +assert.sameValue(result, 12, "19761118 is a valid ISO string for PlainDate"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.monthsInYear(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..3f738aa0b903 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,31 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.monthsinyear +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.monthsInYear(arg); +assert.sameValue( + result1, + 12, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.monthsInYear(arg); +assert.sameValue( + result2, + 12, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..ae18bd1fb430 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-number.js @@ -0,0 +1,44 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.monthsinyear +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.monthsInYear(arg); +assert.sameValue(result1, 12, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.monthsInYear(arg); +assert.sameValue(result2, 12, "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + assert.throws( + RangeError, + () => instance.monthsInYear(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.monthsInYear(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..a5157d449e06 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.monthsinyear +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.Calendar("iso8601"); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.monthsInYear(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.monthsInYear(arg), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.monthsInYear(arg), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.monthsInYear(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.monthsInYear(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..d87b04f88953 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.monthsinyear +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.monthsInYear(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-wrong-type.js new file mode 100644 index 000000000000..b178789d3017 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.monthsinyear +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.monthsInYear(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.monthsInYear(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/leap-second.js new file mode 100644 index 000000000000..209c126375eb --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/leap-second.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.monthsinyear +description: Leap second is a valid ISO string for PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.monthsInYear(arg); +assert.sameValue( + result1, + 12, + "leap second is a valid ISO string for PlainDate" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.monthsInYear(arg); +assert.sameValue( + result2, + 12, + "second: 60 is ignored in property bag for PlainDate" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/year-zero.js index 1a55a1837c0b..9c6e1e7196fe 100644 --- a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/year-zero.js @@ -8,13 +8,19 @@ description: Negative zero, as an extended year, is rejected features: [Temporal, arrow-function] ---*/ -const arg = "-000000-10-31"; +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; const instance = new Temporal.Calendar("iso8601"); - -assert.throws( +invalidStrings.forEach((arg) => { + assert.throws( RangeError, - () => { instance.monthsInYear(arg); }, + () => instance.monthsInYear(arg), "reject minus zero as extended year" -); + ); +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-number.js new file mode 100644 index 000000000000..b9ebf188a76e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-number.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.weekofyear +description: A number is converted to a string, then to Temporal.PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const arg = 19761118; + +const result = instance.weekOfYear(arg); +assert.sameValue(result, 47, "19761118 is a valid ISO string for PlainDate"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.weekOfYear(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..4b3792f34614 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,31 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.weekofyear +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.weekOfYear(arg); +assert.sameValue( + result1, + 47, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.weekOfYear(arg); +assert.sameValue( + result2, + 47, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..c5c9117e8664 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-number.js @@ -0,0 +1,44 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.weekofyear +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.weekOfYear(arg); +assert.sameValue(result1, 47, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.weekOfYear(arg); +assert.sameValue(result2, 47, "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + assert.throws( + RangeError, + () => instance.weekOfYear(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.weekOfYear(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..90ac76d277a6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.weekofyear +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.Calendar("iso8601"); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.weekOfYear(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.weekOfYear(arg), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.weekOfYear(arg), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.weekOfYear(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.weekOfYear(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..321b2a24fb16 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.weekofyear +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.weekOfYear(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-wrong-type.js new file mode 100644 index 000000000000..c01cbccbf86d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.weekofyear +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.weekOfYear(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.weekOfYear(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/leap-second.js new file mode 100644 index 000000000000..b740a5f4f0de --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/leap-second.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.weekofyear +description: Leap second is a valid ISO string for PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.weekOfYear(arg); +assert.sameValue( + result1, + 52, + "leap second is a valid ISO string for PlainDate" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.weekOfYear(arg); +assert.sameValue( + result2, + 52, + "second: 60 is ignored in property bag for PlainDate" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/year-zero.js index ee65a5a7b30f..f7a798b849c5 100644 --- a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/year-zero.js @@ -8,13 +8,19 @@ description: Negative zero, as an extended year, is rejected features: [Temporal, arrow-function] ---*/ -const arg = "-000000-10-31"; +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; const instance = new Temporal.Calendar("iso8601"); - -assert.throws( +invalidStrings.forEach((arg) => { + assert.throws( RangeError, - () => { instance.weekOfYear(arg); }, + () => instance.weekOfYear(arg), "reject minus zero as extended year" -); + ); +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-number.js new file mode 100644 index 000000000000..4ef02c995bd4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-number.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.year +description: A number is converted to a string, then to Temporal.PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const arg = 19761118; + +const result = instance.year(arg); +assert.sameValue(result, 1976, "19761118 is a valid ISO string for PlainDate"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.year(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..542ecde17ea5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,31 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.year +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.year(arg); +assert.sameValue( + result1, + 1976, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.year(arg); +assert.sameValue( + result2, + 1976, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..0df0395bdd7f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-number.js @@ -0,0 +1,44 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.year +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.year(arg); +assert.sameValue(result1, 1976, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.year(arg); +assert.sameValue(result2, 1976, "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + assert.throws( + RangeError, + () => instance.year(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.year(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..79ffa0817a89 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.year +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.Calendar("iso8601"); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.year(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.year(arg), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.year(arg), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.year(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.year(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..7d973a2718f8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.year +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.year(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-wrong-type.js new file mode 100644 index 000000000000..2f14a8efe657 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.year +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.year(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.year(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/leap-second.js new file mode 100644 index 000000000000..1608cbed9d27 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/leap-second.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.year +description: Leap second is a valid ISO string for PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.year(arg); +assert.sameValue( + result1, + 2016, + "leap second is a valid ISO string for PlainDate" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.year(arg); +assert.sameValue( + result2, + 2016, + "second: 60 is ignored in property bag for PlainDate" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/year-zero.js index 9ce68d325a4a..31c7467c669b 100644 --- a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/year-zero.js @@ -8,13 +8,19 @@ description: Negative zero, as an extended year, is rejected features: [Temporal, arrow-function] ---*/ -const arg = "-000000-10-31"; +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; const instance = new Temporal.Calendar("iso8601"); - -assert.throws( +invalidStrings.forEach((arg) => { + assert.throws( RangeError, - () => { instance.year(arg); }, + () => instance.year(arg), "reject minus zero as extended year" -); + ); +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/options-wrong-type.js new file mode 100644 index 000000000000..9a4bd2f4375e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.yearmonthfromfields +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.Calendar("iso8601"); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.yearMonthFromFields({ year: 2000, monthCode: "M05" }, value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/compare/argument-cast.js b/js/src/tests/test262/built-ins/Temporal/Duration/compare/argument-cast.js new file mode 100644 index 000000000000..0144de21276c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/compare/argument-cast.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.compare +description: Strings and objects are supported arguments. +features: [Temporal] +---*/ + +assert.sameValue(Temporal.Duration.compare("PT12H", new Temporal.Duration()), 1, + "first argument string"); +assert.sameValue(Temporal.Duration.compare({ hours: 12 }, new Temporal.Duration()), 1, + "first argument object"); +assert.throws(TypeError, () => Temporal.Duration.compare({ hour: 12 }, new Temporal.Duration()), + "first argument missing property"); + +assert.sameValue(Temporal.Duration.compare(new Temporal.Duration(), "PT12H"), -1, + "second argument string"); +assert.sameValue(Temporal.Duration.compare(new Temporal.Duration(), { hours: 12 }), -1, + "second argument object"); +assert.throws(TypeError, () => Temporal.Duration.compare(new Temporal.Duration(), { hour: 12 }), + "second argument missing property"); + +assert.sameValue(Temporal.Duration.compare({ hours: 12, minute: 5 }, { hours: 12, day: 5 }), 0, + "ignores incorrect properties"); + + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/compare/basic.js b/js/src/tests/test262/built-ins/Temporal/Duration/compare/basic.js new file mode 100644 index 000000000000..b3d1fe8040a4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/compare/basic.js @@ -0,0 +1,56 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.compare +description: Basic comparisons. +features: [Temporal] +---*/ + +const td1pos = new Temporal.Duration(0, 0, 0, 0, 5, 5, 5, 5, 5, 5); +const td2pos = new Temporal.Duration(0, 0, 0, 0, 5, 4, 5, 5, 5, 5); +const td1neg = new Temporal.Duration(0, 0, 0, 0, -5, -5, -5, -5, -5, -5); +const td2neg = new Temporal.Duration(0, 0, 0, 0, -5, -4, -5, -5, -5, -5); +assert.sameValue(Temporal.Duration.compare(td1pos, td1pos), 0, + "time units: equal"); +assert.sameValue(Temporal.Duration.compare(td2pos, td1pos), -1, + "time units: smaller/larger"); +assert.sameValue(Temporal.Duration.compare(td1pos, td2pos), 1, + "time units: larger/smaller"); +assert.sameValue(Temporal.Duration.compare(td1neg, td1neg), 0, + "time units: negative/negative equal"); +assert.sameValue(Temporal.Duration.compare(td2neg, td1neg), 1, + "time units: negative/negative smaller/larger"); +assert.sameValue(Temporal.Duration.compare(td1neg, td2neg), -1, + "time units: negative/negative larger/smaller"); +assert.sameValue(Temporal.Duration.compare(td1neg, td2pos), -1, + "time units: negative/positive"); +assert.sameValue(Temporal.Duration.compare(td1pos, td2neg), 1, + "time units: positive/negative"); + +const dd1pos = new Temporal.Duration(5, 5, 5, 5, 5, 5, 5, 5, 5, 5); +const dd2pos = new Temporal.Duration(5, 5, 5, 5, 5, 4, 5, 5, 5, 5); +const dd1neg = new Temporal.Duration(-5, -5, -5, -5, -5, -5, -5, -5, -5, -5); +const dd2neg = new Temporal.Duration(-5, -5, -5, -5, -5, -4, -5, -5, -5, -5); +const relativeTo = Temporal.PlainDate.from("2017-01-01"); +assert.throws(RangeError, () => Temporal.Duration.compare(dd1pos, dd2pos), + "date units: relativeTo is required"); +assert.sameValue(Temporal.Duration.compare(dd1pos, dd1pos, { relativeTo }), 0, + "date units: equal"); +assert.sameValue(Temporal.Duration.compare(dd2pos, dd1pos, { relativeTo }), -1, + "date units: smaller/larger"); +assert.sameValue(Temporal.Duration.compare(dd1pos, dd2pos, { relativeTo }), 1, + "date units: larger/smaller"); +assert.sameValue(Temporal.Duration.compare(dd1neg, dd1neg, { relativeTo }), 0, + "date units: negative/negative equal"); +assert.sameValue(Temporal.Duration.compare(dd2neg, dd1neg, { relativeTo }), 1, + "date units: negative/negative smaller/larger"); +assert.sameValue(Temporal.Duration.compare(dd1neg, dd2neg, { relativeTo }), -1, + "date units: negative/negative larger/smaller"); +assert.sameValue(Temporal.Duration.compare(dd1neg, dd2pos, { relativeTo }), -1, + "date units: negative/positive"); +assert.sameValue(Temporal.Duration.compare(dd1pos, dd2neg, { relativeTo }), 1, + "date units: positive/negative"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/compare/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Duration/compare/options-wrong-type.js new file mode 100644 index 000000000000..727bdc6ac3f7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/compare/options-wrong-type.js @@ -0,0 +1,25 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.compare +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +for (const value of badOptions) { + assert.throws(TypeError, () => Temporal.Duration.compare({ hours: 1 }, { minutes: 60 }, value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/compare/relativeto-hour.js b/js/src/tests/test262/built-ins/Temporal/Duration/compare/relativeto-hour.js new file mode 100644 index 000000000000..cb107450bff1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/compare/relativeto-hour.js @@ -0,0 +1,44 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.compare +description: relativeTo with hours. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const oneDay = new Temporal.Duration(0, 0, 0, 1); +const hours24 = new Temporal.Duration(0, 0, 0, 0, 24); +assert.sameValue(Temporal.Duration.compare(oneDay, hours24), + 0, + "relativeTo not required for days"); +assert.sameValue( + Temporal.Duration.compare(oneDay, hours24, { relativeTo: Temporal.PlainDate.from("2017-01-01") }), + 0, + "relativeTo does not affect days if PlainDate"); +assert.sameValue(Temporal.Duration.compare(oneDay, hours24, { relativeTo: "2019-11-03" }), + 0, + "casts relativeTo to PlainDate from string"); +assert.sameValue(Temporal.Duration.compare(oneDay, hours24, { relativeTo: { year: 2019, month: 11, day: 3 } }), + 0, + "casts relativeTo to PlainDate from object"); + +const timeZone = TemporalHelpers.springForwardFallBackTimeZone(); +assert.sameValue( + Temporal.Duration.compare(oneDay, hours24, { relativeTo: new Temporal.ZonedDateTime(0n, timeZone) }), + 0, + 'relativeTo does not affect days if ZonedDateTime, and duration encompasses no DST change'); +assert.sameValue( + Temporal.Duration.compare(oneDay, hours24, { relativeTo: new Temporal.ZonedDateTime(972802800_000_000_000n, timeZone) }), + 1, + 'relativeTo does affect days if ZonedDateTime, and duration encompasses DST change'); +assert.sameValue( + Temporal.Duration.compare(oneDay, hours24, { + relativeTo: { year: 2000, month: 10, day: 29, timeZone } + }), + 1, + 'casts relativeTo to ZonedDateTime from object'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/compare/relativeto-month.js b/js/src/tests/test262/built-ins/Temporal/Duration/compare/relativeto-month.js new file mode 100644 index 000000000000..0ede90da7c70 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/compare/relativeto-month.js @@ -0,0 +1,20 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.compare +description: relativeTo with months. +features: [Temporal] +---*/ + +const oneMonth = new Temporal.Duration(0, 1); +const days30 = new Temporal.Duration(0, 0, 0, 30); +assert.sameValue( + Temporal.Duration.compare(oneMonth, days30, { relativeTo: Temporal.PlainDate.from("2018-04-01") }), 0); +assert.sameValue( + Temporal.Duration.compare(oneMonth, days30, { relativeTo: Temporal.PlainDate.from("2018-03-01") }), 1); +assert.sameValue( + Temporal.Duration.compare(oneMonth, days30, { relativeTo: Temporal.PlainDate.from("2018-02-01") }), -1); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/compare/relativeto-propertybag-invalid.js b/js/src/tests/test262/built-ins/Temporal/Duration/compare/relativeto-propertybag-invalid.js new file mode 100644 index 000000000000..b2f74d2f9423 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/compare/relativeto-propertybag-invalid.js @@ -0,0 +1,17 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.compare +description: Throws if a value in the relativeTo property bag is missing. +features: [Temporal] +---*/ + +const oneDay = new Temporal.Duration(0, 0, 0, 1); +const hours24 = new Temporal.Duration(0, 0, 0, 0, 24); +assert.throws(TypeError, () => Temporal.Duration.compare(oneDay, hours24, { relativeTo: { month: 11, day: 3 } }), "missing year"); +assert.throws(TypeError, () => Temporal.Duration.compare(oneDay, hours24, { relativeTo: { year: 2019, month: 11 } }), "missing day"); +assert.throws(TypeError, () => Temporal.Duration.compare(oneDay, hours24, { relativeTo: { year: 2019, day: 3 } }), "missing month"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/compare/relativeto-year.js b/js/src/tests/test262/built-ins/Temporal/Duration/compare/relativeto-year.js new file mode 100644 index 000000000000..3cb4f21a1d26 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/compare/relativeto-year.js @@ -0,0 +1,18 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.compare +description: relativeTo with years. +features: [Temporal] +---*/ + +const oneYear = new Temporal.Duration(1); +const days365 = new Temporal.Duration(0, 0, 0, 365); +assert.sameValue( + Temporal.Duration.compare(oneYear, days365, { relativeTo: Temporal.PlainDate.from("2017-01-01") }), 0); +assert.sameValue( + Temporal.Duration.compare(oneYear, days365, { relativeTo: Temporal.PlainDate.from("2016-01-01") }), 1); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/compare/timezone-string-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Duration/compare/timezone-string-leap-second.js new file mode 100644 index 000000000000..bef606c98d92 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/compare/timezone-string-leap-second.js @@ -0,0 +1,23 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.compare +description: Leap second is a valid ISO string for TimeZone +features: [Temporal] +---*/ + +let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; + +// A string with a leap second is a valid ISO string, so the following two +// operations should not throw + +Temporal.Duration.compare(new Temporal.Duration(), new Temporal.Duration(), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }); +Temporal.Duration.compare(new Temporal.Duration(), new Temporal.Duration(), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }); + +timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; +assert.throws(RangeError, () => Temporal.Duration.compare(new Temporal.Duration(), new Temporal.Duration(), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), "leap second in time zone name not valid"); +assert.throws(RangeError, () => Temporal.Duration.compare(new Temporal.Duration(), new Temporal.Duration(), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), "leap second in time zone name not valid (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/compare/timezone-string-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Duration/compare/timezone-string-year-zero.js new file mode 100644 index 000000000000..021476c786f3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/compare/timezone-string-year-zero.js @@ -0,0 +1,28 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.compare +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+00:00[UTC]", +]; +invalidStrings.forEach((timeZone) => { + assert.throws( + RangeError, + () => Temporal.Duration.compare(new Temporal.Duration(), new Temporal.Duration(), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), + "reject minus zero as extended year" + ); + assert.throws( + RangeError, + () => Temporal.Duration.compare(new Temporal.Duration(), new Temporal.Duration(), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), + "reject minus zero as extended year (nested property)" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/compare/timezone-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Duration/compare/timezone-wrong-type.js new file mode 100644 index 000000000000..77f2c397e700 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/compare/timezone-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.compare +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for TimeZone +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], +]; + +for (const [timeZone, description] of rangeErrorTests) { + assert.throws(RangeError, () => Temporal.Duration.compare(new Temporal.Duration(), new Temporal.Duration(), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), `${description} does not convert to a valid ISO string`); + assert.throws(RangeError, () => Temporal.Duration.compare(new Temporal.Duration(), new Temporal.Duration(), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [timeZone, description] of typeErrorTests) { + assert.throws(TypeError, () => Temporal.Duration.compare(new Temporal.Duration(), new Temporal.Duration(), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), `${description} is not a valid object and does not convert to a string`); + assert.throws(TypeError, () => Temporal.Duration.compare(new Temporal.Duration(), new Temporal.Duration(), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), `${description} is not a valid object and does not convert to a string (nested property)`); +} + +const timeZone = undefined; +assert.throws(RangeError, () => Temporal.Duration.compare(new Temporal.Duration(), new Temporal.Duration(), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), `undefined is always a RangeError as nested property`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/from/argument-duration.js b/js/src/tests/test262/built-ins/Temporal/Duration/from/argument-duration.js new file mode 100644 index 000000000000..e723380c4b01 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/from/argument-duration.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.from +description: A Duration object is copied, not returned directly +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const orig = new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, 987, 654, 321); +const result = Temporal.Duration.from(orig); + +TemporalHelpers.assertDuration( + result, + 1, 2, 3, 4, 5, 6, 7, 987, 654, 321, + "Duration is copied" +); + +assert.notSameValue( + result, + orig, + "When a Duration is given, the returned value is not the original Duration" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/abs/new-object.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/abs/new-object.js new file mode 100644 index 000000000000..d03be3a575f7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/abs/new-object.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.abs +description: Temporal.Duration.prototype.abs returns a new object. +features: [Temporal] +---*/ + +let d1 = new Temporal.Duration(); +assert.notSameValue(d1.abs(), d1); + +let d2 = new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); +assert.notSameValue(d2.abs(), d2); + +let d3 = new Temporal.Duration(1e5, 2e5, 3e5, 4e5, 5e5, 6e5, 7e5, 8e5, 9e5, 10e5); +assert.notSameValue(d3.abs(), d3); + +let d4 = new Temporal.Duration(-1, -2, -3, -4, -5, -6, -7, -8, -9, -10); +assert.notSameValue(d4.abs(), d4); + +// Test with some zeros +let d5 = new Temporal.Duration(1, 0, 3, 0, 5, 0, 7, 0, 9, 0); +assert.notSameValue(d5.abs(), d5); + +let d6 = new Temporal.Duration(0, 2, 0, 4, 0, 6, 0, 8, 0, 10); +assert.notSameValue(d6.abs(), d6); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/argument-object-invalid.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/argument-object-invalid.js new file mode 100644 index 000000000000..a7331fc6e0d7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/argument-object-invalid.js @@ -0,0 +1,16 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.add +description: Mixed positive and negative values or missing properties always throw +features: [Temporal] +---*/ + +const duration = Temporal.Duration.from({ days: 1, minutes: 5 }); +assert.throws(RangeError, () => duration.add({ hours: 1, minutes: -30 }), "mixed signs"); +assert.throws(TypeError, () => duration.add({}), "no properties"); +assert.throws(TypeError, () => duration.add({ month: 12 }), "only singular 'month' property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/argument-string.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/argument-string.js new file mode 100644 index 000000000000..e31ef8436bfe --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/argument-string.js @@ -0,0 +1,17 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.add +description: String arguments are supported. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const duration = Temporal.Duration.from({ days: 1, minutes: 5 }); +const result = duration.add("P2DT5M"); +TemporalHelpers.assertDuration(result, 0, 0, 0, 3, 0, 10, 0, 0, 0, 0, "String argument should be supported"); +assert.throws(RangeError, () => duration.add("2DT5M"), "Invalid string argument should throw"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/basic.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/basic.js new file mode 100644 index 000000000000..d6802b7146ca --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/basic.js @@ -0,0 +1,34 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.add +description: Basic behavior +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const duration1 = Temporal.Duration.from({ days: 1, minutes: 5 }); +TemporalHelpers.assertDuration(duration1.add({ days: 2, minutes: 5 }), + 0, 0, 0, 3, 0, 10, 0, 0, 0, 0, "positive same units"); +TemporalHelpers.assertDuration(duration1.add({ hours: 12, seconds: 30 }), + 0, 0, 0, 1, 12, 5, 30, 0, 0, 0, "positive different units"); +TemporalHelpers.assertDuration(Temporal.Duration.from("P3DT10M").add({ days: -2, minutes: -5 }), + 0, 0, 0, 1, 0, 5, 0, 0, 0, 0, "negative same units"); +TemporalHelpers.assertDuration(Temporal.Duration.from("P1DT12H5M30S").add({ hours: -12, seconds: -30 }), + 0, 0, 0, 1, 0, 5, 0, 0, 0, 0, "negative different units"); +const duration2 = Temporal.Duration.from("P50DT50H50M50.500500500S"); +TemporalHelpers.assertDuration(duration2.add(duration2), + 0, 0, 0, 104, 5, 41, 41, 1, 1, 0, "balancing positive"); +const duration3 = Temporal.Duration.from({ hours: -1, seconds: -60 }); +TemporalHelpers.assertDuration(duration3.add({ minutes: 122 }), + 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, "balancing flipped sign 1"); +const duration4 = Temporal.Duration.from({ hours: -1, seconds: -3721 }); +TemporalHelpers.assertDuration(duration4.add({ minutes: 61, nanoseconds: 3722000000001 }), + 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, "balancing flipped sign 2"); +TemporalHelpers.assertDuration(duration1.add({ month: 1, days: 1 }), + 0, 0, 0, 2, 0, 5, 0, 0, 0, 0, + "incorrectly-spelled properties are ignored"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/options-undefined.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/options-undefined.js index bba8cdc04a34..a7c8517ffffa 100644 --- a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/options-undefined.js +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/options-undefined.js @@ -5,12 +5,31 @@ /*--- esid: sec-temporal.duration.prototype.add description: Verify that undefined options are handled correctly. +includes: [temporalHelpers.js] features: [Temporal] ---*/ const duration1 = new Temporal.Duration(1); const duration2 = new Temporal.Duration(0, 12); -assert.throws(RangeError, () => duration1.add(duration2), "default relativeTo is undefined"); -assert.throws(RangeError, () => duration1.add(duration2, undefined), "default relativeTo is undefined"); +const duration3 = new Temporal.Duration(0, 0, 0, 1); +const duration4 = new Temporal.Duration(0, 0, 0, 0, 24); + +assert.throws(RangeError, () => duration1.add(duration2), "no options with years"); +TemporalHelpers.assertDuration(duration3.add(duration4), + 0, 0, 0, /* days = */ 2, 0, 0, 0, 0, 0, 0, + "no options with days"); + +const optionValues = [ + [undefined, "undefined"], + [{}, "plain object"], + [() => {}, "lambda"], +]; +for (const [options, description] of optionValues) { + assert.throws(RangeError, () => duration1.add(duration2, options), + `options ${description} with years`); + TemporalHelpers.assertDuration(duration3.add(duration4, options), + 0, 0, 0, /* days = */ 2, 0, 0, 0, 0, 0, 0, + `options ${description} with days`); +} reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/options-wrong-type.js new file mode 100644 index 000000000000..0be8538fd456 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.add +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.Duration(0, 0, 0, 0, 1); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.add({ hours: 1 }, value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/relativeto-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/relativeto-leap-second.js new file mode 100644 index 000000000000..d6602384e0c3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/relativeto-leap-second.js @@ -0,0 +1,46 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.add +description: Leap second is constrained in both an ISO string and a property bag +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Duration(1, 0, 0, 1); + +let relativeTo = "2016-12-31T23:59:60"; +const result1 = instance.add(new Temporal.Duration(0, 0, 0, 0, -24), { relativeTo }); +TemporalHelpers.assertDuration( + result1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "leap second is a valid ISO string for PlainDate relativeTo" +); + +relativeTo = "2016-12-31T23:59:60+00:00[UTC]"; +const result2 = instance.add(new Temporal.Duration(0, 0, 0, 0, -24), { relativeTo }); +TemporalHelpers.assertDuration( + result2, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "leap second is a valid ISO string for ZonedDateTime relativeTo" +); + +relativeTo = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result3 = instance.add(new Temporal.Duration(0, 0, 0, 0, -24), { relativeTo }); +TemporalHelpers.assertDuration( + result3, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "second: 60 is valid in a property bag for PlainDate relativeTo" +); + +relativeTo = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60, timeZone: "UTC" }; +const result4 = instance.add(new Temporal.Duration(0, 0, 0, 0, -24), { relativeTo }); +TemporalHelpers.assertDuration( + result4, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "second: 60 is valid in a property bag for ZonedDateTime relativeTo" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/relativeto-month.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/relativeto-month.js new file mode 100644 index 000000000000..fc4b609848b2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/relativeto-month.js @@ -0,0 +1,21 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.add +description: relativeTo with months. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const oneMonth = new Temporal.Duration(0, 1); +const days30 = new Temporal.Duration(0, 0, 0, 30); +TemporalHelpers.assertDuration(oneMonth.add(days30, { relativeTo: Temporal.PlainDate.from('2018-01-01') }), + 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, "January"); +TemporalHelpers.assertDuration(oneMonth.add(days30, { relativeTo: Temporal.PlainDate.from('2018-02-01') }), + 0, 1, 0, 30, 0, 0, 0, 0, 0, 0, "February"); +TemporalHelpers.assertDuration(oneMonth.add(days30, { relativeTo: Temporal.PlainDate.from('2018-03-01') }), + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, "March"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/relativeto-number.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/relativeto-number.js new file mode 100644 index 000000000000..45e87cfce756 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/relativeto-number.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.add +description: A number as relativeTo option is converted to a string, then to Temporal.PlainDate +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Duration(1, 0, 0, 1); + +const relativeTo = 20191101; + +const result = instance.add(new Temporal.Duration(0, 0, 0, 0, -24), { relativeTo }); +TemporalHelpers.assertDuration(result, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "20191101 is a valid ISO string for relativeTo"); + +const numbers = [ + 1, + -20191101, + 1234567890, +]; + +for (const relativeTo of numbers) { + assert.throws( + RangeError, + () => instance.add(new Temporal.Duration(0, 0, 0, 0, -24), { relativeTo }), + `Number ${relativeTo} does not convert to a valid ISO string for relativeTo` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/relativeto-order.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/relativeto-order.js new file mode 100644 index 000000000000..cffd653efc25 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/relativeto-order.js @@ -0,0 +1,19 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.add +description: relativeTo with years. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const d1 = new Temporal.Duration(0, 1, 0, 0); +const d2 = new Temporal.Duration(0, 0, 0, 30); +const relativeTo = new Temporal.PlainDate(2000, 1, 1); +TemporalHelpers.assertDuration(d1.add(d2, { relativeTo }), + 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, + "first this is resolved against relativeTo, then the argument against relativeTo + this"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-calendar-number.js new file mode 100644 index 000000000000..95ee3717eef1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-calendar-number.js @@ -0,0 +1,45 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.add +description: A number as calendar in relativeTo property bag is converted to a string, then to a calendar +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Duration(1, 0, 0, 1); + +const calendar = 19970327; + +let relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; +const result1 = instance.add(new Temporal.Duration(0, 0, 0, 0, -24), { relativeTo }); +TemporalHelpers.assertDuration(result1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for relativeTo.calendar"); + +relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; +const result2 = instance.add(new Temporal.Duration(0, 0, 0, 0, -24), { relativeTo }); +TemporalHelpers.assertDuration(result2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for relativeTo.calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws( + RangeError, + () => instance.add(new Temporal.Duration(0, 0, 0, 0, -24), { relativeTo }), + `Number ${calendar} does not convert to a valid ISO string for relativeTo.calendar` + ); + relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.add(new Temporal.Duration(0, 0, 0, 0, -24), { relativeTo }), + `Number ${calendar} does not convert to a valid ISO string for relativeTo.calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..e5c36e0c50e3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-calendar-wrong-type.js @@ -0,0 +1,52 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.add +description: > + Appropriate error thrown when relativeTo.calendar cannot be converted to a + calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.Duration(1, 0, 0, 1); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.add(new Temporal.Duration(0, 0, 0, 0, -24), { relativeTo }), `${description} does not convert to a valid ISO string`); + + relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.add(new Temporal.Duration(0, 0, 0, 0, -24), { relativeTo }), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], + [Temporal.ZonedDateTime, "Temporal.ZonedDateTime, object"], + [Temporal.ZonedDateTime.prototype, "Temporal.ZonedDateTime.prototype, object"], +]; + +for (const [calendar, description] of typeErrorTests) { + let relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.add(new Temporal.Duration(0, 0, 0, 0, -24), { relativeTo }), `${description} is not a valid property bag and does not convert to a string`); + + relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.add(new Temporal.Duration(0, 0, 0, 0, -24), { relativeTo }), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.add(new Temporal.Duration(0, 0, 0, 0, -24), { relativeTo }), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/relativeto-required.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/relativeto-required.js new file mode 100644 index 000000000000..cea3361ca533 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/relativeto-required.js @@ -0,0 +1,36 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.add +description: relativeTo is required if the largest unit is at least weeks. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const d = Temporal.Duration.from({ hours: 1 }); +const dy = Temporal.Duration.from({ years: 1 }); +const dm = Temporal.Duration.from({ months: 1 }); +const dw = Temporal.Duration.from({ weeks: 1 }); +assert.throws(RangeError, () => d.add(dy)); +assert.throws(RangeError, () => d.add(dm)); +assert.throws(RangeError, () => d.add(dw)); +assert.throws(RangeError, () => dy.add(d)); +assert.throws(RangeError, () => dm.add(d)); +assert.throws(RangeError, () => dw.add(d)); +const relativeTo = Temporal.PlainDate.from("2000-01-01"); +TemporalHelpers.assertDuration(d.add(dy, { relativeTo }), + 1, 0, 0, 0, 1, 0, 0, 0, 0, 0); +TemporalHelpers.assertDuration(d.add(dm, { relativeTo }), + 0, 1, 0, 0, 1, 0, 0, 0, 0, 0); +TemporalHelpers.assertDuration(d.add(dw, { relativeTo }), + 0, 0, 1, 0, 1, 0, 0, 0, 0, 0); +TemporalHelpers.assertDuration(dy.add(d, { relativeTo }), + 1, 0, 0, 0, 1, 0, 0, 0, 0, 0); +TemporalHelpers.assertDuration(dm.add(d, { relativeTo }), + 0, 1, 0, 0, 1, 0, 0, 0, 0, 0); +TemporalHelpers.assertDuration(dw.add(d, { relativeTo }), + 0, 0, 1, 0, 1, 0, 0, 0, 0, 0); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/relativeto-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/relativeto-wrong-type.js new file mode 100644 index 000000000000..e65cd25c40d6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/relativeto-wrong-type.js @@ -0,0 +1,42 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.add +description: > + Appropriate error thrown when relativeTo cannot be converted to a valid + relativeTo string or property bag +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.Duration(1, 0, 0, 1); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [relativeTo, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.add(new Temporal.Duration(0, 0, 0, 0, -24), { relativeTo }), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], + [Temporal.ZonedDateTime, "Temporal.ZonedDateTime, object"], + [Temporal.ZonedDateTime.prototype, "Temporal.ZonedDateTime.prototype, object"], +]; + +for (const [relativeTo, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.add(new Temporal.Duration(0, 0, 0, 0, -24), { relativeTo }), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/relativeto-year.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/relativeto-year.js new file mode 100644 index 000000000000..1556a07d00d4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/relativeto-year.js @@ -0,0 +1,19 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.add +description: relativeTo with years. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const oneYear = new Temporal.Duration(1); +const days365 = new Temporal.Duration(0, 0, 0, 365); +TemporalHelpers.assertDuration(oneYear.add(days365, { relativeTo: Temporal.PlainDate.from("2016-01-01") }), + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, "non-leap year"); +TemporalHelpers.assertDuration(oneYear.add(days365, { relativeTo: Temporal.PlainDate.from("2015-01-01") }), + 1, 11, 0, 30, 0, 0, 0, 0, 0, 0, "leap year"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/timezone-string-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/timezone-string-leap-second.js new file mode 100644 index 000000000000..767929548fde --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/timezone-string-leap-second.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.add +description: Leap second is a valid ISO string for TimeZone +features: [Temporal] +---*/ + +const instance = new Temporal.Duration(1); +let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; + +// A string with a leap second is a valid ISO string, so the following two +// operations should not throw + +instance.add(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }); +instance.add(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }); + +timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; +assert.throws(RangeError, () => instance.add(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), "leap second in time zone name not valid"); +assert.throws(RangeError, () => instance.add(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), "leap second in time zone name not valid (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/timezone-string-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/timezone-string-year-zero.js new file mode 100644 index 000000000000..e824f6ff3bd3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/timezone-string-year-zero.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.add +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.Duration(1); +invalidStrings.forEach((timeZone) => { + assert.throws( + RangeError, + () => instance.add(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), + "reject minus zero as extended year" + ); + assert.throws( + RangeError, + () => instance.add(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), + "reject minus zero as extended year (nested property)" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/timezone-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/timezone-wrong-type.js new file mode 100644 index 000000000000..dc93e84bf72a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/add/timezone-wrong-type.js @@ -0,0 +1,41 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.add +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for TimeZone +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.Duration(1); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], +]; + +for (const [timeZone, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.add(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), `${description} does not convert to a valid ISO string`); + assert.throws(RangeError, () => instance.add(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [timeZone, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.add(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), `${description} is not a valid object and does not convert to a string`); + assert.throws(TypeError, () => instance.add(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), `${description} is not a valid object and does not convert to a string (nested property)`); +} + +const timeZone = undefined; +assert.throws(RangeError, () => instance.add(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), `undefined is always a RangeError as nested property`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/blank/basic.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/blank/basic.js new file mode 100644 index 000000000000..6c4c1c49c781 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/blank/basic.js @@ -0,0 +1,28 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-get-temporal.duration.prototype.blank +description: Basic tests for blank. +features: [Temporal] +---*/ + +assert.sameValue(Temporal.Duration.from("P3DT1H").blank, false); +assert.sameValue(Temporal.Duration.from("-PT2H20M30S").blank, false); +assert.sameValue(Temporal.Duration.from("PT0S").blank, true); +const zero = Temporal.Duration.from({ + years: 0, + months: 0, + weeks: 0, + days: 0, + hours: 0, + minutes: 0, + seconds: 0, + milliseconds: 0, + microseconds: 0, + nanoseconds: 0 +}); +assert.sameValue(zero.blank, true); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/largestunit-smallestunit-default.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/largestunit-smallestunit-default.js new file mode 100644 index 000000000000..9ee8a5456f67 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/largestunit-smallestunit-default.js @@ -0,0 +1,41 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.round +description: assumes a different default for largestUnit if smallestUnit is larger than the default +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const relativeTo = Temporal.PlainDate.from("2020-01-01"); +const almostYear = Temporal.Duration.from({ days: 364 }); +TemporalHelpers.assertDuration(almostYear.round({ smallestUnit: "years", relativeTo }), + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "years"); +const almostMonth = Temporal.Duration.from({ days: 27 }); +TemporalHelpers.assertDuration(almostMonth.round({ smallestUnit: "months", relativeTo }), + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "months"); +const almostWeek = Temporal.Duration.from({ days: 6 }); +TemporalHelpers.assertDuration(almostWeek.round({ smallestUnit: "weeks", relativeTo }), + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "weeks"); +const almostDay = Temporal.Duration.from({ seconds: 86399 }); +TemporalHelpers.assertDuration(almostDay.round({ smallestUnit: "days" }), + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "days"); +const almostHour = Temporal.Duration.from({ seconds: 3599 }); +TemporalHelpers.assertDuration(almostHour.round({ smallestUnit: "hours" }), + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "hours"); +const almostMinute = Temporal.Duration.from({ seconds: 59 }); +TemporalHelpers.assertDuration(almostMinute.round({ smallestUnit: "minutes" }), + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "minutes"); +const almostSecond = Temporal.Duration.from({ nanoseconds: 999999999 }); +TemporalHelpers.assertDuration(almostSecond.round({ smallestUnit: "seconds" }), + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "seconds"); +const almostMillisecond = Temporal.Duration.from({ nanoseconds: 999999 }); +TemporalHelpers.assertDuration(almostMillisecond.round({ smallestUnit: "milliseconds" }), + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "milliseconds"); +const almostMicrosecond = Temporal.Duration.from({ nanoseconds: 999 }); +TemporalHelpers.assertDuration(almostMicrosecond.round({ smallestUnit: "microseconds" }), + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "microseconds"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/largestunit-smallestunit-mismatch.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/largestunit-smallestunit-mismatch.js new file mode 100644 index 000000000000..b5d3eca51dee --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/largestunit-smallestunit-mismatch.js @@ -0,0 +1,23 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.round +description: RangeError thrown when smallestUnit is larger than largestUnit +features: [Temporal] +---*/ + +const d = new Temporal.Duration(5, 5, 5, 5, 5, 5, 5, 5, 5, 5); +const relativeTo = Temporal.PlainDate.from('2020-01-01'); +const units = ["years", "months", "weeks", "days", "hours", "minutes", "seconds", "milliseconds", "microseconds", "nanoseconds"]; +for (let largestIdx = 1; largestIdx < units.length; largestIdx++) { + for (let smallestIdx = 0; smallestIdx < largestIdx; smallestIdx++) { + const largestUnit = units[largestIdx]; + const smallestUnit = units[smallestIdx]; + assert.throws(RangeError, () => d.round({ largestUnit, smallestUnit, relativeTo }), + `${smallestUnit} > ${largestUnit}`); + } +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/options-wrong-type.js new file mode 100644 index 000000000000..561e227d7e76 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/options-wrong-type.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.round +description: TypeError thrown when options argument is missing or a non-string primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + undefined, + null, + true, + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.Duration(0, 0, 0, 0, 1); +assert.throws(TypeError, () => instance.round(), "TypeError on missing options argument"); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.round(value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/relativeto-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/relativeto-leap-second.js new file mode 100644 index 000000000000..dc78f1117f06 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/relativeto-leap-second.js @@ -0,0 +1,46 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.round +description: Leap second is constrained in both an ISO string and a property bag +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Duration(1, 0, 0, 0, 24); + +let relativeTo = "2016-12-31T23:59:60"; +const result1 = instance.round({ largestUnit: "years", relativeTo }); +TemporalHelpers.assertDuration( + result1, + 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, + "leap second is a valid ISO string for PlainDate relativeTo" +); + +relativeTo = "2016-12-31T23:59:60+00:00[UTC]"; +const result2 = instance.round({ largestUnit: "years", relativeTo }); +TemporalHelpers.assertDuration( + result2, + 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, + "leap second is a valid ISO string for ZonedDateTime relativeTo" +); + +relativeTo = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result3 = instance.round({ largestUnit: "years", relativeTo }); +TemporalHelpers.assertDuration( + result3, + 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, + "second: 60 is valid in a property bag for PlainDate relativeTo" +); + +relativeTo = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60, timeZone: "UTC" }; +const result4 = instance.round({ largestUnit: "years", relativeTo }); +TemporalHelpers.assertDuration( + result4, + 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, + "second: 60 is valid in a property bag for ZonedDateTime relativeTo" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/relativeto-number.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/relativeto-number.js new file mode 100644 index 000000000000..a4f913d2228c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/relativeto-number.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.round +description: A number as relativeTo option is converted to a string, then to Temporal.PlainDate +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Duration(1, 0, 0, 0, 24); + +const relativeTo = 20191101; + +const result = instance.round({ largestUnit: "years", relativeTo }); +TemporalHelpers.assertDuration(result, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, "20191101 is a valid ISO string for relativeTo"); + +const numbers = [ + 1, + -20191101, + 1234567890, +]; + +for (const relativeTo of numbers) { + assert.throws( + RangeError, + () => instance.round({ largestUnit: "years", relativeTo }), + `Number ${relativeTo} does not convert to a valid ISO string for relativeTo` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-calendar-number.js new file mode 100644 index 000000000000..8a343976e7db --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-calendar-number.js @@ -0,0 +1,45 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.round +description: A number as calendar in relativeTo property bag is converted to a string, then to a calendar +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Duration(1, 0, 0, 0, 24); + +const calendar = 19970327; + +let relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; +const result1 = instance.round({ largestUnit: "years", relativeTo }); +TemporalHelpers.assertDuration(result1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for relativeTo.calendar"); + +relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; +const result2 = instance.round({ largestUnit: "years", relativeTo }); +TemporalHelpers.assertDuration(result2, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for relativeTo.calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws( + RangeError, + () => instance.round({ largestUnit: "years", relativeTo }), + `Number ${calendar} does not convert to a valid ISO string for relativeTo.calendar` + ); + relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.round({ largestUnit: "years", relativeTo }), + `Number ${calendar} does not convert to a valid ISO string for relativeTo.calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..d7b4b23526fc --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-calendar-wrong-type.js @@ -0,0 +1,52 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.round +description: > + Appropriate error thrown when relativeTo.calendar cannot be converted to a + calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.Duration(1, 0, 0, 0, 24); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.round({ largestUnit: "years", relativeTo }), `${description} does not convert to a valid ISO string`); + + relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.round({ largestUnit: "years", relativeTo }), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], + [Temporal.ZonedDateTime, "Temporal.ZonedDateTime, object"], + [Temporal.ZonedDateTime.prototype, "Temporal.ZonedDateTime.prototype, object"], +]; + +for (const [calendar, description] of typeErrorTests) { + let relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.round({ largestUnit: "years", relativeTo }), `${description} is not a valid property bag and does not convert to a string`); + + relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.round({ largestUnit: "years", relativeTo }), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.round({ largestUnit: "years", relativeTo }), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/relativeto-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/relativeto-wrong-type.js new file mode 100644 index 000000000000..fdf975ab64da --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/relativeto-wrong-type.js @@ -0,0 +1,42 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.round +description: > + Appropriate error thrown when relativeTo cannot be converted to a valid + relativeTo string or property bag +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.Duration(1, 0, 0, 0, 24); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [relativeTo, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.round({ largestUnit: "years", relativeTo }), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], + [Temporal.ZonedDateTime, "Temporal.ZonedDateTime, object"], + [Temporal.ZonedDateTime.prototype, "Temporal.ZonedDateTime.prototype, object"], +]; + +for (const [relativeTo, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.round({ largestUnit: "years", relativeTo }), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/roundto-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/roundto-invalid-string.js new file mode 100644 index 000000000000..cb0872125462 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/roundto-invalid-string.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.round +description: RangeError thrown when smallestUnit option not one of the allowed string values +features: [Temporal] +---*/ + +const duration = new Temporal.Duration(0, 0, 0, 0, 12, 34, 56, 123, 987, 500); +const badValues = [ + "era", + "eraYear", + "millisecond\0", + "mill\u0131second", + "SECOND", + "eras", + "eraYears", + "milliseconds\0", + "mill\u0131seconds", + "SECONDS", + "other string", +]; +for (const smallestUnit of badValues) { + assert.throws(RangeError, () => duration.round(smallestUnit), + `"${smallestUnit}" is not a valid value for smallest unit`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/smallestunit-disallowed-units-string.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/smallestunit-disallowed-units-string.js deleted file mode 100644 index f21cdb197dca..000000000000 --- a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/smallestunit-disallowed-units-string.js +++ /dev/null @@ -1,29 +0,0 @@ -// |reftest| skip -- Temporal is not supported -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.duration.prototype.round -description: Specifically disallowed units for the smallestUnit option -features: [Temporal, arrow-function] ----*/ - -const instance = new Temporal.Duration(0, 0, 0, 4, 5, 6, 7, 987, 654, 321); -const invalidUnits = [ - "era", - "eras", -]; -invalidUnits.forEach((smallestUnit) => { - assert.throws( - RangeError, - () => instance.round({ smallestUnit }), - `{ smallestUnit: "${smallestUnit}" } should not be allowed as an argument to round` - ); - assert.throws( - RangeError, - () => instance.round(smallestUnit), - `"${smallestUnit}" should not be allowed as an argument to round` - ); -}); - -reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/smallestunit-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/smallestunit-invalid-string.js index 1d3b92277481..6400b3546d8b 100644 --- a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/smallestunit-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/smallestunit-invalid-string.js @@ -9,6 +9,22 @@ features: [Temporal] ---*/ const duration = new Temporal.Duration(0, 0, 0, 0, 12, 34, 56, 123, 987, 500); -assert.throws(RangeError, () => duration.round({ smallestUnit: "other string" })); +const badValues = [ + "era", + "eraYear", + "millisecond\0", + "mill\u0131second", + "SECOND", + "eras", + "eraYears", + "milliseconds\0", + "mill\u0131seconds", + "SECONDS", + "other string", +]; +for (const smallestUnit of badValues) { + assert.throws(RangeError, () => duration.round({ smallestUnit }), + `"${smallestUnit}" is not a valid value for smallest unit`); +} reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/smallestunit.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/smallestunit.js new file mode 100644 index 000000000000..413237571ede --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/smallestunit.js @@ -0,0 +1,37 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.round +description: smallestUnit should be taken into account +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const d = Temporal.Duration.from({ + days: 1, + hours: 2, + minutes: 3, + seconds: 4, + milliseconds: 5, + microseconds: 6, + nanoseconds: 7 +}); +const tests = { + 'day': [0, 0, 0, 1, 0, 0, 0, 0, 0, 0], + 'hour': [0, 0, 0, 1, 2, 0, 0, 0, 0, 0], + 'minute': [0, 0, 0, 1, 2, 3, 0, 0, 0, 0], + 'second': [0, 0, 0, 1, 2, 3, 4, 0, 0, 0], + 'millisecond': [0, 0, 0, 1, 2, 3, 4, 5, 0, 0], + 'microsecond': [0, 0, 0, 1, 2, 3, 4, 5, 6, 0], + 'nanosecond': [0, 0, 0, 1, 2, 3, 4, 5, 6, 7], +}; +for (const [smallestUnit, expected] of Object.entries(tests)) { + TemporalHelpers.assertDuration(d.round(smallestUnit), ...expected, + `"${smallestUnit}" should work as argument`); + TemporalHelpers.assertDuration(d.round({ smallestUnit }), ...expected, + `"${smallestUnit}" should work in option bag`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/timezone-string-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/timezone-string-leap-second.js new file mode 100644 index 000000000000..ab8265731f52 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/timezone-string-leap-second.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.round +description: Leap second is a valid ISO string for TimeZone +features: [Temporal] +---*/ + +const instance = new Temporal.Duration(1); +let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; + +// A string with a leap second is a valid ISO string, so the following two +// operations should not throw + +instance.round({ largestUnit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone } }); +instance.round({ largestUnit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }); + +timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; +assert.throws(RangeError, () => instance.round({ largestUnit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), "leap second in time zone name not valid"); +assert.throws(RangeError, () => instance.round({ largestUnit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), "leap second in time zone name not valid (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/timezone-string-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/timezone-string-year-zero.js new file mode 100644 index 000000000000..0ae795e75fa0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/timezone-string-year-zero.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.round +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.Duration(1); +invalidStrings.forEach((timeZone) => { + assert.throws( + RangeError, + () => instance.round({ largestUnit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), + "reject minus zero as extended year" + ); + assert.throws( + RangeError, + () => instance.round({ largestUnit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), + "reject minus zero as extended year (nested property)" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/timezone-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/timezone-wrong-type.js new file mode 100644 index 000000000000..9e0725e3e224 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/round/timezone-wrong-type.js @@ -0,0 +1,41 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.round +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for TimeZone +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.Duration(1); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], +]; + +for (const [timeZone, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.round({ largestUnit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), `${description} does not convert to a valid ISO string`); + assert.throws(RangeError, () => instance.round({ largestUnit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [timeZone, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.round({ largestUnit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), `${description} is not a valid object and does not convert to a string`); + assert.throws(TypeError, () => instance.round({ largestUnit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), `${description} is not a valid object and does not convert to a string (nested property)`); +} + +const timeZone = undefined; +assert.throws(RangeError, () => instance.round({ largestUnit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), `undefined is always a RangeError as nested property`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/argument-object-invalid.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/argument-object-invalid.js new file mode 100644 index 000000000000..324033e843c5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/argument-object-invalid.js @@ -0,0 +1,16 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.subtract +description: Mixed positive and negative values or missing properties always throw +features: [Temporal] +---*/ + +const duration = Temporal.Duration.from({ days: 1, minutes: 5 }); +assert.throws(RangeError, () => duration.subtract({ hours: 1, minutes: -30 }), "mixed signs"); +assert.throws(TypeError, () => duration.subtract({}), "no properties"); +assert.throws(TypeError, () => duration.subtract({ month: 12 }), "only singular 'month' property"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/argument-string.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/argument-string.js new file mode 100644 index 000000000000..4d0037afbb1e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/argument-string.js @@ -0,0 +1,17 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.subtract +description: String arguments are supported. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const duration = Temporal.Duration.from({ days: 3, hours: 1, minutes: 10 }); +const result = duration.subtract('P1DT5M'); +TemporalHelpers.assertDuration(result, 0, 0, 0, 2, 1, 5, 0, 0, 0, 0, "String argument should be supported"); +assert.throws(RangeError, () => duration.subtract("2DT5M"), "Invalid string argument should throw"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/basic.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/basic.js new file mode 100644 index 000000000000..4cdd1a3f6edc --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/basic.js @@ -0,0 +1,69 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.subtract +description: Basic behavior +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const duration = Temporal.Duration.from({ days: 3, hours: 1, minutes: 10 }); +TemporalHelpers.assertDuration(duration.subtract({ days: 1, minutes: 5 }), + 0, 0, 0, 2, 1, 5, 0, 0, 0, 0); +TemporalHelpers.assertDuration(duration.subtract(duration), + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); +TemporalHelpers.assertDuration(duration.subtract({ days: 3 }), + 0, 0, 0, 0, 1, 10, 0, 0, 0, 0); +TemporalHelpers.assertDuration(duration.subtract({ minutes: 10 }), + 0, 0, 0, 3, 1, 0, 0, 0, 0, 0); +TemporalHelpers.assertDuration(duration.subtract({ minutes: 15 }), + 0, 0, 0, 3, 0, 55, 0, 0, 0, 0); +TemporalHelpers.assertDuration(duration.subtract({ seconds: 30 }), + 0, 0, 0, 3, 1, 9, 30, 0, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('P2DT1H5M').subtract({ days: -1, minutes: -5 }), + 0, 0, 0, 3, 1, 10, 0, 0, 0, 0); +TemporalHelpers.assertDuration(new Temporal.Duration().subtract({ days: -3, hours: -1, minutes: -10 }), + 0, 0, 0, 3, 1, 10, 0, 0, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('PT1H10M').subtract({ days: -3 }), + 0, 0, 0, 3, 1, 10, 0, 0, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('P3DT1H').subtract({ minutes: -10 }), + 0, 0, 0, 3, 1, 10, 0, 0, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('P3DT55M').subtract({ minutes: -15 }), + 0, 0, 0, 3, 1, 10, 0, 0, 0, 0); +TemporalHelpers.assertDuration(Temporal.Duration.from('P3DT1H9M30S').subtract({ seconds: -30 }), + 0, 0, 0, 3, 1, 10, 0, 0, 0, 0); +const d = Temporal.Duration.from({ + minutes: 100, + seconds: 100, + milliseconds: 2000, + microseconds: 2000, + nanoseconds: 2000 +}); +const less = Temporal.Duration.from({ + minutes: 10, + seconds: 10, + milliseconds: 500, + microseconds: 500, + nanoseconds: 500 +}); +TemporalHelpers.assertDuration(d.subtract(less), + 0, 0, 0, 0, 0, 91, 31, 501, 501, 500); +const tenDays = Temporal.Duration.from('P10D'); +const tenMinutes = Temporal.Duration.from('PT10M'); +TemporalHelpers.assertDuration(tenDays.subtract({ days: 15 }), + 0, 0, 0, -5, 0, 0, 0, 0, 0, 0); +TemporalHelpers.assertDuration(tenMinutes.subtract({ minutes: 15 }), + 0, 0, 0, 0, 0, -5, 0, 0, 0, 0); +const d1 = Temporal.Duration.from({ hours: 1, seconds: 60 }); +TemporalHelpers.assertDuration(d1.subtract({ minutes: 122 }), + 0, 0, 0, 0, -1, -1, 0, 0, 0, 0); +const d2 = Temporal.Duration.from({ hours: 1, seconds: 3721 }); +TemporalHelpers.assertDuration(d2.subtract({ minutes: 61, nanoseconds: 3722000000001 }), + 0, 0, 0, 0, 0, -1, -1, 0, 0, -1); +TemporalHelpers.assertDuration(duration.subtract({ month: 1, days: 1 }), + 0, 0, 0, 2, 1, 10, 0, 0, 0, 0, + "incorrectly-spelled properties are ignored"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/options-undefined.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/options-undefined.js index f64b107c751c..6fe398c162bd 100644 --- a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/options-undefined.js +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/options-undefined.js @@ -5,12 +5,31 @@ /*--- esid: sec-temporal.duration.prototype.subtract description: Verify that undefined options are handled correctly. +includes: [temporalHelpers.js] features: [Temporal] ---*/ const duration1 = new Temporal.Duration(1); -const duration2 = new Temporal.Duration(0, 12); -assert.throws(RangeError, () => duration1.subtract(duration2), "default relativeTo is undefined"); -assert.throws(RangeError, () => duration1.subtract(duration2, undefined), "default relativeTo is undefined"); +const duration2 = new Temporal.Duration(0, 24); +const duration3 = new Temporal.Duration(0, 0, 0, 1); +const duration4 = new Temporal.Duration(0, 0, 0, 0, 48); + +assert.throws(RangeError, () => duration1.subtract(duration2), "no options with years"); +TemporalHelpers.assertDuration(duration3.subtract(duration4), + 0, 0, 0, /* days = */ -1, 0, 0, 0, 0, 0, 0, + "no options with days"); + +const optionValues = [ + [undefined, "undefined"], + [{}, "plain object"], + [() => {}, "lambda"], +]; +for (const [options, description] of optionValues) { + assert.throws(RangeError, () => duration1.subtract(duration2, options), + `options ${description} with years`); + TemporalHelpers.assertDuration(duration3.subtract(duration4, options), + 0, 0, 0, /* days = */ -1, 0, 0, 0, 0, 0, 0, + `options ${description} with days`); +} reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/options-wrong-type.js new file mode 100644 index 000000000000..32458fa7cba6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.subtract +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.Duration(0, 0, 0, 0, 1); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.subtract({ hours: 1 }, value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/relativeto-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/relativeto-leap-second.js new file mode 100644 index 000000000000..f9094d7c38c8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/relativeto-leap-second.js @@ -0,0 +1,46 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.subtract +description: Leap second is constrained in both an ISO string and a property bag +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Duration(1, 0, 0, 1); + +let relativeTo = "2016-12-31T23:59:60"; +const result1 = instance.subtract(new Temporal.Duration(0, 0, 0, 0, 24), { relativeTo }); +TemporalHelpers.assertDuration( + result1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "leap second is a valid ISO string for PlainDate relativeTo" +); + +relativeTo = "2016-12-31T23:59:60+00:00[UTC]"; +const result2 = instance.subtract(new Temporal.Duration(0, 0, 0, 0, 24), { relativeTo }); +TemporalHelpers.assertDuration( + result2, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "leap second is a valid ISO string for ZonedDateTime relativeTo" +); + +relativeTo = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result3 = instance.subtract(new Temporal.Duration(0, 0, 0, 0, 24), { relativeTo }); +TemporalHelpers.assertDuration( + result3, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "second: 60 is valid in a property bag for PlainDate relativeTo" +); + +relativeTo = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60, timeZone: "UTC" }; +const result4 = instance.subtract(new Temporal.Duration(0, 0, 0, 0, 24), { relativeTo }); +TemporalHelpers.assertDuration( + result4, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "second: 60 is valid in a property bag for ZonedDateTime relativeTo" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/relativeto-month.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/relativeto-month.js new file mode 100644 index 000000000000..0f2059570615 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/relativeto-month.js @@ -0,0 +1,21 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.subtract +description: relativeTo with months. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const oneMonth = new Temporal.Duration(0, 1); +const days30 = new Temporal.Duration(0, 0, 0, 30); +TemporalHelpers.assertDuration(oneMonth.subtract(days30, { relativeTo: Temporal.PlainDate.from('2018-02-01') }), + 0, 0, 0, -2, 0, 0, 0, 0, 0, 0, "February"); +TemporalHelpers.assertDuration(oneMonth.subtract(days30, { relativeTo: Temporal.PlainDate.from('2018-03-01') }), + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "March"); +TemporalHelpers.assertDuration(oneMonth.subtract(days30, { relativeTo: Temporal.PlainDate.from('2018-04-01') }), + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "April"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/relativeto-number.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/relativeto-number.js new file mode 100644 index 000000000000..d9efa271e6cd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/relativeto-number.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.subtract +description: A number as relativeTo option is converted to a string, then to Temporal.PlainDate +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Duration(1, 0, 0, 1); + +const relativeTo = 20191101; + +const result = instance.subtract(new Temporal.Duration(0, 0, 0, 0, 24), { relativeTo }); +TemporalHelpers.assertDuration(result, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "20191101 is a valid ISO string for relativeTo"); + +const numbers = [ + 1, + -20191101, + 1234567890, +]; + +for (const relativeTo of numbers) { + assert.throws( + RangeError, + () => instance.subtract(new Temporal.Duration(0, 0, 0, 0, 24), { relativeTo }), + `Number ${relativeTo} does not convert to a valid ISO string for relativeTo` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/relativeto-order.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/relativeto-order.js new file mode 100644 index 000000000000..af57b1a1373d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/relativeto-order.js @@ -0,0 +1,19 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.subtract +description: relativeTo with years. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const d1 = new Temporal.Duration(0, 2, 1, 4); +const d2 = new Temporal.Duration(0, 1, 1, 1); +const relativeTo = new Temporal.PlainDate(2000, 1, 1); +TemporalHelpers.assertDuration(d1.subtract(d2, { relativeTo }), + 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, + "first this is resolved against relativeTo, then the argument against relativeTo + this"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-calendar-number.js new file mode 100644 index 000000000000..c29d216c7c9a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-calendar-number.js @@ -0,0 +1,45 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.subtract +description: A number as calendar in relativeTo property bag is converted to a string, then to a calendar +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Duration(1, 0, 0, 1); + +const calendar = 19970327; + +let relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; +const result1 = instance.subtract(new Temporal.Duration(0, 0, 0, 0, 24), { relativeTo }); +TemporalHelpers.assertDuration(result1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for relativeTo.calendar"); + +relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; +const result2 = instance.subtract(new Temporal.Duration(0, 0, 0, 0, 24), { relativeTo }); +TemporalHelpers.assertDuration(result2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for relativeTo.calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws( + RangeError, + () => instance.subtract(new Temporal.Duration(0, 0, 0, 0, 24), { relativeTo }), + `Number ${calendar} does not convert to a valid ISO string for relativeTo.calendar` + ); + relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.subtract(new Temporal.Duration(0, 0, 0, 0, 24), { relativeTo }), + `Number ${calendar} does not convert to a valid ISO string for relativeTo.calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..cd527bc3c52f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-calendar-wrong-type.js @@ -0,0 +1,52 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.subtract +description: > + Appropriate error thrown when relativeTo.calendar cannot be converted to a + calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.Duration(1, 0, 0, 1); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.subtract(new Temporal.Duration(0, 0, 0, 0, 24), { relativeTo }), `${description} does not convert to a valid ISO string`); + + relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.subtract(new Temporal.Duration(0, 0, 0, 0, 24), { relativeTo }), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], + [Temporal.ZonedDateTime, "Temporal.ZonedDateTime, object"], + [Temporal.ZonedDateTime.prototype, "Temporal.ZonedDateTime.prototype, object"], +]; + +for (const [calendar, description] of typeErrorTests) { + let relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.subtract(new Temporal.Duration(0, 0, 0, 0, 24), { relativeTo }), `${description} is not a valid property bag and does not convert to a string`); + + relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.subtract(new Temporal.Duration(0, 0, 0, 0, 24), { relativeTo }), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.subtract(new Temporal.Duration(0, 0, 0, 0, 24), { relativeTo }), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/relativeto-required.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/relativeto-required.js new file mode 100644 index 000000000000..96aee23b340f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/relativeto-required.js @@ -0,0 +1,36 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.subtract +description: relativeTo is required if the largest unit is at least weeks. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const d = Temporal.Duration.from({ hours: 1 }); +const dy = Temporal.Duration.from({ years: 1, hours: 1 }); +const dm = Temporal.Duration.from({ months: 1, hours: 1 }); +const dw = Temporal.Duration.from({ weeks: 1, hours: 1 }); +assert.throws(RangeError, () => d.subtract(dy)); +assert.throws(RangeError, () => d.subtract(dm)); +assert.throws(RangeError, () => d.subtract(dw)); +assert.throws(RangeError, () => dy.subtract(d)); +assert.throws(RangeError, () => dm.subtract(d)); +assert.throws(RangeError, () => dw.subtract(d)); +const relativeTo = Temporal.PlainDate.from("2000-01-01"); +TemporalHelpers.assertDuration(d.subtract(dy, { relativeTo }), + -1, 0, 0, 0, 0, 0, 0, 0, 0, 0); +TemporalHelpers.assertDuration(d.subtract(dm, { relativeTo }), + 0, -1, 0, 0, 0, 0, 0, 0, 0, 0); +TemporalHelpers.assertDuration(d.subtract(dw, { relativeTo }), + 0, 0, -1, 0, 0, 0, 0, 0, 0, 0); +TemporalHelpers.assertDuration(dy.subtract(d, { relativeTo }), + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0); +TemporalHelpers.assertDuration(dm.subtract(d, { relativeTo }), + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0); +TemporalHelpers.assertDuration(dw.subtract(d, { relativeTo }), + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/relativeto-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/relativeto-wrong-type.js new file mode 100644 index 000000000000..a5fc02380966 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/relativeto-wrong-type.js @@ -0,0 +1,42 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.subtract +description: > + Appropriate error thrown when relativeTo cannot be converted to a valid + relativeTo string or property bag +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.Duration(1, 0, 0, 1); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [relativeTo, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.subtract(new Temporal.Duration(0, 0, 0, 0, 24), { relativeTo }), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], + [Temporal.ZonedDateTime, "Temporal.ZonedDateTime, object"], + [Temporal.ZonedDateTime.prototype, "Temporal.ZonedDateTime.prototype, object"], +]; + +for (const [relativeTo, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.subtract(new Temporal.Duration(0, 0, 0, 0, 24), { relativeTo }), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/relativeto-year.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/relativeto-year.js new file mode 100644 index 000000000000..dc170da19661 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/relativeto-year.js @@ -0,0 +1,19 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.subtract +description: relativeTo with years. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const oneYear = new Temporal.Duration(1); +const days365 = new Temporal.Duration(0, 0, 0, 365); +TemporalHelpers.assertDuration(oneYear.subtract(days365, { relativeTo: Temporal.PlainDate.from("2017-01-01") }), + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "non-leap year"); +TemporalHelpers.assertDuration(oneYear.subtract(days365, { relativeTo: Temporal.PlainDate.from("2016-01-01") }), + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "leap year"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/timezone-string-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/timezone-string-leap-second.js new file mode 100644 index 000000000000..cb3e0b86aae6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/timezone-string-leap-second.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.subtract +description: Leap second is a valid ISO string for TimeZone +features: [Temporal] +---*/ + +const instance = new Temporal.Duration(1); +let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; + +// A string with a leap second is a valid ISO string, so the following two +// operations should not throw + +instance.subtract(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }); +instance.subtract(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }); + +timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; +assert.throws(RangeError, () => instance.subtract(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), "leap second in time zone name not valid"); +assert.throws(RangeError, () => instance.subtract(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), "leap second in time zone name not valid (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/timezone-string-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/timezone-string-year-zero.js new file mode 100644 index 000000000000..5fffeeac319c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/timezone-string-year-zero.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.subtract +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.Duration(1); +invalidStrings.forEach((timeZone) => { + assert.throws( + RangeError, + () => instance.subtract(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), + "reject minus zero as extended year" + ); + assert.throws( + RangeError, + () => instance.subtract(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), + "reject minus zero as extended year (nested property)" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/timezone-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/timezone-wrong-type.js new file mode 100644 index 000000000000..1715b610cdb3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/subtract/timezone-wrong-type.js @@ -0,0 +1,41 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.subtract +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for TimeZone +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.Duration(1); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], +]; + +for (const [timeZone, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.subtract(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), `${description} does not convert to a valid ISO string`); + assert.throws(RangeError, () => instance.subtract(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [timeZone, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.subtract(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), `${description} is not a valid object and does not convert to a string`); + assert.throws(TypeError, () => instance.subtract(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), `${description} is not a valid object and does not convert to a string (nested property)`); +} + +const timeZone = undefined; +assert.throws(RangeError, () => instance.subtract(new Temporal.Duration(1), { relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), `undefined is always a RangeError as nested property`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toJSON/options.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toJSON/options.js new file mode 100644 index 000000000000..bf8775a05df9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toJSON/options.js @@ -0,0 +1,21 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.tojson +description: Temporal.Duration.prototype.toJSON does not support options, unlike toString. +features: [Temporal] +---*/ + +let called = 0; +const options = new Proxy({}, { + get() { + ++called; + } +}); +const d = new Temporal.Duration(1, 2); +assert.sameValue(d.toJSON(options), "P1Y2M"); +assert.sameValue(called, 0); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/fractionalseconddigits-auto.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/fractionalseconddigits-auto.js new file mode 100644 index 000000000000..f30df60fc290 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/fractionalseconddigits-auto.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.tostring +description: auto value for fractionalSecondDigits option +features: [Temporal] +---*/ + +const wholeSeconds = new Temporal.Duration(1, 2, 3, 4, 5, 6, 7); +const subSeconds = new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, 987, 650); + +const tests = [ + [wholeSeconds, "P1Y2M3W4DT5H6M7S"], + [subSeconds, "P1Y2M3W4DT5H6M7.98765S"], +]; + +for (const [duration, expected] of tests) { + assert.sameValue(duration.toString(), expected, "default is to emit seconds and drop trailing zeroes"); + assert.sameValue(duration.toString({ fractionalSecondDigits: "auto" }), expected, "auto is the default"); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/fractionalseconddigits-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/fractionalseconddigits-invalid-string.js index 5342d129871f..c2d1b2789ff3 100644 --- a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/fractionalseconddigits-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/fractionalseconddigits-invalid-string.js @@ -17,8 +17,9 @@ features: [Temporal] const duration = new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, 987, 650, 0); -for (const fractionalSecondDigits of ["other string", "AUTO", "not-auto", "autos"]) { - assert.throws(RangeError, () => duration.toString({ fractionalSecondDigits })); +for (const fractionalSecondDigits of ["other string", "AUTO", "not-auto", "autos", "auto\0"]) { + assert.throws(RangeError, () => duration.toString({ fractionalSecondDigits }), + `"${fractionalSecondDigits}" is not a valid value for fractionalSecondDigits`); } reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/fractionalseconddigits-number.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/fractionalseconddigits-number.js new file mode 100644 index 000000000000..96bdbcd6ca48 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/fractionalseconddigits-number.js @@ -0,0 +1,31 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.tostring +description: Number for fractionalSecondDigits option +features: [Temporal] +---*/ + +const wholeSeconds = new Temporal.Duration(1, 2, 3, 4, 5, 6, 7); +const subSeconds = new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, 987, 650); + +assert.sameValue(subSeconds.toString({ fractionalSecondDigits: 0 }), "P1Y2M3W4DT5H6M7S", + "truncates 4 decimal places to 0"); +assert.sameValue(wholeSeconds.toString({ fractionalSecondDigits: 2 }), "P1Y2M3W4DT5H6M7.00S", + "pads whole seconds to 2 decimal places"); +assert.sameValue(subSeconds.toString({ fractionalSecondDigits: 2 }), "P1Y2M3W4DT5H6M7.98S", + "truncates 4 decimal places to 2"); +assert.sameValue(subSeconds.toString({ fractionalSecondDigits: 3 }), "P1Y2M3W4DT5H6M7.987S", + "truncates 4 decimal places to 3"); +assert.sameValue(subSeconds.toString({ fractionalSecondDigits: 6 }), "P1Y2M3W4DT5H6M7.987650S", + "pads 4 decimal places to 6"); +assert.sameValue(wholeSeconds.toString({ fractionalSecondDigits: 7 }), "P1Y2M3W4DT5H6M7.0000000S", + "pads whole seconds to 7 decimal places"); +assert.sameValue(subSeconds.toString({ fractionalSecondDigits: 7 }), "P1Y2M3W4DT5H6M7.9876500S", + "pads 4 decimal places to 7"); +assert.sameValue(subSeconds.toString({ fractionalSecondDigits: 9 }), "P1Y2M3W4DT5H6M7.987650000S", + "pads 4 decimal places to 9"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/fractionalseconddigits-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/fractionalseconddigits-out-of-range.js index 5ddcfe36c6fa..307beed88463 100644 --- a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/fractionalseconddigits-out-of-range.js +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/fractionalseconddigits-out-of-range.js @@ -17,9 +17,13 @@ features: [Temporal] const duration = new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, 987, 650, 0); -assert.throws(RangeError, () => duration.toString({ fractionalSecondDigits: -Infinity })); -assert.throws(RangeError, () => duration.toString({ fractionalSecondDigits: -1 })); -assert.throws(RangeError, () => duration.toString({ fractionalSecondDigits: 10 })); -assert.throws(RangeError, () => duration.toString({ fractionalSecondDigits: Infinity })); +assert.throws(RangeError, () => duration.toString({ fractionalSecondDigits: -Infinity }), + "−∞ is out of range for fractionalSecondDigits"); +assert.throws(RangeError, () => duration.toString({ fractionalSecondDigits: -1 }), + "−1 is out of range for fractionalSecondDigits"); +assert.throws(RangeError, () => duration.toString({ fractionalSecondDigits: 10 }), + "10 is out of range for fractionalSecondDigits"); +assert.throws(RangeError, () => duration.toString({ fractionalSecondDigits: Infinity }), + "∞ is out of range for fractionalSecondDigits"); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/fractionalseconddigits-undefined.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/fractionalseconddigits-undefined.js index 84f0d55c0038..0059bbb42038 100644 --- a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/fractionalseconddigits-undefined.js +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/fractionalseconddigits-undefined.js @@ -17,12 +17,23 @@ info: | features: [Temporal] ---*/ -const duration = new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, 987, 650, 0); +const wholeSeconds = new Temporal.Duration(1, 2, 3, 4, 5, 6, 7); +const subSeconds = new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, 987, 650); -const explicit = duration.toString({ fractionalSecondDigits: undefined }); -assert.sameValue(explicit, "P1Y2M3W4DT5H6M7.98765S", "default fractionalSecondDigits is auto"); +const tests = [ + [wholeSeconds, "P1Y2M3W4DT5H6M7S"], + [subSeconds, "P1Y2M3W4DT5H6M7.98765S"], +]; -const implicit = duration.toString({}); -assert.sameValue(implicit, "P1Y2M3W4DT5H6M7.98765S", "default fractionalSecondDigits is auto"); +for (const [duration, expected] of tests) { + const explicit = duration.toString({ fractionalSecondDigits: undefined }); + assert.sameValue(explicit, expected, "default fractionalSecondDigits is auto (property present but undefined)"); + + const implicit = duration.toString({}); + assert.sameValue(implicit, expected, "default fractionalSecondDigits is auto (property not present)"); + + const lambda = duration.toString(() => {}); + assert.sameValue(lambda, expected, "default fractionalSecondDigits is auto (property not present, function object)"); +} reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/fractionalseconddigits-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/fractionalseconddigits-wrong-type.js index cbd95cfdaca7..a4bd73020d8a 100644 --- a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/fractionalseconddigits-wrong-type.js +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/fractionalseconddigits-wrong-type.js @@ -23,6 +23,28 @@ features: [Temporal] ---*/ const duration = new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, 987, 650, 0); -TemporalHelpers.checkFractionalSecondDigitsOptionWrongType(duration); + +assert.throws(RangeError, () => duration.toString({ fractionalSecondDigits: null }), + "null is not a number and converts to the string 'null' which is not valid for fractionalSecondDigits"); +assert.throws(RangeError, () => duration.toString({ fractionalSecondDigits: true }), + "true is not a number and converts to the string 'true' which is not valid for fractionalSecondDigits"); +assert.throws(RangeError, () => duration.toString({ fractionalSecondDigits: false }), + "false is not a number and converts to the string 'false' which is not valid for fractionalSecondDigits"); +assert.throws(TypeError, () => duration.toString({ fractionalSecondDigits: Symbol() }), + "symbols are not numbers and cannot convert to strings"); +assert.throws(RangeError, () => duration.toString({ fractionalSecondDigits: 2n }), + "bigints are not numbers and convert to strings which are not valid for fractionalSecondDigits"); +assert.throws(RangeError, () => duration.toString({ fractionalSecondDigits: {} }), + "plain objects are not numbers and convert to strings which are not valid for fractionalSecondDigits"); + +const expected = [ + "get fractionalSecondDigits.toString", + "call fractionalSecondDigits.toString", +]; +const actual = []; +const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); +const result = duration.toString({ fractionalSecondDigits: observer }); +assert.sameValue(result, "P1Y2M3W4DT5H6M7.98765S", "object with toString uses toString return value"); +assert.compareArray(actual, expected, "object with toString calls toString and not valueOf"); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/options-wrong-type.js new file mode 100644 index 000000000000..f1ccff62f40b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.tostring +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.Duration(0, 0, 0, 0, 1); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.toString(value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/roundingmode-ceil.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/roundingmode-ceil.js new file mode 100644 index 000000000000..ccc6d376dcd7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/roundingmode-ceil.js @@ -0,0 +1,37 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.tostring +description: ceil value for roundingMode option +features: [Temporal] +---*/ + +const duration = new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, 123, 987, 500); + +const result1 = duration.toString({ smallestUnit: "microsecond", roundingMode: "ceil" }); +assert.sameValue(result1, "P1Y2M3W4DT5H6M7.123988S", + "roundingMode is ceil (with 6 digits from smallestUnit)"); + +const result2 = duration.toString({ fractionalSecondDigits: 6, roundingMode: "ceil" }); +assert.sameValue(result2, "P1Y2M3W4DT5H6M7.123988S", + "roundingMode is ceil (with 6 digits from fractionalSecondDigits)"); + +const result3 = duration.toString({ smallestUnit: "millisecond", roundingMode: "ceil" }); +assert.sameValue(result3, "P1Y2M3W4DT5H6M7.124S", + "roundingMode is ceil (with 3 digits from smallestUnit)"); + +const result4 = duration.toString({ fractionalSecondDigits: 3, roundingMode: "ceil" }); +assert.sameValue(result4, "P1Y2M3W4DT5H6M7.124S", + "roundingMode is ceil (with 3 digits from fractionalSecondDigits)"); + +const result5 = duration.toString({ smallestUnit: "second", roundingMode: "ceil" }); +assert.sameValue(result5, "P1Y2M3W4DT5H6M8S", + "roundingMode is ceil (with 0 digits from smallestUnit)"); + +const result6 = duration.toString({ fractionalSecondDigits: 0, roundingMode: "ceil" }); +assert.sameValue(result6, "P1Y2M3W4DT5H6M8S", + "roundingMode is ceil (with 0 digits from fractionalSecondDigits)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/roundingmode-floor.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/roundingmode-floor.js new file mode 100644 index 000000000000..2f2173cb8846 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/roundingmode-floor.js @@ -0,0 +1,37 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.tostring +description: floor value for roundingMode option +features: [Temporal] +---*/ + +const duration = new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, 123, 987, 500); + +const result1 = duration.toString({ smallestUnit: "microsecond", roundingMode: "floor" }); +assert.sameValue(result1, "P1Y2M3W4DT5H6M7.123987S", + "roundingMode is floor (with 6 digits from smallestUnit)"); + +const result2 = duration.toString({ fractionalSecondDigits: 6, roundingMode: "floor" }); +assert.sameValue(result2, "P1Y2M3W4DT5H6M7.123987S", + "roundingMode is floor (with 6 digits from fractionalSecondDigits)"); + +const result3 = duration.toString({ smallestUnit: "millisecond", roundingMode: "floor" }); +assert.sameValue(result3, "P1Y2M3W4DT5H6M7.123S", + "roundingMode is floor (with 3 digits from smallestUnit)"); + +const result4 = duration.toString({ fractionalSecondDigits: 3, roundingMode: "floor" }); +assert.sameValue(result4, "P1Y2M3W4DT5H6M7.123S", + "roundingMode is floor (with 3 digits from fractionalSecondDigits)"); + +const result5 = duration.toString({ smallestUnit: "second", roundingMode: "floor" }); +assert.sameValue(result5, "P1Y2M3W4DT5H6M7S", + "roundingMode is floor (with 0 digits from smallestUnit)"); + +const result6 = duration.toString({ fractionalSecondDigits: 0, roundingMode: "floor" }); +assert.sameValue(result6, "P1Y2M3W4DT5H6M7S", + "roundingMode is floor (with 0 digits from fractionalSecondDigits)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/roundingmode-halfExpand.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/roundingmode-halfExpand.js new file mode 100644 index 000000000000..81f89c060c73 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/roundingmode-halfExpand.js @@ -0,0 +1,37 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.tostring +description: halfExpand value for roundingMode option +features: [Temporal] +---*/ + +const duration = new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, 123, 987, 500); + +const result1 = duration.toString({ smallestUnit: "microsecond", roundingMode: "halfExpand" }); +assert.sameValue(result1, "P1Y2M3W4DT5H6M7.123988S", + "roundingMode is halfExpand (with 6 digits from smallestUnit)"); + +const result2 = duration.toString({ fractionalSecondDigits: 6, roundingMode: "halfExpand" }); +assert.sameValue(result2, "P1Y2M3W4DT5H6M7.123988S", + "roundingMode is halfExpand (with 6 digits from fractionalSecondDigits)"); + +const result3 = duration.toString({ smallestUnit: "millisecond", roundingMode: "halfExpand" }); +assert.sameValue(result3, "P1Y2M3W4DT5H6M7.124S", + "roundingMode is halfExpand (with 3 digits from smallestUnit)"); + +const result4 = duration.toString({ fractionalSecondDigits: 3, roundingMode: "halfExpand" }); +assert.sameValue(result4, "P1Y2M3W4DT5H6M7.124S", + "roundingMode is halfExpand (with 3 digits from fractionalSecondDigits)"); + +const result5 = duration.toString({ smallestUnit: "second", roundingMode: "halfExpand" }); +assert.sameValue(result5, "P1Y2M3W4DT5H6M7S", + "roundingMode is halfExpand (with 0 digits from smallestUnit)"); + +const result6 = duration.toString({ fractionalSecondDigits: 0, roundingMode: "halfExpand" }); +assert.sameValue(result6, "P1Y2M3W4DT5H6M7S", + "roundingMode is halfExpand (with 0 digits from fractionalSecondDigits)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/roundingmode-trunc.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/roundingmode-trunc.js new file mode 100644 index 000000000000..f93512994d65 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/roundingmode-trunc.js @@ -0,0 +1,37 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.tostring +description: trunc value for roundingMode option +features: [Temporal] +---*/ + +const duration = new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, 123, 987, 500); + +const result1 = duration.toString({ smallestUnit: "microsecond", roundingMode: "trunc" }); +assert.sameValue(result1, "P1Y2M3W4DT5H6M7.123987S", + "roundingMode is trunc (with 6 digits from smallestUnit)"); + +const result2 = duration.toString({ fractionalSecondDigits: 6, roundingMode: "trunc" }); +assert.sameValue(result2, "P1Y2M3W4DT5H6M7.123987S", + "roundingMode is trunc (with 6 digits from fractionalSecondDigits)"); + +const result3 = duration.toString({ smallestUnit: "millisecond", roundingMode: "trunc" }); +assert.sameValue(result3, "P1Y2M3W4DT5H6M7.123S", + "roundingMode is trunc (with 3 digits from smallestUnit)"); + +const result4 = duration.toString({ fractionalSecondDigits: 3, roundingMode: "trunc" }); +assert.sameValue(result4, "P1Y2M3W4DT5H6M7.123S", + "roundingMode is trunc (with 3 digits from fractionalSecondDigits)"); + +const result5 = duration.toString({ smallestUnit: "second", roundingMode: "trunc" }); +assert.sameValue(result5, "P1Y2M3W4DT5H6M7S", + "roundingMode is trunc (with 0 digits from smallestUnit)"); + +const result6 = duration.toString({ fractionalSecondDigits: 0, roundingMode: "trunc" }); +assert.sameValue(result6, "P1Y2M3W4DT5H6M7S", + "roundingMode is trunc (with 0 digits from fractionalSecondDigits)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/smallestunit-fractionalseconddigits.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/smallestunit-fractionalseconddigits.js new file mode 100644 index 000000000000..6cab0facfde5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/smallestunit-fractionalseconddigits.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.tostring +description: fractionalSecondDigits option is not used with smallestUnit present +features: [Temporal] +---*/ + +const duration = new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, 789, 999, 999); +const tests = [ + ["second", "P1Y2M3W4DT5H6M7S"], + ["millisecond", "P1Y2M3W4DT5H6M7.789S"], + ["microsecond", "P1Y2M3W4DT5H6M7.789999S"], + ["nanosecond", "P1Y2M3W4DT5H6M7.789999999S"], +]; + +for (const [smallestUnit, expected] of tests) { + const string = duration.toString({ + smallestUnit, + get fractionalSecondDigits() { throw new Test262Error("should not get fractionalSecondDigits") } + }); + assert.sameValue(string, expected, `smallestUnit: "${smallestUnit}" overrides fractionalSecondDigits`); +} + +assert.throws(RangeError, () => duration.toString({ + smallestUnit: "hour", + get fractionalSecondDigits() { throw new Test262Error("should not get fractionalSecondDigits") } +}), "hour is an invalid smallestUnit but still overrides fractionalSecondDigits"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/smallestunit-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/smallestunit-invalid-string.js index 247e8b7637b6..4814101a35da 100644 --- a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/smallestunit-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/smallestunit-invalid-string.js @@ -9,9 +9,34 @@ features: [Temporal] ---*/ const duration = new Temporal.Duration(0, 0, 0, 0, 12, 34, 56, 123, 987, 500); -const values = ["eras", "years", "months", "weeks", "days", "hours", "minutes", "nonsense", "other string", "mill\u0131seconds", "SECONDS"]; -for (const smallestUnit of values) { - assert.throws(RangeError, () => duration.toString({ smallestUnit })); +const badValues = [ + "era", + "eraYear", + "year", + "month", + "week", + "day", + "hour", + "minute", + "millisecond\0", + "mill\u0131second", + "SECOND", + "eras", + "eraYears", + "years", + "months", + "weeks", + "days", + "hours", + "minutes", + "milliseconds\0", + "mill\u0131seconds", + "SECONDS", + "other string", +]; +for (const smallestUnit of badValues) { + assert.throws(RangeError, () => duration.toString({ smallestUnit }), + `"${smallestUnit}" is not a valid value for smallest unit`); } reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/smallestunit-valid-units.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/smallestunit-valid-units.js index 11ad7f828b79..8be618d6b71f 100644 --- a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/smallestunit-valid-units.js +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/toString/smallestunit-valid-units.js @@ -10,12 +10,37 @@ features: [Temporal] const duration = new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, 987, 654, 321); -assert.sameValue(duration.toString({ smallestUnit: "second" }), "P1Y2M3W4DT5H6M7S"); -assert.sameValue(duration.toString({ smallestUnit: "millisecond" }), "P1Y2M3W4DT5H6M7.987S"); -assert.sameValue(duration.toString({ smallestUnit: "microsecond" }), "P1Y2M3W4DT5H6M7.987654S"); -assert.sameValue(duration.toString({ smallestUnit: "nanosecond" }), "P1Y2M3W4DT5H6M7.987654321S"); +function test(instance, expectations, description) { + for (const [smallestUnit, expectedResult] of expectations) { + assert.sameValue(instance.toString({ smallestUnit }), expectedResult, + `${description} with smallestUnit "${smallestUnit}"`); + } +} + +test( + duration, + [ + ["seconds", "P1Y2M3W4DT5H6M7S"], + ["milliseconds", "P1Y2M3W4DT5H6M7.987S"], + ["microseconds", "P1Y2M3W4DT5H6M7.987654S"], + ["nanoseconds", "P1Y2M3W4DT5H6M7.987654321S"], + ], + "subseconds toString" +); + +test( + new Temporal.Duration(1, 2, 3, 4, 5, 6, 7), + [ + ["seconds", "P1Y2M3W4DT5H6M7S"], + ["milliseconds", "P1Y2M3W4DT5H6M7.000S"], + ["microseconds", "P1Y2M3W4DT5H6M7.000000S"], + ["nanoseconds", "P1Y2M3W4DT5H6M7.000000000S"], + ], + "whole seconds toString" +); const notValid = [ + "era", "year", "month", "week", @@ -25,7 +50,8 @@ const notValid = [ ]; notValid.forEach((smallestUnit) => { - assert.throws(RangeError, () => duration.toString({ smallestUnit }), smallestUnit); + assert.throws(RangeError, () => duration.toString({ smallestUnit }), + `"${smallestUnit}" is not a valid unit for the smallestUnit option`); }); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/total/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/total/options-wrong-type.js index ac4625bc1b18..c11bc7d90108 100644 --- a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/total/options-wrong-type.js +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/total/options-wrong-type.js @@ -1,14 +1,14 @@ // |reftest| skip -- Temporal is not supported -// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// Copyright (C) 2022 Igalia, S.L. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. /*--- esid: sec-temporal.duration.prototype.total -description: TypeError thrown when options argument is missing or a primitive +description: TypeError thrown when options argument is missing or a non-string primitive features: [BigInt, Symbol, Temporal] ---*/ -const values = [ +const badOptions = [ undefined, null, true, @@ -18,9 +18,10 @@ const values = [ ]; const instance = new Temporal.Duration(0, 0, 0, 0, 1); -assert.throws(TypeError, () => instance.total(), "TypeError on missing argument"); -values.forEach((value) => { - assert.throws(TypeError, () => instance.total(value), `TypeError on wrong argument type ${typeof(value)}`); -}); +assert.throws(TypeError, () => instance.total(), "TypeError on missing options argument"); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.total(value), + `TypeError on wrong options type ${typeof value}`); +}; reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/total/relativeto-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/total/relativeto-leap-second.js new file mode 100644 index 000000000000..6af825f2d4c4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/total/relativeto-leap-second.js @@ -0,0 +1,45 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.total +description: Leap second is constrained in both an ISO string and a property bag +features: [Temporal] +---*/ + +const instance = new Temporal.Duration(1, 0, 0, 0, 24); + +let relativeTo = "2016-12-31T23:59:60"; +const result1 = instance.total({ unit: "days", relativeTo }); +assert.sameValue( + result1, + 366, + "leap second is a valid ISO string for PlainDate relativeTo" +); + +relativeTo = "2016-12-31T23:59:60+00:00[UTC]"; +const result2 = instance.total({ unit: "days", relativeTo }); +assert.sameValue( + result2, + 366, + "leap second is a valid ISO string for ZonedDateTime relativeTo" +); + +relativeTo = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result3 = instance.total({ unit: "days", relativeTo }); +assert.sameValue( + result3, + 366, + "second: 60 is valid in a property bag for PlainDate relativeTo" +); + +relativeTo = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60, timeZone: "UTC" }; +const result4 = instance.total({ unit: "days", relativeTo }); +assert.sameValue( + result4, + 366, + "second: 60 is valid in a property bag for ZonedDateTime relativeTo" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/total/relativeto-number.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/total/relativeto-number.js new file mode 100644 index 000000000000..826a1317c2f2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/total/relativeto-number.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.total +description: A number as relativeTo option is converted to a string, then to Temporal.PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Duration(1, 0, 0, 0, 24); + +const relativeTo = 20191101; + +const result = instance.total({ unit: "days", relativeTo }); +assert.sameValue(result, 367, "20191101 is a valid ISO string for relativeTo"); + +const numbers = [ + 1, + -20191101, + 1234567890, +]; + +for (const relativeTo of numbers) { + assert.throws( + RangeError, + () => instance.total({ unit: "days", relativeTo }), + `Number ${relativeTo} does not convert to a valid ISO string for relativeTo` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-calendar-number.js new file mode 100644 index 000000000000..92fc470e3999 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-calendar-number.js @@ -0,0 +1,44 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.total +description: A number as calendar in relativeTo property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Duration(1, 0, 0, 0, 24); + +const calendar = 19970327; + +let relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; +const result1 = instance.total({ unit: "days", relativeTo }); +assert.sameValue(result1, 367, "19970327 is a valid ISO string for relativeTo.calendar"); + +relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; +const result2 = instance.total({ unit: "days", relativeTo }); +assert.sameValue(result2, 367, "19970327 is a valid ISO string for relativeTo.calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws( + RangeError, + () => instance.total({ unit: "days", relativeTo }), + `Number ${calendar} does not convert to a valid ISO string for relativeTo.calendar` + ); + relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.total({ unit: "days", relativeTo }), + `Number ${calendar} does not convert to a valid ISO string for relativeTo.calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..88b50ff3d493 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-calendar-wrong-type.js @@ -0,0 +1,52 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.total +description: > + Appropriate error thrown when relativeTo.calendar cannot be converted to a + calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.Duration(1, 0, 0, 0, 24); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.total({ unit: "days", relativeTo }), `${description} does not convert to a valid ISO string`); + + relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.total({ unit: "days", relativeTo }), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], + [Temporal.ZonedDateTime, "Temporal.ZonedDateTime, object"], + [Temporal.ZonedDateTime.prototype, "Temporal.ZonedDateTime.prototype, object"], +]; + +for (const [calendar, description] of typeErrorTests) { + let relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.total({ unit: "days", relativeTo }), `${description} is not a valid property bag and does not convert to a string`); + + relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.total({ unit: "days", relativeTo }), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const relativeTo = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.total({ unit: "days", relativeTo }), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/total/relativeto-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/total/relativeto-wrong-type.js new file mode 100644 index 000000000000..108b7f1f46dd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/total/relativeto-wrong-type.js @@ -0,0 +1,42 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.total +description: > + Appropriate error thrown when relativeTo cannot be converted to a valid + relativeTo string or property bag +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.Duration(1, 0, 0, 0, 24); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [relativeTo, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.total({ unit: "days", relativeTo }), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], + [Temporal.ZonedDateTime, "Temporal.ZonedDateTime, object"], + [Temporal.ZonedDateTime.prototype, "Temporal.ZonedDateTime.prototype, object"], +]; + +for (const [relativeTo, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.total({ unit: "days", relativeTo }), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/total/timezone-string-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/total/timezone-string-leap-second.js new file mode 100644 index 000000000000..864f18a21400 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/total/timezone-string-leap-second.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.total +description: Leap second is a valid ISO string for TimeZone +features: [Temporal] +---*/ + +const instance = new Temporal.Duration(1); +let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; + +// A string with a leap second is a valid ISO string, so the following two +// operations should not throw + +instance.total({ unit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone } }); +instance.total({ unit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }); + +timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; +assert.throws(RangeError, () => instance.total({ unit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), "leap second in time zone name not valid"); +assert.throws(RangeError, () => instance.total({ unit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), "leap second in time zone name not valid (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/total/timezone-string-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/total/timezone-string-year-zero.js new file mode 100644 index 000000000000..5b2d9bfbd5ed --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/total/timezone-string-year-zero.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.total +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.Duration(1); +invalidStrings.forEach((timeZone) => { + assert.throws( + RangeError, + () => instance.total({ unit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), + "reject minus zero as extended year" + ); + assert.throws( + RangeError, + () => instance.total({ unit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), + "reject minus zero as extended year (nested property)" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/total/timezone-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/total/timezone-wrong-type.js new file mode 100644 index 000000000000..7e5c63e72501 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/total/timezone-wrong-type.js @@ -0,0 +1,41 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.total +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for TimeZone +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.Duration(1); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], +]; + +for (const [timeZone, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.total({ unit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), `${description} does not convert to a valid ISO string`); + assert.throws(RangeError, () => instance.total({ unit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [timeZone, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.total({ unit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone } }), `${description} is not a valid object and does not convert to a string`); + assert.throws(TypeError, () => instance.total({ unit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), `${description} is not a valid object and does not convert to a string (nested property)`); +} + +const timeZone = undefined; +assert.throws(RangeError, () => instance.total({ unit: "months", relativeTo: { year: 2000, month: 5, day: 2, timeZone: { timeZone } } }), `undefined is always a RangeError as nested property`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/valueOf/basic.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/valueOf/basic.js new file mode 100644 index 000000000000..a1b5de5a361c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/valueOf/basic.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.valueof +description: Basic tests for valueOf(). +features: [Temporal] +---*/ + +const d1 = Temporal.Duration.from("P3DT1H"); +const d2 = Temporal.Duration.from("P3DT1H"); + +assert.throws(TypeError, () => d1.valueOf(), "valueOf"); +assert.throws(TypeError, () => d1 < d1, "<"); +assert.throws(TypeError, () => d1 <= d1, "<="); +assert.throws(TypeError, () => d1 > d1, ">"); +assert.throws(TypeError, () => d1 >= d1, ">="); +assert.sameValue(d1 === d1, true, "==="); +assert.sameValue(d1 === d2, false, "==="); +assert.sameValue(d1 !== d1, false, "!=="); +assert.sameValue(d1 !== d2, true, "!=="); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/with/argument-invalid-prop.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/with/argument-invalid-prop.js new file mode 100644 index 000000000000..d80c8ad4b5f6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/with/argument-invalid-prop.js @@ -0,0 +1,16 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.with +description: Singular properties are ignored. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const d = Temporal.Duration.from({ years: 5, days: 1 }); +const d2 = d.with({ year: 1, days: 0 }); +TemporalHelpers.assertDuration(d2, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/with/argument-mixed-sign.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/with/argument-mixed-sign.js new file mode 100644 index 000000000000..0f10e770a7a0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/with/argument-mixed-sign.js @@ -0,0 +1,14 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.with +description: The durationLike argument must not contain different signs. +features: [Temporal] +---*/ + +const d = new Temporal.Duration(1, 2, 3, 4, 5); +assert.throws(RangeError, () => d.with({ hours: 1, minutes: -1 })); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/with/argument-sign-prop.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/with/argument-sign-prop.js new file mode 100644 index 000000000000..a660c8a70e7f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/with/argument-sign-prop.js @@ -0,0 +1,17 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.with +description: Passing a sign property is not supported. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const d = Temporal.Duration.from({ years: 5, days: 1 }); +assert.throws(TypeError, () => d.with({ sign: -1 })); +const d2 = d.with({ sign: -1, days: 0 }); +TemporalHelpers.assertDuration(d2, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/prototype/with/sign-replace.js b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/with/sign-replace.js new file mode 100644 index 000000000000..9f66c16b13a5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Duration/prototype/with/sign-replace.js @@ -0,0 +1,18 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.with +description: Replacing the sign is supported. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const d = Temporal.Duration.from({ years: 5, days: 1 }); +assert.sameValue(d.sign, 1, "original sign"); +const d2 = d.with({ years: -1, days: 0, minutes: -1 }); +assert.sameValue(d2.sign, -1, "new sign"); +TemporalHelpers.assertDuration(d2, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Duration/shell.js b/js/src/tests/test262/built-ins/Temporal/Duration/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/built-ins/Temporal/Duration/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/Duration/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/compare/argument-object-tostring.js b/js/src/tests/test262/built-ins/Temporal/Instant/compare/argument-object-tostring.js new file mode 100644 index 000000000000..7ccc170cf87e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/compare/argument-object-tostring.js @@ -0,0 +1,25 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.compare +description: Object is converted to a string, then to Temporal.Instant +features: [Temporal] +---*/ + +const epoch = new Temporal.Instant(0n); + +const arg = {}; +assert.throws(RangeError, () => Temporal.Instant.compare(arg, epoch), "[object Object] is not a valid ISO string (first argument)"); +assert.throws(RangeError, () => Temporal.Instant.compare(epoch, arg), "[object Object] is not a valid ISO string (second argument)"); + +arg.toString = function() { + return "1970-01-01T00:00Z"; +}; +const result1 = Temporal.Instant.compare(arg, epoch); +assert.sameValue(result1, 0, "result of toString is interpreted as ISO string (first argument)"); +const result2 = Temporal.Instant.compare(epoch, arg); +assert.sameValue(result2, 0, "result of toString is interpreted as ISO string (second argument)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/compare/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Instant/compare/argument-wrong-type.js new file mode 100644 index 000000000000..14a08fa58acc --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/compare/argument-wrong-type.js @@ -0,0 +1,42 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.compare +description: > + Appropriate error thrown when argument cannot be converted to a valid string + for Instant +features: [BigInt, Symbol, Temporal] +---*/ + +const other = new Temporal.Instant(0n); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], + [{}, "plain object"], + [Temporal.Instant, "Temporal.Instant, object"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => Temporal.Instant.compare(arg, other), `${description} does not convert to a valid ISO string (first argument)`); + assert.throws(RangeError, () => Temporal.Instant.compare(other, arg), `${description} does not convert to a valid ISO string (second argument)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [Temporal.Instant.prototype, "Temporal.Instant.prototype, object"], // fails brand check in toString() +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => Temporal.Instant.compare(arg, other), `${description} does not convert to a string (first argument)`); + assert.throws(TypeError, () => Temporal.Instant.compare(other, arg), `${description} does not convert to a string (second argument)`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/compare/instant-string-sub-minute-offset.js b/js/src/tests/test262/built-ins/Temporal/Instant/compare/instant-string-sub-minute-offset.js new file mode 100644 index 000000000000..2d3bba42b844 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/compare/instant-string-sub-minute-offset.js @@ -0,0 +1,20 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.compare +description: Temporal.Instant string with sub-minute offset +features: [Temporal] +---*/ + +const epoch = new Temporal.Instant(0n); +const str = "1970-01-01T00:19:32.37+00:19:32.37"; + +const result1 = Temporal.Instant.compare(str, epoch); +assert.sameValue(result1, 0, "if present, sub-minute offset is accepted exactly (first argument)"); + +const result2 = Temporal.Instant.compare(epoch, str); +assert.sameValue(result2, 0, "if present, sub-minute offset is accepted exactly (second argument)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/compare/leap-second.js b/js/src/tests/test262/built-ins/Temporal/Instant/compare/leap-second.js new file mode 100644 index 000000000000..111520a10362 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/compare/leap-second.js @@ -0,0 +1,18 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.compare +description: Leap second is a valid ISO string for Instant +features: [Temporal] +---*/ + +const other = new Temporal.Instant(1_483_228_799_000_000_000n); +const arg = "2016-12-31T23:59:60Z"; +const result1 = Temporal.Instant.compare(arg, other); +assert.sameValue(result1, 0, "leap second is a valid ISO string for Instant (first argument)"); +const result2 = Temporal.Instant.compare(other, arg); +assert.sameValue(result2, 0, "leap second is a valid ISO string for Instant (second argument)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/compare/shell.js b/js/src/tests/test262/built-ins/Temporal/Instant/compare/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/Instant/compare/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/Instant/compare/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/compare/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Instant/compare/year-zero.js index 9ee12478173c..196442aab10d 100644 --- a/js/src/tests/test262/built-ins/Temporal/Instant/compare/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/Instant/compare/year-zero.js @@ -9,14 +9,20 @@ features: [Temporal] ---*/ const instance = new Temporal.Instant(0n); -const bad = '-000000-03-30T00:45Z'; +const invalidStrings = [ + "-000000-03-30T00:45Z", + "-000000-03-30T01:45+01:00", + "-000000-03-30T01:45:00+00:00[UTC]", +]; -assert.throws(RangeError, - () => Temporal.Instant.compare(bad, instance), - "minus zero is invalid extended year (first argument)"); -assert.throws(RangeError, - () => Temporal.Instant.compare(instance, bad), - "minus zero is invalid extended year (second argument)" -); +invalidStrings.forEach((arg) => { + assert.throws(RangeError, + () => Temporal.Instant.compare(arg, instance), + "minus zero is invalid extended year (first argument)"); + assert.throws(RangeError, + () => Temporal.Instant.compare(instance, arg), + "minus zero is invalid extended year (second argument)" + ); +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/from/argument-instant.js b/js/src/tests/test262/built-ins/Temporal/Instant/from/argument-instant.js new file mode 100644 index 000000000000..c5d990b5ee65 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/from/argument-instant.js @@ -0,0 +1,22 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.from +description: A Instant object is copied, not returned directly +features: [Temporal] +---*/ + +const orig = new Temporal.Instant(217_175_010_123_456_789n); +const result = Temporal.Instant.from(orig); + +assert.sameValue(result.epochNanoseconds, 217_175_010_123_456_789n, "Instant is copied"); + +assert.notSameValue( + result, + orig, + "When an Instant is given, the returned value is not the original Instant" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/from/argument-object-tostring.js b/js/src/tests/test262/built-ins/Temporal/Instant/from/argument-object-tostring.js new file mode 100644 index 000000000000..9642dc036a0e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/from/argument-object-tostring.js @@ -0,0 +1,20 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.from +description: Object is converted to a string, then to Temporal.Instant +features: [Temporal] +---*/ + +const arg = {}; +assert.throws(RangeError, () => Temporal.Instant.from(arg), "[object Object] is not a valid ISO string"); + +arg.toString = function() { + return "1970-01-01T00:00Z"; +}; +const result = Temporal.Instant.from(arg); +assert.sameValue(result.epochNanoseconds, 0n, "result of toString is interpreted as ISO string"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/from/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Instant/from/argument-wrong-type.js new file mode 100644 index 000000000000..542b81c858f3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/from/argument-wrong-type.js @@ -0,0 +1,38 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.from +description: > + Appropriate error thrown when argument cannot be converted to a valid string + for Instant +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], + [{}, "plain object"], + [Temporal.Instant, "Temporal.Instant, object"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => Temporal.Instant.from(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [Temporal.Instant.prototype, "Temporal.Instant.prototype, object"], // fails brand check in toString() +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => Temporal.Instant.from(arg), `${description} does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/from/basic.js b/js/src/tests/test262/built-ins/Temporal/Instant/from/basic.js new file mode 100644 index 000000000000..22137fddef3b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/from/basic.js @@ -0,0 +1,62 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.from +description: Basic functionality of Temporal.Instant.from +features: [Temporal] +---*/ + +const baseValue = 217_178_580_000_000_000n; + +let instant = Temporal.Instant.from("1976-11-18T15:23Z"); +assert.sameValue( + instant.epochNanoseconds, + baseValue, + "ISO string with UTC designator and minutes precision" +); + +instant = Temporal.Instant.from("1976-11-18T15:23:30Z"); +assert.sameValue( + instant.epochNanoseconds, + baseValue + 30_000_000_000n, + "ISO string with UTC designator and seconds precision" +); + +instant = Temporal.Instant.from("1976-11-18T15:23:30.123Z"); +assert.sameValue( + instant.epochNanoseconds, + baseValue + 30_123_000_000n, + "ISO string with UTC designator and milliseconds precision" +); + +instant = Temporal.Instant.from("1976-11-18T15:23:30.123456Z"); +assert.sameValue( + instant.epochNanoseconds, + baseValue + 30_123_456_000n, + "ISO string with UTC designator and microseconds precision" +); + +instant = Temporal.Instant.from("1976-11-18T15:23:30.123456789Z"); +assert.sameValue( + instant.epochNanoseconds, + baseValue + 30_123_456_789n, + "ISO string with UTC designator and nanoseconds precision" +); + +instant = Temporal.Instant.from("1976-11-18T15:23-01:00"); +assert.sameValue( + instant.epochNanoseconds, + baseValue + 3600_000_000_000n, + "ISO string with negative UTC offset" +); + +instant = Temporal.Instant.from("1976-11-18T15:23+01:00"); +assert.sameValue( + instant.epochNanoseconds, + baseValue - 3600_000_000_000n, + "ISO string with positive UTC offset" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/from/instant-string-sub-minute-offset.js b/js/src/tests/test262/built-ins/Temporal/Instant/from/instant-string-sub-minute-offset.js new file mode 100644 index 000000000000..0a177da0733b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/from/instant-string-sub-minute-offset.js @@ -0,0 +1,15 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.from +description: Temporal.Instant string with sub-minute offset +features: [Temporal] +---*/ + +const str = "1970-01-01T00:19:32.37+00:19:32.37"; +const result = Temporal.Instant.from(str); +assert.sameValue(result.epochNanoseconds, 0n, "if present, sub-minute offset is accepted exactly"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/from/leap-second.js b/js/src/tests/test262/built-ins/Temporal/Instant/from/leap-second.js new file mode 100644 index 000000000000..01699c764e26 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/from/leap-second.js @@ -0,0 +1,19 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.from +description: Leap second is a valid ISO string for Instant +features: [Temporal] +---*/ + +const arg = "2016-12-31T23:59:60Z"; +const result = Temporal.Instant.from(arg); +assert.sameValue( + result.epochNanoseconds, + 1_483_228_799_000_000_000n, + "leap second is a valid ISO string for Instant" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/from/shell.js b/js/src/tests/test262/built-ins/Temporal/Instant/from/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/Instant/from/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/Instant/from/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/from/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Instant/from/year-zero.js index 102a16602a6e..5ea56daa8abe 100644 --- a/js/src/tests/test262/built-ins/Temporal/Instant/from/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/Instant/from/year-zero.js @@ -5,19 +5,19 @@ /*--- esid: sec-temporal.instant.from description: Negative zero, as an extended year, is rejected -features: [Temporal] +features: [Temporal, arrow-function] ---*/ const invalidStrings = [ - "-000000-03-31T00:45Z", - "-000000-03-31T01:45+01:00", - "-000000-03-31T01:45:00+01:00[UTC]" + "-000000-03-30T00:45Z", + "-000000-03-30T01:45+01:00", + "-000000-03-30T01:45:00+00:00[UTC]", ]; -invalidStrings.forEach((str) => { +invalidStrings.forEach((arg) => { assert.throws( RangeError, - () => Temporal.Instant.from(str), + () => Temporal.Instant.from(arg), "reject minus zero as extended year" ); }); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/fromEpochMicroseconds/shell.js b/js/src/tests/test262/built-ins/Temporal/Instant/fromEpochMicroseconds/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/Instant/fromEpochMicroseconds/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/Instant/fromEpochMicroseconds/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/fromEpochMilliseconds/shell.js b/js/src/tests/test262/built-ins/Temporal/Instant/fromEpochMilliseconds/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/Instant/fromEpochMilliseconds/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/Instant/fromEpochMilliseconds/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/fromEpochNanoseconds/shell.js b/js/src/tests/test262/built-ins/Temporal/Instant/fromEpochNanoseconds/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/Instant/fromEpochNanoseconds/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/Instant/fromEpochNanoseconds/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/fromEpochSeconds/shell.js b/js/src/tests/test262/built-ins/Temporal/Instant/fromEpochSeconds/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/Instant/fromEpochSeconds/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/Instant/fromEpochSeconds/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/add/shell.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/add/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/add/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/add/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/equals/argument-object-tostring.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/equals/argument-object-tostring.js new file mode 100644 index 000000000000..ec44c3cd9ebf --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/equals/argument-object-tostring.js @@ -0,0 +1,22 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.equals +description: Object is converted to a string, then to Temporal.Instant +features: [Temporal] +---*/ + +const instance = new Temporal.Instant(0n); + +const arg = {}; +assert.throws(RangeError, () => instance.equals(arg), "[object Object] is not a valid ISO string"); + +arg.toString = function() { + return "1970-01-01T00:00Z"; +}; +const result = instance.equals(arg); +assert.sameValue(result, true, "result of toString is interpreted as ISO string"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/equals/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/equals/argument-wrong-type.js index a5d45237095d..206485634272 100644 --- a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/equals/argument-wrong-type.js +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/equals/argument-wrong-type.js @@ -1,23 +1,40 @@ // |reftest| skip -- Temporal is not supported -// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// Copyright (C) 2022 Igalia, S.L. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. /*--- esid: sec-temporal.instant.prototype.equals -description: Appropriate error thrown when argument cannot be converted to a valid string -features: [Symbol, Temporal] +description: > + Appropriate error thrown when argument cannot be converted to a valid string + for Instant +features: [BigInt, Symbol, Temporal] ---*/ -const instance = Temporal.Instant.fromEpochSeconds(0); +const instance = new Temporal.Instant(0n); -assert.throws(RangeError, () => instance.equals(undefined), "undefined"); -assert.throws(RangeError, () => instance.equals(null), "null"); -assert.throws(RangeError, () => instance.equals(true), "true"); -assert.throws(RangeError, () => instance.equals(""), "empty string"); -assert.throws(TypeError, () => instance.equals(Symbol()), "symbol"); -assert.throws(RangeError, () => instance.equals(1), "1"); -assert.throws(RangeError, () => instance.equals({}), "plain object"); -assert.throws(RangeError, () => instance.equals(Temporal.Instant), "Temporal.Instant"); -assert.throws(TypeError, () => instance.equals(Temporal.Instant.prototype), "Temporal.Instant.prototype"); +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], + [{}, "plain object"], + [Temporal.Instant, "Temporal.Instant, object"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.equals(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [Temporal.Instant.prototype, "Temporal.Instant.prototype, object"], // fails brand check in toString() +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.equals(arg), `${description} does not convert to a string`); +} reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/equals/instant-string-sub-minute-offset.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/equals/instant-string-sub-minute-offset.js new file mode 100644 index 000000000000..1d6a2129cd6d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/equals/instant-string-sub-minute-offset.js @@ -0,0 +1,17 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.equals +description: Temporal.Instant string with sub-minute offset +features: [Temporal] +---*/ + +const instance = new Temporal.Instant(0n); + +const str = "1970-01-01T00:19:32.37+00:19:32.37"; +const result = instance.equals(str); +assert.sameValue(result, true, "if present, sub-minute offset is accepted exactly"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/equals/leap-second.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/equals/leap-second.js new file mode 100644 index 000000000000..cc0a282e4b42 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/equals/leap-second.js @@ -0,0 +1,21 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.equals +description: Leap second is a valid ISO string for Instant +features: [Temporal] +---*/ + +const instance = new Temporal.Instant(1_483_228_799_000_000_000n); + +const arg = "2016-12-31T23:59:60Z"; +const result = instance.equals(arg); +assert.sameValue( + result, + true, + "leap second is a valid ISO string for Instant" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/equals/shell.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/equals/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/equals/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/equals/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/equals/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/equals/year-zero.js index fa94136a64cd..b383cd716265 100644 --- a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/equals/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/equals/year-zero.js @@ -5,19 +5,19 @@ /*--- esid: sec-temporal.instant.prototype.equals description: Negative zero, as an extended year, is rejected -features: [Temporal] +features: [Temporal, arrow-function] ---*/ const invalidStrings = [ - "-000000-03-30T00:45Z", - "-000000-03-30T01:45+01:00", - "-000000-03-30T01:45:00+01:00[UTC]" + "-000000-03-30T00:45Z", + "-000000-03-30T01:45+01:00", + "-000000-03-30T01:45:00+00:00[UTC]", ]; const instance = new Temporal.Instant(0n); -invalidStrings.forEach((str) => { +invalidStrings.forEach((arg) => { assert.throws( RangeError, - () => instance.equals(str), + () => instance.equals(arg), "reject minus zero as extended year" ); }); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/round/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/round/options-wrong-type.js index 4c334fe9a1ac..711c57f5df21 100644 --- a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/round/options-wrong-type.js +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/round/options-wrong-type.js @@ -1,14 +1,14 @@ // |reftest| skip -- Temporal is not supported -// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// Copyright (C) 2022 Igalia, S.L. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. /*--- esid: sec-temporal.instant.prototype.round -description: TypeError thrown when options argument is missing or a primitive -features: [Symbol, Temporal] +description: TypeError thrown when options argument is missing or a non-string primitive +features: [BigInt, Symbol, Temporal] ---*/ -const values = [ +const badOptions = [ undefined, null, true, @@ -18,9 +18,10 @@ const values = [ ]; const instance = new Temporal.Instant(0n); -assert.throws(TypeError, () => instance.round(), "missing argument"); -for (const value of values) { - assert.throws(TypeError, () => instance.round(value), `argument ${String(value)}`); -} +assert.throws(TypeError, () => instance.round(), "TypeError on missing options argument"); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.round(value), + `TypeError on wrong options type ${typeof value}`); +}; reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/round/rounding-direction.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/round/rounding-direction.js new file mode 100644 index 000000000000..d201aaa4c708 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/round/rounding-direction.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.round +description: Rounding down is towards the Big Bang, not the epoch or 1 BCE +features: [Temporal] +---*/ + +const instance = new Temporal.Instant(-65_261_246_399_500_000_000n); // -000099-12-15T12:00:00.5Z +assert.sameValue( + instance.round({ smallestUnit: "second", roundingMode: "floor" }).epochNanoseconds, + -65_261_246_400_000_000_000n, // -000099-12-15T12:00:00Z + "Rounding down is towards the Big Bang, not the epoch or 1 BCE (roundingMode floor)" +); +assert.sameValue( + instance.round({ smallestUnit: "second", roundingMode: "trunc" }).epochNanoseconds, + -65_261_246_400_000_000_000n, // -000099-12-15T12:00:00Z + "Rounding down is towards the Big Bang, not the epoch or 1 BCE (roundingMode trunc)" +); +assert.sameValue( + instance.round({ smallestUnit: "second", roundingMode: "ceil" }).epochNanoseconds, + -65_261_246_399_000_000_000n, // -000099-12-15T12:00:01Z + "Rounding up is away from the Big Bang, not the epoch or 1 BCE (roundingMode ceil)" +); +assert.sameValue( + instance.round({ smallestUnit: "second", roundingMode: "halfExpand" }).epochNanoseconds, + -65_261_246_399_000_000_000n, // -000099-12-15T12:00:01Z + "Rounding up is away from the Big Bang, not the epoch or 1 BCE (roundingMode halfExpand)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/round/roundto-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/round/roundto-invalid-string.js new file mode 100644 index 000000000000..aef159991907 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/round/roundto-invalid-string.js @@ -0,0 +1,38 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.round +description: RangeError thrown when smallestUnit option not one of the allowed string values +features: [Temporal] +---*/ + +const instant = new Temporal.Instant(1_000_000_000_123_987_500n); +const badValues = [ + "era", + "eraYear", + "year", + "month", + "week", + "day", + "millisecond\0", + "mill\u0131second", + "SECOND", + "eras", + "eraYears", + "years", + "months", + "weeks", + "days", + "milliseconds\0", + "mill\u0131seconds", + "SECONDS", + "other string", +]; +for (const smallestUnit of badValues) { + assert.throws(RangeError, () => instant.round(smallestUnit), + `"${smallestUnit}" is not a valid value for smallest unit`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/round/shell.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/round/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/round/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/round/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/round/smallestunit-disallowed-units.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/round/smallestunit-disallowed-units.js deleted file mode 100644 index 8167be007d6c..000000000000 --- a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/round/smallestunit-disallowed-units.js +++ /dev/null @@ -1,37 +0,0 @@ -// |reftest| skip -- Temporal is not supported -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.instant.prototype.round -description: Specifically disallowed units for the smallestUnit option -features: [Temporal, arrow-function] ----*/ - -const instance = new Temporal.Instant(1_000_000_000_987_654_321n); -const invalidUnits = [ - "era", - "eras", - "year", - "month", - "week", - "years", - "months", - "weeks", - "day", - "days", -]; -invalidUnits.forEach((smallestUnit) => { - assert.throws( - RangeError, - () => instance.round({ smallestUnit }), - `{ smallestUnit: "${smallestUnit}" } should not be allowed as an argument to round` - ); - assert.throws( - RangeError, - () => instance.round(smallestUnit), - `"${smallestUnit}" should not be allowed as an argument to round` - ); -}); - -reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/round/smallestunit-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/round/smallestunit-invalid-string.js index 2da339c56d64..c75fd7fa95db 100644 --- a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/round/smallestunit-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/round/smallestunit-invalid-string.js @@ -9,6 +9,30 @@ features: [Temporal] ---*/ const instant = new Temporal.Instant(1_000_000_000_123_987_500n); -assert.throws(RangeError, () => instant.round({ smallestUnit: "other string" })); +const badValues = [ + "era", + "eraYear", + "year", + "month", + "week", + "day", + "millisecond\0", + "mill\u0131second", + "SECOND", + "eras", + "eraYears", + "years", + "months", + "weeks", + "days", + "milliseconds\0", + "mill\u0131seconds", + "SECONDS", + "other string", +]; +for (const smallestUnit of badValues) { + assert.throws(RangeError, () => instant.round({ smallestUnit }), + `"${smallestUnit}" is not a valid value for smallest unit`); +} reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/since/argument-object-tostring.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/since/argument-object-tostring.js new file mode 100644 index 000000000000..18f819d87a84 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/since/argument-object-tostring.js @@ -0,0 +1,23 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.since +description: Object is converted to a string, then to Temporal.Instant +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Instant(0n); + +const arg = {}; +assert.throws(RangeError, () => instance.since(arg), "[object Object] is not a valid ISO string"); + +arg.toString = function() { + return "1970-01-01T00:00Z"; +}; +const result = instance.since(arg); +TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "result of toString is interpreted as ISO string"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/since/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/since/argument-wrong-type.js new file mode 100644 index 000000000000..4552e010a1d6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/since/argument-wrong-type.js @@ -0,0 +1,40 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.since +description: > + Appropriate error thrown when argument cannot be converted to a valid string + for Instant +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.Instant(0n); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], + [{}, "plain object"], + [Temporal.Instant, "Temporal.Instant, object"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.since(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [Temporal.Instant.prototype, "Temporal.Instant.prototype, object"], // fails brand check in toString() +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.since(arg), `${description} does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/since/instant-string-sub-minute-offset.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/since/instant-string-sub-minute-offset.js new file mode 100644 index 000000000000..0463fff39ab0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/since/instant-string-sub-minute-offset.js @@ -0,0 +1,18 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.since +description: Temporal.Instant string with sub-minute offset +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Instant(0n); + +const str = "1970-01-01T00:19:32.37+00:19:32.37"; +const result = instance.since(str); +TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "if present, sub-minute offset is accepted exactly"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/since/largestunit-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/since/largestunit-invalid-string.js index 1757cfeedbfc..7cb804ea1098 100644 --- a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/since/largestunit-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/since/largestunit-invalid-string.js @@ -10,9 +10,30 @@ features: [Temporal] const earlier = new Temporal.Instant(1_000_000_000_000_000_000n); const later = new Temporal.Instant(1_000_090_061_987_654_321n); -const values = ["era", "eraYear", "years", "months", "weeks", "days", "other string"]; -for (const largestUnit of values) { - assert.throws(RangeError, () => later.since(earlier, { largestUnit })); +const badValues = [ + "era", + "eraYear", + "year", + "month", + "week", + "day", + "millisecond\0", + "mill\u0131second", + "SECOND", + "eras", + "eraYears", + "years", + "months", + "weeks", + "days", + "milliseconds\0", + "mill\u0131seconds", + "SECONDS", + "other string" +]; +for (const largestUnit of badValues) { + assert.throws(RangeError, () => later.since(earlier, { largestUnit }), + `"${largestUnit}" is not a valid value for largestUnit`); } reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/since/leap-second.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/since/leap-second.js new file mode 100644 index 000000000000..5c10384990da --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/since/leap-second.js @@ -0,0 +1,22 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.since +description: Leap second is a valid ISO string for Instant +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Instant(1_483_228_799_000_000_000n); + +const arg = "2016-12-31T23:59:60Z"; +const result = instance.since(arg); +TemporalHelpers.assertDuration( + result, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "leap second is a valid ISO string for Instant" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/since/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/since/options-wrong-type.js new file mode 100644 index 000000000000..bb189545e5f7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/since/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.since +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.Instant(0n); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.since(new Temporal.Instant(3600_000_000_000n), value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/since/shell.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/since/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/since/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/since/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/since/smallestunit-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/since/smallestunit-invalid-string.js index 6f8e163bf989..4687071e9456 100644 --- a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/since/smallestunit-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/since/smallestunit-invalid-string.js @@ -10,9 +10,30 @@ features: [Temporal] const earlier = new Temporal.Instant(1_000_000_000_000_000_000n); const later = new Temporal.Instant(1_000_090_061_987_654_321n); -const values = ["era", "eraYear", "years", "months", "weeks", "days", "other string"]; -for (const smallestUnit of values) { - assert.throws(RangeError, () => later.since(earlier, { smallestUnit })); +const badValues = [ + "era", + "eraYear", + "year", + "month", + "week", + "day", + "millisecond\0", + "mill\u0131second", + "SECOND", + "eras", + "eraYears", + "years", + "months", + "weeks", + "days", + "milliseconds\0", + "mill\u0131seconds", + "SECONDS", + "other string", +]; +for (const smallestUnit of badValues) { + assert.throws(RangeError, () => later.since(earlier, { smallestUnit }), + `"${smallestUnit}" is not a valid value for smallest unit`); } reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/since/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/since/year-zero.js index 8a19b0310fdc..a9680ba62e5a 100644 --- a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/since/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/since/year-zero.js @@ -5,19 +5,19 @@ /*--- esid: sec-temporal.instant.prototype.since description: Negative zero, as an extended year, is rejected -features: [Temporal] +features: [Temporal, arrow-function] ---*/ const invalidStrings = [ - "-000000-03-30T00:45Z", - "-000000-03-30T01:45+01:00", - "-000000-03-30T01:45:00+01:00[UTC]" + "-000000-03-30T00:45Z", + "-000000-03-30T01:45+01:00", + "-000000-03-30T01:45:00+00:00[UTC]", ]; const instance = new Temporal.Instant(0n); -invalidStrings.forEach((str) => { +invalidStrings.forEach((arg) => { assert.throws( RangeError, - () => instance.since(str), + () => instance.since(arg), "reject minus zero as extended year" ); }); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/subtract/shell.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/subtract/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/subtract/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/subtract/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/fractionalseconddigits-auto.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/fractionalseconddigits-auto.js new file mode 100644 index 000000000000..65547075eace --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/fractionalseconddigits-auto.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.tostring +description: auto value for fractionalSecondDigits option +features: [BigInt, Temporal] +---*/ + +const zeroSeconds = new Temporal.Instant(0n); +const wholeSeconds = new Temporal.Instant(30_000_000_000n); +const subSeconds = new Temporal.Instant(30_123_400_000n); + +const tests = [ + [zeroSeconds, "1970-01-01T00:00:00Z"], + [wholeSeconds, "1970-01-01T00:00:30Z"], + [subSeconds, "1970-01-01T00:00:30.1234Z"], +]; + +for (const [instant, expected] of tests) { + assert.sameValue(instant.toString(), expected, "default is to emit seconds and drop trailing zeroes"); + assert.sameValue(instant.toString({ fractionalSecondDigits: "auto" }), expected, "auto is the default"); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/fractionalseconddigits-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/fractionalseconddigits-invalid-string.js index 3e8962aa9cb0..1dfd9097ba72 100644 --- a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/fractionalseconddigits-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/fractionalseconddigits-invalid-string.js @@ -11,12 +11,15 @@ info: | sec-temporal-tosecondsstringprecision step 9: 9. Let _digits_ be ? GetStringOrNumberOption(_normalizedOptions_, *"fractionalSecondDigits"*, « *"auto"* », 0, 9, *"auto"*). sec-temporal.instant.prototype.tostring step 6: - 6. Let _precision_ be ? ToDurationSecondsStringPrecision(_options_). + 6. Let _precision_ be ? ToSecondsStringPrecision(_options_). features: [Temporal] ---*/ const instant = new Temporal.Instant(1_000_000_000_987_650_000n); -assert.throws(RangeError, () => instant.toString({ fractionalSecondDigits: "other string" })); +for (const fractionalSecondDigits of ["other string", "AUTO", "not-auto", "autos", "auto\0"]) { + assert.throws(RangeError, () => instant.toString({ fractionalSecondDigits }), + `"${fractionalSecondDigits}" is not a valid value for fractionalSecondDigits`); +} reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/fractionalseconddigits-non-integer.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/fractionalseconddigits-non-integer.js index ee0d110daedc..30e8619d2a73 100644 --- a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/fractionalseconddigits-non-integer.js +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/fractionalseconddigits-non-integer.js @@ -11,7 +11,7 @@ info: | sec-temporal-tosecondsstringprecision step 9: 9. Let _digits_ be ? GetStringOrNumberOption(_normalizedOptions_, *"fractionalSecondDigits"*, « *"auto"* », 0, 9, *"auto"*). sec-temporal.instant.prototype.tostring step 6: - 6. Let _precision_ be ? ToDurationSecondsStringPrecision(_options_). + 6. Let _precision_ be ? ToSecondsStringPrecision(_options_). features: [Temporal] ---*/ diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/fractionalseconddigits-number.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/fractionalseconddigits-number.js new file mode 100644 index 000000000000..4187d5d52128 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/fractionalseconddigits-number.js @@ -0,0 +1,36 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.tostring +description: Number for fractionalSecondDigits option +features: [BigInt, Temporal] +---*/ + +const zeroSeconds = new Temporal.Instant(0n); +const wholeSeconds = new Temporal.Instant(30_000_000_000n); +const subSeconds = new Temporal.Instant(30_123_400_000n); + +assert.sameValue(subSeconds.toString({ fractionalSecondDigits: 0 }), "1970-01-01T00:00:30Z", + "truncates 4 decimal places to 0"); +assert.sameValue(zeroSeconds.toString({ fractionalSecondDigits: 2 }), "1970-01-01T00:00:00.00Z", + "pads zero seconds to 2 decimal places"); +assert.sameValue(wholeSeconds.toString({ fractionalSecondDigits: 2 }), "1970-01-01T00:00:30.00Z", + "pads whole seconds to 2 decimal places"); +assert.sameValue(subSeconds.toString({ fractionalSecondDigits: 2 }), "1970-01-01T00:00:30.12Z", + "truncates 4 decimal places to 2"); +assert.sameValue(subSeconds.toString({ fractionalSecondDigits: 3 }), "1970-01-01T00:00:30.123Z", + "truncates 4 decimal places to 3"); +assert.sameValue(subSeconds.toString({ fractionalSecondDigits: 6 }), "1970-01-01T00:00:30.123400Z", + "pads 4 decimal places to 6"); +assert.sameValue(zeroSeconds.toString({ fractionalSecondDigits: 7 }), "1970-01-01T00:00:00.0000000Z", + "pads zero seconds to 7 decimal places"); +assert.sameValue(wholeSeconds.toString({ fractionalSecondDigits: 7 }), "1970-01-01T00:00:30.0000000Z", + "pads whole seconds to 7 decimal places"); +assert.sameValue(subSeconds.toString({ fractionalSecondDigits: 7 }), "1970-01-01T00:00:30.1234000Z", + "pads 4 decimal places to 7"); +assert.sameValue(subSeconds.toString({ fractionalSecondDigits: 9 }), "1970-01-01T00:00:30.123400000Z", + "pads 4 decimal places to 9"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/fractionalseconddigits-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/fractionalseconddigits-out-of-range.js index 84ed25e6a228..f06ec18ad41a 100644 --- a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/fractionalseconddigits-out-of-range.js +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/fractionalseconddigits-out-of-range.js @@ -11,15 +11,19 @@ info: | sec-temporal-tosecondsstringprecision step 9: 9. Let _digits_ be ? GetStringOrNumberOption(_normalizedOptions_, *"fractionalSecondDigits"*, « *"auto"* », 0, 9, *"auto"*). sec-temporal.instant.prototype.tostring step 6: - 6. Let _precision_ be ? ToDurationSecondsStringPrecision(_options_). + 6. Let _precision_ be ? ToSecondsStringPrecision(_options_). features: [Temporal] ---*/ const instant = new Temporal.Instant(1_000_000_000_987_650_000n); -assert.throws(RangeError, () => instant.toString({ fractionalSecondDigits: -1 })); -assert.throws(RangeError, () => instant.toString({ fractionalSecondDigits: 10 })); -assert.throws(RangeError, () => instant.toString({ fractionalSecondDigits: -Infinity })); -assert.throws(RangeError, () => instant.toString({ fractionalSecondDigits: Infinity })); +assert.throws(RangeError, () => instant.toString({ fractionalSecondDigits: -Infinity }), + "−∞ is out of range for fractionalSecondDigits"); +assert.throws(RangeError, () => instant.toString({ fractionalSecondDigits: -1 }), + "−1 is out of range for fractionalSecondDigits"); +assert.throws(RangeError, () => instant.toString({ fractionalSecondDigits: 10 }), + "10 is out of range for fractionalSecondDigits"); +assert.throws(RangeError, () => instant.toString({ fractionalSecondDigits: Infinity }), + "∞ is out of range for fractionalSecondDigits"); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/fractionalseconddigits-undefined.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/fractionalseconddigits-undefined.js index 387e0eb514e2..a8fa989e420f 100644 --- a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/fractionalseconddigits-undefined.js +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/fractionalseconddigits-undefined.js @@ -9,20 +9,33 @@ info: | sec-getoption step 3: 3. If _value_ is *undefined*, return _fallback_. sec-getstringornumberoption step 2: - 2. Let _value_ be ? GetOption(_options_, _property_, *"stringOrNumber"*, *undefined*, _fallback_). + 2. Let _value_ be ? GetOption(_options_, _property_, « Number, String », *undefined*, _fallback_). sec-temporal-tosecondsstringprecision step 9: 9. Let _digits_ be ? GetStringOrNumberOption(_normalizedOptions_, *"fractionalSecondDigits"*, « *"auto"* », 0, 9, *"auto"*). sec-temporal.instant.prototype.tostring step 6: - 6. Let _precision_ be ? ToDurationSecondsStringPrecision(_options_). + 6. Let _precision_ be ? ToSecondsStringPrecision(_options_). features: [Temporal] ---*/ -const instant = new Temporal.Instant(1_000_000_000_987_650_000n); +const zeroSeconds = new Temporal.Instant(0n); +const wholeSeconds = new Temporal.Instant(30_000_000_000n); +const subSeconds = new Temporal.Instant(30_123_400_000n); -const explicit = instant.toString({ fractionalSecondDigits: undefined }); -assert.sameValue(explicit, "2001-09-09T01:46:40.98765Z", "default fractionalSecondDigits is auto"); +const tests = [ + [zeroSeconds, "1970-01-01T00:00:00Z"], + [wholeSeconds, "1970-01-01T00:00:30Z"], + [subSeconds, "1970-01-01T00:00:30.1234Z"], +]; -const implicit = instant.toString({}); -assert.sameValue(implicit, "2001-09-09T01:46:40.98765Z", "default fractionalSecondDigits is auto"); +for (const [instant, expected] of tests) { + const explicit = instant.toString({ fractionalSecondDigits: undefined }); + assert.sameValue(explicit, expected, "default fractionalSecondDigits is auto (property present but undefined)"); + + const implicit = instant.toString({}); + assert.sameValue(implicit, expected, "default fractionalSecondDigits is auto (property not present)"); + + const lambda = instant.toString(() => {}); + assert.sameValue(lambda, expected, "default fractionalSecondDigits is auto (property not present, function object)"); +} reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/fractionalseconddigits-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/fractionalseconddigits-wrong-type.js index 7b952de46aa2..12955ab3d697 100644 --- a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/fractionalseconddigits-wrong-type.js +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/fractionalseconddigits-wrong-type.js @@ -23,6 +23,28 @@ features: [Temporal] ---*/ const instant = new Temporal.Instant(1_000_000_000_987_650_000n); -TemporalHelpers.checkFractionalSecondDigitsOptionWrongType(instant); + +assert.throws(RangeError, () => instant.toString({ fractionalSecondDigits: null }), + "null is not a number and converts to the string 'null' which is not valid for fractionalSecondDigits"); +assert.throws(RangeError, () => instant.toString({ fractionalSecondDigits: true }), + "true is not a number and converts to the string 'true' which is not valid for fractionalSecondDigits"); +assert.throws(RangeError, () => instant.toString({ fractionalSecondDigits: false }), + "false is not a number and converts to the string 'false' which is not valid for fractionalSecondDigits"); +assert.throws(TypeError, () => instant.toString({ fractionalSecondDigits: Symbol() }), + "symbols are not numbers and cannot convert to strings"); +assert.throws(RangeError, () => instant.toString({ fractionalSecondDigits: 2n }), + "bigints are not numbers and convert to strings which are not valid for fractionalSecondDigits"); +assert.throws(RangeError, () => instant.toString({ fractionalSecondDigits: {} }), + "plain objects are not numbers and convert to strings which are not valid for fractionalSecondDigits"); + +const expected = [ + "get fractionalSecondDigits.toString", + "call fractionalSecondDigits.toString", +]; +const actual = []; +const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); +const result = instant.toString({ fractionalSecondDigits: observer }); +assert.sameValue(result, "2001-09-09T01:46:40.98765Z", "object with toString uses toString return value"); +assert.compareArray(actual, expected, "object with toString calls toString and not valueOf"); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/options-wrong-type.js new file mode 100644 index 000000000000..269b1d0f09b2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.tostring +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.Instant(0n); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.toString(value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/rounding-cross-midnight.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/rounding-cross-midnight.js new file mode 100644 index 000000000000..b06736487873 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/rounding-cross-midnight.js @@ -0,0 +1,16 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.tostring +description: Rounding can cross midnight +features: [Temporal] +---*/ + +const instant = new Temporal.Instant(946_684_799_999_999_999n); // one nanosecond before 2000-01-01T00:00:00 +for (const roundingMode of ["ceil", "halfExpand"]) { + assert.sameValue(instant.toString({ fractionalSecondDigits: 8, roundingMode }), "2000-01-01T00:00:00.00000000Z"); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/rounding-direction.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/rounding-direction.js new file mode 100644 index 000000000000..263e7ea8b116 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/rounding-direction.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.tostring +description: Rounding down is towards the Big Bang, not the epoch or 1 BCE +features: [Temporal] +---*/ + +const instance = new Temporal.Instant(-65_261_246_399_500_000_000n); // -000099-12-15T12:00:00.5Z +assert.sameValue( + instance.toString({ smallestUnit: "second", roundingMode: "floor" }), + "-000099-12-15T12:00:00Z", + "Rounding down is towards the Big Bang, not the epoch or 1 BCE" +); +assert.sameValue( + instance.toString({ smallestUnit: "second", roundingMode: "trunc" }), + "-000099-12-15T12:00:00Z", + "Rounding down is towards the Big Bang, not the epoch or 1 BCE (roundingMode trunc)" +); +assert.sameValue( + instance.toString({ smallestUnit: "second", roundingMode: "ceil" }), + "-000099-12-15T12:00:01Z", + "Rounding up is away from the Big Bang, not the epoch or 1 BCE (roundingMode ceil)" +); +assert.sameValue( + instance.toString({ smallestUnit: "second", roundingMode: "halfExpand" }), + "-000099-12-15T12:00:01Z", + "Rounding up is away from the Big Bang, not the epoch or 1 BCE (roundingMode halfExpand)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/roundingmode-ceil.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/roundingmode-ceil.js new file mode 100644 index 000000000000..d8f3c46f5b06 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/roundingmode-ceil.js @@ -0,0 +1,40 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.tostring +description: ceil value for roundingMode option +features: [Temporal] +---*/ + +const instant = new Temporal.Instant(1_000_000_000_123_987_500n); + +const result1 = instant.toString({ smallestUnit: "microsecond", roundingMode: "ceil" }); +assert.sameValue(result1, "2001-09-09T01:46:40.123988Z", + "roundingMode is ceil (with 6 digits from smallestUnit)"); + +const result2 = instant.toString({ fractionalSecondDigits: 6, roundingMode: "ceil" }); +assert.sameValue(result2, "2001-09-09T01:46:40.123988Z", + "roundingMode is ceil (with 6 digits from fractionalSecondDigits)"); + +const result3 = instant.toString({ smallestUnit: "millisecond", roundingMode: "ceil" }); +assert.sameValue(result3, "2001-09-09T01:46:40.124Z", + "roundingMode is ceil (with 3 digits from smallestUnit)"); + +const result4 = instant.toString({ fractionalSecondDigits: 3, roundingMode: "ceil" }); +assert.sameValue(result4, "2001-09-09T01:46:40.124Z", + "roundingMode is ceil (with 3 digits from fractionalSecondDigits)"); + +const result5 = instant.toString({ smallestUnit: "second", roundingMode: "ceil" }); +assert.sameValue(result5, "2001-09-09T01:46:41Z", + "roundingMode is ceil (with 0 digits from smallestUnit)"); + +const result6 = instant.toString({ fractionalSecondDigits: 0, roundingMode: "ceil" }); +assert.sameValue(result6, "2001-09-09T01:46:41Z", + "roundingMode is ceil (with 0 digits from fractionalSecondDigits)"); + +const result7 = instant.toString({ smallestUnit: "minute", roundingMode: "ceil" }); +assert.sameValue(result7, "2001-09-09T01:47Z", "roundingMode is ceil (round to minute)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/roundingmode-floor.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/roundingmode-floor.js new file mode 100644 index 000000000000..90f33f89da84 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/roundingmode-floor.js @@ -0,0 +1,40 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.tostring +description: floor value for roundingMode option +features: [Temporal] +---*/ + +const instant = new Temporal.Instant(1_000_000_000_123_987_500n); + +const result1 = instant.toString({ smallestUnit: "microsecond", roundingMode: "floor" }); +assert.sameValue(result1, "2001-09-09T01:46:40.123987Z", + "roundingMode is floor (with 6 digits from smallestUnit)"); + +const result2 = instant.toString({ fractionalSecondDigits: 6, roundingMode: "floor" }); +assert.sameValue(result2, "2001-09-09T01:46:40.123987Z", + "roundingMode is floor (with 6 digits from fractionalSecondDigits)"); + +const result3 = instant.toString({ smallestUnit: "millisecond", roundingMode: "floor" }); +assert.sameValue(result3, "2001-09-09T01:46:40.123Z", + "roundingMode is floor (with 3 digits from smallestUnit)"); + +const result4 = instant.toString({ fractionalSecondDigits: 3, roundingMode: "floor" }); +assert.sameValue(result4, "2001-09-09T01:46:40.123Z", + "roundingMode is floor (with 3 digits from fractionalSecondDigits)"); + +const result5 = instant.toString({ smallestUnit: "second", roundingMode: "floor" }); +assert.sameValue(result5, "2001-09-09T01:46:40Z", + "roundingMode is floor (with 0 digits from smallestUnit)"); + +const result6 = instant.toString({ fractionalSecondDigits: 0, roundingMode: "floor" }); +assert.sameValue(result6, "2001-09-09T01:46:40Z", + "roundingMode is floor (with 0 digits from fractionalSecondDigits)"); + +const result7 = instant.toString({ smallestUnit: "minute", roundingMode: "floor" }); +assert.sameValue(result7, "2001-09-09T01:46Z", "roundingMode is floor (round to minute)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/roundingmode-halfExpand.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/roundingmode-halfExpand.js new file mode 100644 index 000000000000..921bd8b1b010 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/roundingmode-halfExpand.js @@ -0,0 +1,40 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.tostring +description: halfExpand value for roundingMode option +features: [Temporal] +---*/ + +const instant = new Temporal.Instant(1_000_000_000_123_987_500n); + +const result1 = instant.toString({ smallestUnit: "microsecond", roundingMode: "halfExpand" }); +assert.sameValue(result1, "2001-09-09T01:46:40.123988Z", + "roundingMode is halfExpand (with 6 digits from smallestUnit)"); + +const result2 = instant.toString({ fractionalSecondDigits: 6, roundingMode: "halfExpand" }); +assert.sameValue(result2, "2001-09-09T01:46:40.123988Z", + "roundingMode is halfExpand (with 6 digits from fractionalSecondDigits)"); + +const result3 = instant.toString({ smallestUnit: "millisecond", roundingMode: "halfExpand" }); +assert.sameValue(result3, "2001-09-09T01:46:40.124Z", + "roundingMode is halfExpand (with 3 digits from smallestUnit)"); + +const result4 = instant.toString({ fractionalSecondDigits: 3, roundingMode: "halfExpand" }); +assert.sameValue(result4, "2001-09-09T01:46:40.124Z", + "roundingMode is halfExpand (with 3 digits from fractionalSecondDigits)"); + +const result5 = instant.toString({ smallestUnit: "second", roundingMode: "halfExpand" }); +assert.sameValue(result5, "2001-09-09T01:46:40Z", + "roundingMode is halfExpand (with 0 digits from smallestUnit)"); + +const result6 = instant.toString({ fractionalSecondDigits: 0, roundingMode: "halfExpand" }); +assert.sameValue(result6, "2001-09-09T01:46:40Z", + "roundingMode is halfExpand (with 0 digits from fractionalSecondDigits)"); + +const result7 = instant.toString({ smallestUnit: "minute", roundingMode: "halfExpand" }); +assert.sameValue(result7, "2001-09-09T01:47Z", "roundingMode is halfExpand (round to minute)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/roundingmode-trunc.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/roundingmode-trunc.js new file mode 100644 index 000000000000..ed1ee4f07b20 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/roundingmode-trunc.js @@ -0,0 +1,40 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.tostring +description: trunc value for roundingMode option +features: [Temporal] +---*/ + +const instant = new Temporal.Instant(1_000_000_000_123_987_500n); + +const result1 = instant.toString({ smallestUnit: "microsecond", roundingMode: "trunc" }); +assert.sameValue(result1, "2001-09-09T01:46:40.123987Z", + "roundingMode is trunc (with 6 digits from smallestUnit)"); + +const result2 = instant.toString({ fractionalSecondDigits: 6, roundingMode: "trunc" }); +assert.sameValue(result2, "2001-09-09T01:46:40.123987Z", + "roundingMode is trunc (with 6 digits from fractionalSecondDigits)"); + +const result3 = instant.toString({ smallestUnit: "millisecond", roundingMode: "trunc" }); +assert.sameValue(result3, "2001-09-09T01:46:40.123Z", + "roundingMode is trunc (with 3 digits from smallestUnit)"); + +const result4 = instant.toString({ fractionalSecondDigits: 3, roundingMode: "trunc" }); +assert.sameValue(result4, "2001-09-09T01:46:40.123Z", + "roundingMode is trunc (with 3 digits from fractionalSecondDigits)"); + +const result5 = instant.toString({ smallestUnit: "second", roundingMode: "trunc" }); +assert.sameValue(result5, "2001-09-09T01:46:40Z", + "roundingMode is trunc (with 0 digits from smallestUnit)"); + +const result6 = instant.toString({ fractionalSecondDigits: 0, roundingMode: "trunc" }); +assert.sameValue(result6, "2001-09-09T01:46:40Z", + "roundingMode is trunc (with 0 digits from fractionalSecondDigits)"); + +const result7 = instant.toString({ smallestUnit: "minute", roundingMode: "trunc" }); +assert.sameValue(result7, "2001-09-09T01:46Z", "roundingMode is trunc (round to minute)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/shell.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/smallestunit-fractionalseconddigits.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/smallestunit-fractionalseconddigits.js new file mode 100644 index 000000000000..e1d0eef15663 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/smallestunit-fractionalseconddigits.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.tostring +description: fractionalSecondDigits option is not used with smallestUnit present +features: [Temporal] +---*/ + +const instant = new Temporal.Instant(56_789_999_999n); +const tests = [ + ["minute", "1970-01-01T00:00Z"], + ["second", "1970-01-01T00:00:56Z"], + ["millisecond", "1970-01-01T00:00:56.789Z"], + ["microsecond", "1970-01-01T00:00:56.789999Z"], + ["nanosecond", "1970-01-01T00:00:56.789999999Z"], +]; + +for (const [smallestUnit, expected] of tests) { + const string = instant.toString({ + smallestUnit, + get fractionalSecondDigits() { throw new Test262Error("should not get fractionalSecondDigits") } + }); + assert.sameValue(string, expected, `smallestUnit: "${smallestUnit}" overrides fractionalSecondDigits`); +} + +assert.throws(RangeError, () => instant.toString({ + smallestUnit: "hour", + get fractionalSecondDigits() { throw new Test262Error("should not get fractionalSecondDigits") } +}), "hour is an invalid smallestUnit but still overrides fractionalSecondDigits"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/smallestunit-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/smallestunit-invalid-string.js index 7eb4723bf79a..3ac973fa5512 100644 --- a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/smallestunit-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/smallestunit-invalid-string.js @@ -9,6 +9,32 @@ features: [Temporal] ---*/ const instant = new Temporal.Instant(1_000_000_000_123_987_500n); -assert.throws(RangeError, () => instant.toString({ smallestUnit: "other string" })); +const badValues = [ + "era", + "eraYear", + "year", + "month", + "week", + "day", + "hour", + "millisecond\0", + "mill\u0131second", + "SECOND", + "eras", + "eraYears", + "years", + "months", + "weeks", + "days", + "hours", + "milliseconds\0", + "mill\u0131seconds", + "SECONDS", + "other string", +]; +for (const smallestUnit of badValues) { + assert.throws(RangeError, () => instant.toString({ smallestUnit }), + `"${smallestUnit}" is not a valid value for smallest unit`); +} reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/smallestunit-valid-units.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/smallestunit-valid-units.js index ae5f02742229..39a75a542e2e 100644 --- a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/smallestunit-valid-units.js +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/smallestunit-valid-units.js @@ -10,11 +10,36 @@ features: [Temporal] const instant = new Temporal.Instant(1_000_000_000_123_456_789n); -assert.sameValue(instant.toString({ smallestUnit: "minute" }), "2001-09-09T01:46Z"); -assert.sameValue(instant.toString({ smallestUnit: "second" }), "2001-09-09T01:46:40Z"); -assert.sameValue(instant.toString({ smallestUnit: "millisecond" }), "2001-09-09T01:46:40.123Z"); -assert.sameValue(instant.toString({ smallestUnit: "microsecond" }), "2001-09-09T01:46:40.123456Z"); -assert.sameValue(instant.toString({ smallestUnit: "nanosecond" }), "2001-09-09T01:46:40.123456789Z"); +function test(instance, expectations, description) { + for (const [smallestUnit, expectedResult] of expectations) { + assert.sameValue(instance.toString({ smallestUnit }), expectedResult, + `${description} with smallestUnit "${smallestUnit}"`); + } +} + +test( + instant, + [ + ["minute", "2001-09-09T01:46Z"], + ["second", "2001-09-09T01:46:40Z"], + ["millisecond", "2001-09-09T01:46:40.123Z"], + ["microsecond", "2001-09-09T01:46:40.123456Z"], + ["nanosecond", "2001-09-09T01:46:40.123456789Z"], + ], + "subseconds toString" +); + +test( + new Temporal.Instant(999_999_960_000_000_000n), + [ + ["minute", "2001-09-09T01:46Z"], + ["second", "2001-09-09T01:46:00Z"], + ["millisecond", "2001-09-09T01:46:00.000Z"], + ["microsecond", "2001-09-09T01:46:00.000000Z"], + ["nanosecond", "2001-09-09T01:46:00.000000000Z"], + ], + "whole minutes toString" +); const notValid = [ "era", @@ -26,7 +51,8 @@ const notValid = [ ]; notValid.forEach((smallestUnit) => { - assert.throws(RangeError, () => instant.toString({ smallestUnit }), smallestUnit); + assert.throws(RangeError, () => instant.toString({ smallestUnit }), + `"${smallestUnit}" is not a valid unit for the smallestUnit option`); }); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/timezone-string-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/timezone-string-leap-second.js new file mode 100644 index 000000000000..f8c5d4cce2f3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/timezone-string-leap-second.js @@ -0,0 +1,23 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.tostring +description: Leap second is a valid ISO string for TimeZone +features: [Temporal] +---*/ + +const instance = new Temporal.Instant(0n); +let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; + +const result1 = instance.toString({ timeZone }); +assert.sameValue(result1.substr(-6), "+00:00", "leap second is a valid ISO string for TimeZone"); +const result2 = instance.toString({ timeZone: { timeZone } }); +assert.sameValue(result2.substr(-6), "+00:00", "leap second is a valid ISO string for TimeZone (nested property)"); + +timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; +assert.throws(RangeError, () => instance.toString({ timeZone }), "leap second in time zone name not valid"); +assert.throws(RangeError, () => instance.toString({ timeZone: { timeZone } }), "leap second in time zone name not valid (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/timezone-string-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/timezone-string-year-zero.js new file mode 100644 index 000000000000..345be2c5097d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/timezone-string-year-zero.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.tostring +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.Instant(0n); +invalidStrings.forEach((timeZone) => { + assert.throws( + RangeError, + () => instance.toString({ timeZone }), + "reject minus zero as extended year" + ); + assert.throws( + RangeError, + () => instance.toString({ timeZone: { timeZone } }), + "reject minus zero as extended year (nested property)" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/timezone-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/timezone-wrong-type.js new file mode 100644 index 000000000000..a995258b9dc8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toString/timezone-wrong-type.js @@ -0,0 +1,41 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.tostring +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for TimeZone +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.Instant(0n); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], +]; + +for (const [timeZone, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.toString({ timeZone }), `${description} does not convert to a valid ISO string`); + assert.throws(RangeError, () => instance.toString({ timeZone: { timeZone } }), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [timeZone, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.toString({ timeZone }), `${description} is not a valid object and does not convert to a string`); + assert.throws(TypeError, () => instance.toString({ timeZone: { timeZone } }), `${description} is not a valid object and does not convert to a string (nested property)`); +} + +const timeZone = undefined; +assert.throws(RangeError, () => instance.toString({ timeZone: { timeZone } }), `undefined is always a RangeError as nested property`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-number.js new file mode 100644 index 000000000000..d03f0e179ed1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-number.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.tozoneddatetime +description: A number is converted to a string, then to Temporal.Calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Instant(1_000_000_000_000_000_000n); + +const arg = 19761118; + +const result = instance.toZonedDateTime({ calendar: arg, timeZone: "UTC" }); +assert.sameValue(result.calendar.id, "iso8601", "19761118 is a valid ISO string for Calendar"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.toZonedDateTime({ calendar: arg, timeZone: "UTC" }), + `Number ${arg} does not convert to a valid ISO string for Calendar` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-string-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-string-leap-second.js new file mode 100644 index 000000000000..ef6fbf7c825b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-string-leap-second.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.tozoneddatetime +description: Leap second is a valid ISO string for Calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Instant(1_000_000_000_000_000_000n); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.toZonedDateTime({ calendar: arg, timeZone: "UTC" }); +assert.sameValue( + result1.calendar.id, + "iso8601", + "leap second is a valid ISO string for Calendar" +); + +arg = { calendar: "2016-12-31T23:59:60" }; +const result2 = instance.toZonedDateTime({ calendar: arg, timeZone: "UTC" }); +assert.sameValue( + result2.calendar.id, + "iso8601", + "leap second is a valid ISO string for Calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-wrong-type.js new file mode 100644 index 000000000000..fd8184db63be --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toZonedDateTime/calendar-wrong-type.js @@ -0,0 +1,35 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.tozoneddatetime +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for Calendar +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.Instant(1_000_000_000_000_000_000n); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.toZonedDateTime({ calendar: arg, timeZone: "UTC" }), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.toZonedDateTime({ calendar: arg, timeZone: "UTC" }), `${description} is not a valid object and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toZonedDateTime/shell.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toZonedDateTime/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toZonedDateTime/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toZonedDateTime/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-string-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-string-leap-second.js new file mode 100644 index 000000000000..833112b49b86 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-string-leap-second.js @@ -0,0 +1,23 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.tozoneddatetime +description: Leap second is a valid ISO string for TimeZone +features: [Temporal] +---*/ + +const instance = new Temporal.Instant(0n); +let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; + +const result1 = instance.toZonedDateTime({ timeZone, calendar: "iso8601" }); +assert.sameValue(result1.timeZone.id, "UTC", "leap second is a valid ISO string for TimeZone"); +const result2 = instance.toZonedDateTime({ timeZone: { timeZone }, calendar: "iso8601" }); +assert.sameValue(result2.timeZone.id, "UTC", "leap second is a valid ISO string for TimeZone (nested property)"); + +timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; +assert.throws(RangeError, () => instance.toZonedDateTime({ timeZone, calendar: "iso8601" }), "leap second in time zone name not valid"); +assert.throws(RangeError, () => instance.toZonedDateTime({ timeZone: { timeZone }, calendar: "iso8601" }), "leap second in time zone name not valid (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-string-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-string-year-zero.js new file mode 100644 index 000000000000..e51cd6dee881 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-string-year-zero.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.tozoneddatetime +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.Instant(0n); +invalidStrings.forEach((timeZone) => { + assert.throws( + RangeError, + () => instance.toZonedDateTime({ timeZone, calendar: "iso8601" }), + "reject minus zero as extended year" + ); + assert.throws( + RangeError, + () => instance.toZonedDateTime({ timeZone: { timeZone }, calendar: "iso8601" }), + "reject minus zero as extended year (nested property)" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-wrong-type.js new file mode 100644 index 000000000000..c7f2ad95c079 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toZonedDateTime/timezone-wrong-type.js @@ -0,0 +1,41 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.tozoneddatetime +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for TimeZone +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.Instant(0n); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], +]; + +for (const [timeZone, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.toZonedDateTime({ timeZone, calendar: "iso8601" }), `${description} does not convert to a valid ISO string`); + assert.throws(RangeError, () => instance.toZonedDateTime({ timeZone: { timeZone }, calendar: "iso8601" }), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [timeZone, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.toZonedDateTime({ timeZone, calendar: "iso8601" }), `${description} is not a valid object and does not convert to a string`); + assert.throws(TypeError, () => instance.toZonedDateTime({ timeZone: { timeZone }, calendar: "iso8601" }), `${description} is not a valid object and does not convert to a string (nested property)`); +} + +const timeZone = undefined; +assert.throws(RangeError, () => instance.toZonedDateTime({ timeZone: { timeZone }, calendar: "iso8601" }), `undefined is always a RangeError as nested property`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-string-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-string-leap-second.js new file mode 100644 index 000000000000..4a717860aa20 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-string-leap-second.js @@ -0,0 +1,23 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.tozoneddatetimeiso +description: Leap second is a valid ISO string for TimeZone +features: [Temporal] +---*/ + +const instance = new Temporal.Instant(0n); +let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; + +const result1 = instance.toZonedDateTimeISO(timeZone); +assert.sameValue(result1.timeZone.id, "UTC", "leap second is a valid ISO string for TimeZone"); +const result2 = instance.toZonedDateTimeISO({ timeZone }); +assert.sameValue(result2.timeZone.id, "UTC", "leap second is a valid ISO string for TimeZone (nested property)"); + +timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; +assert.throws(RangeError, () => instance.toZonedDateTimeISO(timeZone), "leap second in time zone name not valid"); +assert.throws(RangeError, () => instance.toZonedDateTimeISO({ timeZone }), "leap second in time zone name not valid (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-string-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-string-year-zero.js new file mode 100644 index 000000000000..a1b2a898e621 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-string-year-zero.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.tozoneddatetimeiso +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.Instant(0n); +invalidStrings.forEach((timeZone) => { + assert.throws( + RangeError, + () => instance.toZonedDateTimeISO(timeZone), + "reject minus zero as extended year" + ); + assert.throws( + RangeError, + () => instance.toZonedDateTimeISO({ timeZone }), + "reject minus zero as extended year (nested property)" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-wrong-type.js new file mode 100644 index 000000000000..09438199f865 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/timezone-wrong-type.js @@ -0,0 +1,41 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.tozoneddatetimeiso +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for TimeZone +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.Instant(0n); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], +]; + +for (const [timeZone, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.toZonedDateTimeISO(timeZone), `${description} does not convert to a valid ISO string`); + assert.throws(RangeError, () => instance.toZonedDateTimeISO({ timeZone }), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [timeZone, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.toZonedDateTimeISO(timeZone), `${description} is not a valid object and does not convert to a string`); + assert.throws(TypeError, () => instance.toZonedDateTimeISO({ timeZone }), `${description} is not a valid object and does not convert to a string (nested property)`); +} + +const timeZone = undefined; +assert.throws(RangeError, () => instance.toZonedDateTimeISO({ timeZone }), `undefined is always a RangeError as nested property`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/until/argument-object-tostring.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/until/argument-object-tostring.js new file mode 100644 index 000000000000..db3c0cada385 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/until/argument-object-tostring.js @@ -0,0 +1,23 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.until +description: Object is converted to a string, then to Temporal.Instant +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Instant(0n); + +const arg = {}; +assert.throws(RangeError, () => instance.until(arg), "[object Object] is not a valid ISO string"); + +arg.toString = function() { + return "1970-01-01T00:00Z"; +}; +const result = instance.until(arg); +TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "result of toString is interpreted as ISO string"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/until/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/until/argument-wrong-type.js new file mode 100644 index 000000000000..5415adfea795 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/until/argument-wrong-type.js @@ -0,0 +1,40 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.until +description: > + Appropriate error thrown when argument cannot be converted to a valid string + for Instant +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.Instant(0n); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], + [{}, "plain object"], + [Temporal.Instant, "Temporal.Instant, object"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.until(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [Temporal.Instant.prototype, "Temporal.Instant.prototype, object"], // fails brand check in toString() +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.until(arg), `${description} does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/until/instant-string-sub-minute-offset.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/until/instant-string-sub-minute-offset.js new file mode 100644 index 000000000000..b99bebe6db26 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/until/instant-string-sub-minute-offset.js @@ -0,0 +1,18 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.until +description: Temporal.Instant string with sub-minute offset +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Instant(0n); + +const str = "1970-01-01T00:19:32.37+00:19:32.37"; +const result = instance.until(str); +TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "if present, sub-minute offset is accepted exactly"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/until/largestunit-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/until/largestunit-invalid-string.js index 1abf15f9884b..5bd369057d32 100644 --- a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/until/largestunit-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/until/largestunit-invalid-string.js @@ -10,9 +10,30 @@ features: [Temporal] const earlier = new Temporal.Instant(1_000_000_000_000_000_000n); const later = new Temporal.Instant(1_000_090_061_987_654_321n); -const values = ["era", "eraYear", "years", "months", "weeks", "days", "other string"]; -for (const largestUnit of values) { - assert.throws(RangeError, () => earlier.until(later, { largestUnit })); +const badValues = [ + "era", + "eraYear", + "year", + "month", + "week", + "day", + "millisecond\0", + "mill\u0131second", + "SECOND", + "eras", + "eraYears", + "years", + "months", + "weeks", + "days", + "milliseconds\0", + "mill\u0131seconds", + "SECONDS", + "other string" +]; +for (const largestUnit of badValues) { + assert.throws(RangeError, () => earlier.until(later, { largestUnit }), + `"${largestUnit}" is not a valid value for largestUnit`); } reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/until/leap-second.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/until/leap-second.js new file mode 100644 index 000000000000..65a5806850b8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/until/leap-second.js @@ -0,0 +1,22 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.until +description: Leap second is a valid ISO string for Instant +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Instant(1_483_228_799_000_000_000n); + +const arg = "2016-12-31T23:59:60Z"; +const result = instance.until(arg); +TemporalHelpers.assertDuration( + result, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "leap second is a valid ISO string for Instant" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/until/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/until/options-wrong-type.js new file mode 100644 index 000000000000..19855b4efac9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/until/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.until +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.Instant(0n); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.until(new Temporal.Instant(3600_000_000_000n), value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/until/shell.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/until/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/until/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/until/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/until/smallestunit-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/until/smallestunit-invalid-string.js index d1b250667b51..4a5f37512c43 100644 --- a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/until/smallestunit-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/until/smallestunit-invalid-string.js @@ -10,9 +10,30 @@ features: [Temporal] const earlier = new Temporal.Instant(1_000_000_000_000_000_000n); const later = new Temporal.Instant(1_000_090_061_987_654_321n); -const values = ["era", "eraYear", "years", "months", "weeks", "days", "other string"]; -for (const smallestUnit of values) { - assert.throws(RangeError, () => earlier.until(later, { smallestUnit })); +const badValues = [ + "era", + "eraYear", + "year", + "month", + "week", + "day", + "millisecond\0", + "mill\u0131second", + "SECOND", + "eras", + "eraYears", + "years", + "months", + "weeks", + "days", + "milliseconds\0", + "mill\u0131seconds", + "SECONDS", + "other string", +]; +for (const smallestUnit of badValues) { + assert.throws(RangeError, () => earlier.until(later, { smallestUnit }), + `"${smallestUnit}" is not a valid value for smallest unit`); } reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/until/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/until/year-zero.js index a59c48a7955a..efbfc56dc647 100644 --- a/js/src/tests/test262/built-ins/Temporal/Instant/prototype/until/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/Instant/prototype/until/year-zero.js @@ -5,19 +5,19 @@ /*--- esid: sec-temporal.instant.prototype.until description: Negative zero, as an extended year, is rejected -features: [Temporal] +features: [Temporal, arrow-function] ---*/ const invalidStrings = [ - "-000000-03-30T00:45Z", - "-000000-03-30T01:45+01:00", - "-000000-03-30T01:45:00+01:00[UTC]" + "-000000-03-30T00:45Z", + "-000000-03-30T01:45+01:00", + "-000000-03-30T01:45:00+00:00[UTC]", ]; const instance = new Temporal.Instant(0n); -invalidStrings.forEach((str) => { +invalidStrings.forEach((arg) => { assert.throws( RangeError, - () => instance.until(str), + () => instance.until(arg), "reject minus zero as extended year" ); }); diff --git a/js/src/tests/test262/built-ins/Temporal/Now/plainDate/calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Now/plainDate/calendar-number.js new file mode 100644 index 000000000000..e2d5697d3f88 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Now/plainDate/calendar-number.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.now.plaindate +description: A number is converted to a string, then to Temporal.Calendar +features: [Temporal] +---*/ + +const arg = 19761118; + +const result = Temporal.Now.plainDate(arg); +assert.sameValue(result.calendar.id, "iso8601", "19761118 is a valid ISO string for Calendar"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => Temporal.Now.plainDate(arg), + `Number ${arg} does not convert to a valid ISO string for Calendar` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Now/plainDate/calendar-string-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Now/plainDate/calendar-string-leap-second.js new file mode 100644 index 000000000000..0a89740ddcb7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Now/plainDate/calendar-string-leap-second.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.now.plaindate +description: Leap second is a valid ISO string for Calendar +features: [Temporal] +---*/ + +let arg = "2016-12-31T23:59:60"; +const result1 = Temporal.Now.plainDate(arg); +assert.sameValue( + result1.calendar.id, + "iso8601", + "leap second is a valid ISO string for Calendar" +); + +arg = { calendar: "2016-12-31T23:59:60" }; +const result2 = Temporal.Now.plainDate(arg); +assert.sameValue( + result2.calendar.id, + "iso8601", + "leap second is a valid ISO string for Calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Now/plainDate/calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Now/plainDate/calendar-wrong-type.js new file mode 100644 index 000000000000..cb6c0c66ab20 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Now/plainDate/calendar-wrong-type.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.now.plaindate +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for Calendar +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => Temporal.Now.plainDate(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => Temporal.Now.plainDate(arg), `${description} is not a valid object and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Now/plainDate/shell.js b/js/src/tests/test262/built-ins/Temporal/Now/plainDate/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/built-ins/Temporal/Now/plainDate/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/Now/plainDate/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/Now/plainDate/timezone-string-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Now/plainDate/timezone-string-leap-second.js new file mode 100644 index 000000000000..d138d53db1e7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Now/plainDate/timezone-string-leap-second.js @@ -0,0 +1,23 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.now.plaindate +description: Leap second is a valid ISO string for TimeZone +features: [Temporal] +---*/ + +let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; + +// A string with a leap second is a valid ISO string, so the following two +// operations should not throw + +Temporal.Now.plainDate("iso8601", timeZone); +Temporal.Now.plainDate("iso8601", { timeZone }); + +timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; +assert.throws(RangeError, () => Temporal.Now.plainDate("iso8601", timeZone), "leap second in time zone name not valid"); +assert.throws(RangeError, () => Temporal.Now.plainDate("iso8601", { timeZone }), "leap second in time zone name not valid (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Now/plainDate/timezone-string-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Now/plainDate/timezone-string-year-zero.js new file mode 100644 index 000000000000..b324e0b6121f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Now/plainDate/timezone-string-year-zero.js @@ -0,0 +1,28 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.now.plaindate +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+00:00[UTC]", +]; +invalidStrings.forEach((timeZone) => { + assert.throws( + RangeError, + () => Temporal.Now.plainDate("iso8601", timeZone), + "reject minus zero as extended year" + ); + assert.throws( + RangeError, + () => Temporal.Now.plainDate("iso8601", { timeZone }), + "reject minus zero as extended year (nested property)" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Now/plainDate/timezone-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Now/plainDate/timezone-wrong-type.js new file mode 100644 index 000000000000..5365704d4c19 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Now/plainDate/timezone-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.now.plaindate +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for TimeZone +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], +]; + +for (const [timeZone, description] of rangeErrorTests) { + assert.throws(RangeError, () => Temporal.Now.plainDate("iso8601", timeZone), `${description} does not convert to a valid ISO string`); + assert.throws(RangeError, () => Temporal.Now.plainDate("iso8601", { timeZone }), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [timeZone, description] of typeErrorTests) { + assert.throws(TypeError, () => Temporal.Now.plainDate("iso8601", timeZone), `${description} is not a valid object and does not convert to a string`); + assert.throws(TypeError, () => Temporal.Now.plainDate("iso8601", { timeZone }), `${description} is not a valid object and does not convert to a string (nested property)`); +} + +const timeZone = undefined; +assert.throws(RangeError, () => Temporal.Now.plainDate("iso8601", { timeZone }), `undefined is always a RangeError as nested property`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Now/plainDateISO/shell.js b/js/src/tests/test262/built-ins/Temporal/Now/plainDateISO/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/built-ins/Temporal/Now/plainDateISO/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/Now/plainDateISO/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/Now/plainDateISO/timezone-string-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Now/plainDateISO/timezone-string-leap-second.js new file mode 100644 index 000000000000..ff1e0ac86eaa --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Now/plainDateISO/timezone-string-leap-second.js @@ -0,0 +1,23 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.now.plaindateiso +description: Leap second is a valid ISO string for TimeZone +features: [Temporal] +---*/ + +let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; + +// A string with a leap second is a valid ISO string, so the following two +// operations should not throw + +Temporal.Now.plainDateISO(timeZone); +Temporal.Now.plainDateISO({ timeZone }); + +timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; +assert.throws(RangeError, () => Temporal.Now.plainDateISO(timeZone), "leap second in time zone name not valid"); +assert.throws(RangeError, () => Temporal.Now.plainDateISO({ timeZone }), "leap second in time zone name not valid (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Now/plainDateISO/timezone-string-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Now/plainDateISO/timezone-string-year-zero.js new file mode 100644 index 000000000000..289cd32f3ee9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Now/plainDateISO/timezone-string-year-zero.js @@ -0,0 +1,28 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.now.plaindateiso +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+00:00[UTC]", +]; +invalidStrings.forEach((timeZone) => { + assert.throws( + RangeError, + () => Temporal.Now.plainDateISO(timeZone), + "reject minus zero as extended year" + ); + assert.throws( + RangeError, + () => Temporal.Now.plainDateISO({ timeZone }), + "reject minus zero as extended year (nested property)" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Now/plainDateISO/timezone-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Now/plainDateISO/timezone-wrong-type.js new file mode 100644 index 000000000000..150702d37587 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Now/plainDateISO/timezone-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.now.plaindateiso +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for TimeZone +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], +]; + +for (const [timeZone, description] of rangeErrorTests) { + assert.throws(RangeError, () => Temporal.Now.plainDateISO(timeZone), `${description} does not convert to a valid ISO string`); + assert.throws(RangeError, () => Temporal.Now.plainDateISO({ timeZone }), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [timeZone, description] of typeErrorTests) { + assert.throws(TypeError, () => Temporal.Now.plainDateISO(timeZone), `${description} is not a valid object and does not convert to a string`); + assert.throws(TypeError, () => Temporal.Now.plainDateISO({ timeZone }), `${description} is not a valid object and does not convert to a string (nested property)`); +} + +const timeZone = undefined; +assert.throws(RangeError, () => Temporal.Now.plainDateISO({ timeZone }), `undefined is always a RangeError as nested property`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Now/plainDateTime/calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Now/plainDateTime/calendar-number.js new file mode 100644 index 000000000000..7bc57f668c2c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Now/plainDateTime/calendar-number.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.now.plaindatetime +description: A number is converted to a string, then to Temporal.Calendar +features: [Temporal] +---*/ + +const arg = 19761118; + +const result = Temporal.Now.plainDateTime(arg); +assert.sameValue(result.calendar.id, "iso8601", "19761118 is a valid ISO string for Calendar"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => Temporal.Now.plainDateTime(arg), + `Number ${arg} does not convert to a valid ISO string for Calendar` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Now/plainDateTime/calendar-string-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Now/plainDateTime/calendar-string-leap-second.js new file mode 100644 index 000000000000..bd69b07642de --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Now/plainDateTime/calendar-string-leap-second.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.now.plaindatetime +description: Leap second is a valid ISO string for Calendar +features: [Temporal] +---*/ + +let arg = "2016-12-31T23:59:60"; +const result1 = Temporal.Now.plainDateTime(arg); +assert.sameValue( + result1.calendar.id, + "iso8601", + "leap second is a valid ISO string for Calendar" +); + +arg = { calendar: "2016-12-31T23:59:60" }; +const result2 = Temporal.Now.plainDateTime(arg); +assert.sameValue( + result2.calendar.id, + "iso8601", + "leap second is a valid ISO string for Calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Now/plainDateTime/calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Now/plainDateTime/calendar-wrong-type.js new file mode 100644 index 000000000000..306b8208ff56 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Now/plainDateTime/calendar-wrong-type.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.now.plaindatetime +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for Calendar +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => Temporal.Now.plainDateTime(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => Temporal.Now.plainDateTime(arg), `${description} is not a valid object and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Now/plainDateTime/shell.js b/js/src/tests/test262/built-ins/Temporal/Now/plainDateTime/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/Now/plainDateTime/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/Now/plainDateTime/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/Now/plainDateTime/timezone-string-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Now/plainDateTime/timezone-string-leap-second.js new file mode 100644 index 000000000000..e3affb3914de --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Now/plainDateTime/timezone-string-leap-second.js @@ -0,0 +1,23 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.now.plaindatetime +description: Leap second is a valid ISO string for TimeZone +features: [Temporal] +---*/ + +let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; + +// A string with a leap second is a valid ISO string, so the following two +// operations should not throw + +Temporal.Now.plainDateTime("iso8601", timeZone); +Temporal.Now.plainDateTime("iso8601", { timeZone }); + +timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; +assert.throws(RangeError, () => Temporal.Now.plainDateTime("iso8601", timeZone), "leap second in time zone name not valid"); +assert.throws(RangeError, () => Temporal.Now.plainDateTime("iso8601", { timeZone }), "leap second in time zone name not valid (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Now/plainDateTime/timezone-string-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Now/plainDateTime/timezone-string-year-zero.js new file mode 100644 index 000000000000..0b4561b5d774 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Now/plainDateTime/timezone-string-year-zero.js @@ -0,0 +1,28 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.now.plaindatetime +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+00:00[UTC]", +]; +invalidStrings.forEach((timeZone) => { + assert.throws( + RangeError, + () => Temporal.Now.plainDateTime("iso8601", timeZone), + "reject minus zero as extended year" + ); + assert.throws( + RangeError, + () => Temporal.Now.plainDateTime("iso8601", { timeZone }), + "reject minus zero as extended year (nested property)" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Now/plainDateTime/timezone-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Now/plainDateTime/timezone-wrong-type.js new file mode 100644 index 000000000000..8e23d880ddad --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Now/plainDateTime/timezone-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.now.plaindatetime +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for TimeZone +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], +]; + +for (const [timeZone, description] of rangeErrorTests) { + assert.throws(RangeError, () => Temporal.Now.plainDateTime("iso8601", timeZone), `${description} does not convert to a valid ISO string`); + assert.throws(RangeError, () => Temporal.Now.plainDateTime("iso8601", { timeZone }), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [timeZone, description] of typeErrorTests) { + assert.throws(TypeError, () => Temporal.Now.plainDateTime("iso8601", timeZone), `${description} is not a valid object and does not convert to a string`); + assert.throws(TypeError, () => Temporal.Now.plainDateTime("iso8601", { timeZone }), `${description} is not a valid object and does not convert to a string (nested property)`); +} + +const timeZone = undefined; +assert.throws(RangeError, () => Temporal.Now.plainDateTime("iso8601", { timeZone }), `undefined is always a RangeError as nested property`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Now/plainDateTimeISO/shell.js b/js/src/tests/test262/built-ins/Temporal/Now/plainDateTimeISO/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/Now/plainDateTimeISO/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/Now/plainDateTimeISO/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/Now/plainDateTimeISO/timezone-string-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Now/plainDateTimeISO/timezone-string-leap-second.js new file mode 100644 index 000000000000..421155c7bfd9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Now/plainDateTimeISO/timezone-string-leap-second.js @@ -0,0 +1,23 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.now.plaindatetimeiso +description: Leap second is a valid ISO string for TimeZone +features: [Temporal] +---*/ + +let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; + +// A string with a leap second is a valid ISO string, so the following two +// operations should not throw + +Temporal.Now.plainDateTimeISO(timeZone); +Temporal.Now.plainDateTimeISO({ timeZone }); + +timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; +assert.throws(RangeError, () => Temporal.Now.plainDateTimeISO(timeZone), "leap second in time zone name not valid"); +assert.throws(RangeError, () => Temporal.Now.plainDateTimeISO({ timeZone }), "leap second in time zone name not valid (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Now/plainDateTimeISO/timezone-string-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Now/plainDateTimeISO/timezone-string-year-zero.js new file mode 100644 index 000000000000..e67086f627ab --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Now/plainDateTimeISO/timezone-string-year-zero.js @@ -0,0 +1,28 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.now.plaindatetimeiso +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+00:00[UTC]", +]; +invalidStrings.forEach((timeZone) => { + assert.throws( + RangeError, + () => Temporal.Now.plainDateTimeISO(timeZone), + "reject minus zero as extended year" + ); + assert.throws( + RangeError, + () => Temporal.Now.plainDateTimeISO({ timeZone }), + "reject minus zero as extended year (nested property)" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Now/plainDateTimeISO/timezone-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Now/plainDateTimeISO/timezone-wrong-type.js new file mode 100644 index 000000000000..0ce95adafdb8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Now/plainDateTimeISO/timezone-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.now.plaindatetimeiso +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for TimeZone +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], +]; + +for (const [timeZone, description] of rangeErrorTests) { + assert.throws(RangeError, () => Temporal.Now.plainDateTimeISO(timeZone), `${description} does not convert to a valid ISO string`); + assert.throws(RangeError, () => Temporal.Now.plainDateTimeISO({ timeZone }), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [timeZone, description] of typeErrorTests) { + assert.throws(TypeError, () => Temporal.Now.plainDateTimeISO(timeZone), `${description} is not a valid object and does not convert to a string`); + assert.throws(TypeError, () => Temporal.Now.plainDateTimeISO({ timeZone }), `${description} is not a valid object and does not convert to a string (nested property)`); +} + +const timeZone = undefined; +assert.throws(RangeError, () => Temporal.Now.plainDateTimeISO({ timeZone }), `undefined is always a RangeError as nested property`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Now/plainTimeISO/shell.js b/js/src/tests/test262/built-ins/Temporal/Now/plainTimeISO/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/built-ins/Temporal/Now/plainTimeISO/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/Now/plainTimeISO/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/Now/plainTimeISO/timezone-string-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Now/plainTimeISO/timezone-string-leap-second.js new file mode 100644 index 000000000000..4da2a706b745 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Now/plainTimeISO/timezone-string-leap-second.js @@ -0,0 +1,23 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.now.plaintimeiso +description: Leap second is a valid ISO string for TimeZone +features: [Temporal] +---*/ + +let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; + +// A string with a leap second is a valid ISO string, so the following two +// operations should not throw + +Temporal.Now.plainTimeISO(timeZone); +Temporal.Now.plainTimeISO({ timeZone }); + +timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; +assert.throws(RangeError, () => Temporal.Now.plainTimeISO(timeZone), "leap second in time zone name not valid"); +assert.throws(RangeError, () => Temporal.Now.plainTimeISO({ timeZone }), "leap second in time zone name not valid (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Now/plainTimeISO/timezone-string-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Now/plainTimeISO/timezone-string-year-zero.js new file mode 100644 index 000000000000..fa43f3aa24b1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Now/plainTimeISO/timezone-string-year-zero.js @@ -0,0 +1,28 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.now.plaintimeiso +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+00:00[UTC]", +]; +invalidStrings.forEach((timeZone) => { + assert.throws( + RangeError, + () => Temporal.Now.plainTimeISO(timeZone), + "reject minus zero as extended year" + ); + assert.throws( + RangeError, + () => Temporal.Now.plainTimeISO({ timeZone }), + "reject minus zero as extended year (nested property)" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Now/plainTimeISO/timezone-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Now/plainTimeISO/timezone-wrong-type.js new file mode 100644 index 000000000000..e05a8dacb04e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Now/plainTimeISO/timezone-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.now.plaintimeiso +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for TimeZone +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], +]; + +for (const [timeZone, description] of rangeErrorTests) { + assert.throws(RangeError, () => Temporal.Now.plainTimeISO(timeZone), `${description} does not convert to a valid ISO string`); + assert.throws(RangeError, () => Temporal.Now.plainTimeISO({ timeZone }), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [timeZone, description] of typeErrorTests) { + assert.throws(TypeError, () => Temporal.Now.plainTimeISO(timeZone), `${description} is not a valid object and does not convert to a string`); + assert.throws(TypeError, () => Temporal.Now.plainTimeISO({ timeZone }), `${description} is not a valid object and does not convert to a string (nested property)`); +} + +const timeZone = undefined; +assert.throws(RangeError, () => Temporal.Now.plainTimeISO({ timeZone }), `undefined is always a RangeError as nested property`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Now/zonedDateTime/calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Now/zonedDateTime/calendar-number.js new file mode 100644 index 000000000000..6e563c9e35f5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Now/zonedDateTime/calendar-number.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.now.zoneddatetime +description: A number is converted to a string, then to Temporal.Calendar +features: [Temporal] +---*/ + +const arg = 19761118; + +const result = Temporal.Now.zonedDateTime(arg); +assert.sameValue(result.calendar.id, "iso8601", "19761118 is a valid ISO string for Calendar"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => Temporal.Now.zonedDateTime(arg), + `Number ${arg} does not convert to a valid ISO string for Calendar` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Now/zonedDateTime/calendar-string-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Now/zonedDateTime/calendar-string-leap-second.js new file mode 100644 index 000000000000..be5d697680f2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Now/zonedDateTime/calendar-string-leap-second.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.now.zoneddatetime +description: Leap second is a valid ISO string for Calendar +features: [Temporal] +---*/ + +let arg = "2016-12-31T23:59:60"; +const result1 = Temporal.Now.zonedDateTime(arg); +assert.sameValue( + result1.calendar.id, + "iso8601", + "leap second is a valid ISO string for Calendar" +); + +arg = { calendar: "2016-12-31T23:59:60" }; +const result2 = Temporal.Now.zonedDateTime(arg); +assert.sameValue( + result2.calendar.id, + "iso8601", + "leap second is a valid ISO string for Calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Now/zonedDateTime/calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Now/zonedDateTime/calendar-wrong-type.js new file mode 100644 index 000000000000..4cf2764313ec --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Now/zonedDateTime/calendar-wrong-type.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.now.zoneddatetime +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for Calendar +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => Temporal.Now.zonedDateTime(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => Temporal.Now.zonedDateTime(arg), `${description} is not a valid object and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Now/zonedDateTime/shell.js b/js/src/tests/test262/built-ins/Temporal/Now/zonedDateTime/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/Now/zonedDateTime/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/Now/zonedDateTime/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/Now/zonedDateTime/timezone-string-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Now/zonedDateTime/timezone-string-leap-second.js new file mode 100644 index 000000000000..7bbf3da56b53 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Now/zonedDateTime/timezone-string-leap-second.js @@ -0,0 +1,22 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.now.zoneddatetime +description: Leap second is a valid ISO string for TimeZone +features: [Temporal] +---*/ + +let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; + +const result1 = Temporal.Now.zonedDateTime("iso8601", timeZone); +assert.sameValue(result1.timeZone.id, "UTC", "leap second is a valid ISO string for TimeZone"); +const result2 = Temporal.Now.zonedDateTime("iso8601", { timeZone }); +assert.sameValue(result2.timeZone.id, "UTC", "leap second is a valid ISO string for TimeZone (nested property)"); + +timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; +assert.throws(RangeError, () => Temporal.Now.zonedDateTime("iso8601", timeZone), "leap second in time zone name not valid"); +assert.throws(RangeError, () => Temporal.Now.zonedDateTime("iso8601", { timeZone }), "leap second in time zone name not valid (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Now/zonedDateTime/timezone-string-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Now/zonedDateTime/timezone-string-year-zero.js new file mode 100644 index 000000000000..c416717e6494 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Now/zonedDateTime/timezone-string-year-zero.js @@ -0,0 +1,28 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.now.zoneddatetime +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+00:00[UTC]", +]; +invalidStrings.forEach((timeZone) => { + assert.throws( + RangeError, + () => Temporal.Now.zonedDateTime("iso8601", timeZone), + "reject minus zero as extended year" + ); + assert.throws( + RangeError, + () => Temporal.Now.zonedDateTime("iso8601", { timeZone }), + "reject minus zero as extended year (nested property)" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Now/zonedDateTime/timezone-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Now/zonedDateTime/timezone-wrong-type.js new file mode 100644 index 000000000000..3fd6ce2e4c36 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Now/zonedDateTime/timezone-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.now.zoneddatetime +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for TimeZone +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], +]; + +for (const [timeZone, description] of rangeErrorTests) { + assert.throws(RangeError, () => Temporal.Now.zonedDateTime("iso8601", timeZone), `${description} does not convert to a valid ISO string`); + assert.throws(RangeError, () => Temporal.Now.zonedDateTime("iso8601", { timeZone }), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [timeZone, description] of typeErrorTests) { + assert.throws(TypeError, () => Temporal.Now.zonedDateTime("iso8601", timeZone), `${description} is not a valid object and does not convert to a string`); + assert.throws(TypeError, () => Temporal.Now.zonedDateTime("iso8601", { timeZone }), `${description} is not a valid object and does not convert to a string (nested property)`); +} + +const timeZone = undefined; +assert.throws(RangeError, () => Temporal.Now.zonedDateTime("iso8601", { timeZone }), `undefined is always a RangeError as nested property`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Now/zonedDateTimeISO/timezone-string-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Now/zonedDateTimeISO/timezone-string-leap-second.js new file mode 100644 index 000000000000..c9dc1a225797 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Now/zonedDateTimeISO/timezone-string-leap-second.js @@ -0,0 +1,22 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.now.zoneddatetimeiso +description: Leap second is a valid ISO string for TimeZone +features: [Temporal] +---*/ + +let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; + +const result1 = Temporal.Now.zonedDateTimeISO(timeZone); +assert.sameValue(result1.timeZone.id, "UTC", "leap second is a valid ISO string for TimeZone"); +const result2 = Temporal.Now.zonedDateTimeISO({ timeZone }); +assert.sameValue(result2.timeZone.id, "UTC", "leap second is a valid ISO string for TimeZone (nested property)"); + +timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; +assert.throws(RangeError, () => Temporal.Now.zonedDateTimeISO(timeZone), "leap second in time zone name not valid"); +assert.throws(RangeError, () => Temporal.Now.zonedDateTimeISO({ timeZone }), "leap second in time zone name not valid (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Now/zonedDateTimeISO/timezone-string-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Now/zonedDateTimeISO/timezone-string-year-zero.js new file mode 100644 index 000000000000..e0ab9c2cdaeb --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Now/zonedDateTimeISO/timezone-string-year-zero.js @@ -0,0 +1,28 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.now.zoneddatetimeiso +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+00:00[UTC]", +]; +invalidStrings.forEach((timeZone) => { + assert.throws( + RangeError, + () => Temporal.Now.zonedDateTimeISO(timeZone), + "reject minus zero as extended year" + ); + assert.throws( + RangeError, + () => Temporal.Now.zonedDateTimeISO({ timeZone }), + "reject minus zero as extended year (nested property)" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/Now/zonedDateTimeISO/timezone-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Now/zonedDateTimeISO/timezone-wrong-type.js new file mode 100644 index 000000000000..c4840ae2cb8b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/Now/zonedDateTimeISO/timezone-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.now.zoneddatetimeiso +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for TimeZone +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], +]; + +for (const [timeZone, description] of rangeErrorTests) { + assert.throws(RangeError, () => Temporal.Now.zonedDateTimeISO(timeZone), `${description} does not convert to a valid ISO string`); + assert.throws(RangeError, () => Temporal.Now.zonedDateTimeISO({ timeZone }), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [timeZone, description] of typeErrorTests) { + assert.throws(TypeError, () => Temporal.Now.zonedDateTimeISO(timeZone), `${description} is not a valid object and does not convert to a string`); + assert.throws(TypeError, () => Temporal.Now.zonedDateTimeISO({ timeZone }), `${description} is not a valid object and does not convert to a string (nested property)`); +} + +const timeZone = undefined; +assert.throws(RangeError, () => Temporal.Now.zonedDateTimeISO({ timeZone }), `undefined is always a RangeError as nested property`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/calendar-number.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/calendar-number.js new file mode 100644 index 000000000000..efd1641d84cc --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/calendar-number.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate +description: A number is converted to a string, then to Temporal.Calendar +features: [Temporal] +---*/ + +const arg = 19761118; + +const result = new Temporal.PlainDate(2000, 5, 2, arg); +assert.sameValue(result.calendar.id, "iso8601", "19761118 is a valid ISO string for Calendar"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => new Temporal.PlainDate(2000, 5, 2, arg), + `Number ${arg} does not convert to a valid ISO string for Calendar` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/calendar-wrong-type.js new file mode 100644 index 000000000000..30f97a7b75bd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/calendar-wrong-type.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for Calendar +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => new Temporal.PlainDate(2000, 5, 2, arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => new Temporal.PlainDate(2000, 5, 2, arg), `${description} is not a valid object and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/compare/argument-number.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/compare/argument-number.js new file mode 100644 index 000000000000..8557b2e57eb3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/compare/argument-number.js @@ -0,0 +1,37 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.compare +description: A number is converted to a string, then to Temporal.PlainDate +features: [Temporal] +---*/ + +const arg = 19761118; + +const result1 = Temporal.PlainDate.compare(arg, new Temporal.PlainDate(1976, 11, 18)); +assert.sameValue(result1, 0, "19761118 is a valid ISO string for PlainDate (first argument)"); +const result2 = Temporal.PlainDate.compare(new Temporal.PlainDate(1976, 11, 18), arg); +assert.sameValue(result2, 0, "19761118 is a valid ISO string for PlainDate (second argument)"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => Temporal.PlainDate.compare(arg, new Temporal.PlainDate(1976, 11, 18)), + `Number ${arg} does not convert to a valid ISO string for PlainDate (first argument)` + ); + assert.throws( + RangeError, + () => Temporal.PlainDate.compare(new Temporal.PlainDate(1976, 11, 18), arg), + `Number ${arg} does not convert to a valid ISO string for PlainDate (second argument)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..cab3ddb44573 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,25 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.compare +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = Temporal.PlainDate.compare(arg, new Temporal.PlainDate(1976, 11, 18)); +assert.sameValue(result1, 0, "leap second is a valid ISO string for calendar (first argument)"); +const result2 = Temporal.PlainDate.compare(new Temporal.PlainDate(1976, 11, 18), arg); +assert.sameValue(result2, 0, "leap second is a valid ISO string for calendar (first argument)"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result3 = Temporal.PlainDate.compare(arg, new Temporal.PlainDate(1976, 11, 18)); +assert.sameValue(result3, 0, "leap second is a valid ISO string for calendar (nested property, first argument)"); +const result4 = Temporal.PlainDate.compare(new Temporal.PlainDate(1976, 11, 18), arg); +assert.sameValue(result4, 0, "leap second is a valid ISO string for calendar (nested property, second argument)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..e5a8d416cc48 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-number.js @@ -0,0 +1,56 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.compare +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = Temporal.PlainDate.compare(arg, new Temporal.PlainDate(1976, 11, 18)); +assert.sameValue(result1, 0, "19970327 is a valid ISO string for calendar (first argument)"); +const result2 = Temporal.PlainDate.compare(new Temporal.PlainDate(1976, 11, 18), arg); +assert.sameValue(result2, 0, "19970327 is a valid ISO string for calendar (first argument)"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result3 = Temporal.PlainDate.compare(arg, new Temporal.PlainDate(1976, 11, 18)); +assert.sameValue(result3, 0, "19970327 is a valid ISO string for calendar (nested property, first argument)"); +const result4 = Temporal.PlainDate.compare(new Temporal.PlainDate(1976, 11, 18), arg); +assert.sameValue(result4, 0, "19970327 is a valid ISO string for calendar (nested property, first argument)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + assert.throws( + RangeError, + () => Temporal.PlainDate.compare(arg, new Temporal.PlainDate(1976, 11, 18)), + `Number ${calendar} does not convert to a valid ISO string for calendar (first argument)` + ); + assert.throws( + RangeError, + () => Temporal.PlainDate.compare(new Temporal.PlainDate(1976, 11, 18), arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (second argument)` + ); + arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; + assert.throws( + RangeError, + () => Temporal.PlainDate.compare(arg, new Temporal.PlainDate(1976, 11, 18)), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property, first argument)` + ); + assert.throws( + RangeError, + () => Temporal.PlainDate.compare(new Temporal.PlainDate(1976, 11, 18), arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property, second argument)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..a44067f8d2e0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,52 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.compare +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => Temporal.PlainDate.compare(arg, new Temporal.PlainDate(1976, 11, 18)), `${description} does not convert to a valid ISO string (first argument)`); + assert.throws(RangeError, () => Temporal.PlainDate.compare(new Temporal.PlainDate(1976, 11, 18), arg), `${description} does not convert to a valid ISO string (second argument)`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => Temporal.PlainDate.compare(arg, new Temporal.PlainDate(1976, 11, 18)), `${description} does not convert to a valid ISO string (nested property, first argument)`); + assert.throws(RangeError, () => Temporal.PlainDate.compare(new Temporal.PlainDate(1976, 11, 18), arg), `${description} does not convert to a valid ISO string (nested property, second argument)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => Temporal.PlainDate.compare(arg, new Temporal.PlainDate(1976, 11, 18)), `${description} is not a valid property bag and does not convert to a string (first argument)`); + assert.throws(TypeError, () => Temporal.PlainDate.compare(new Temporal.PlainDate(1976, 11, 18), arg), `${description} is not a valid property bag and does not convert to a string (second argument)`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => Temporal.PlainDate.compare(arg, new Temporal.PlainDate(1976, 11, 18)), `${description} is not a valid property bag and does not convert to a string (nested property, first argument)`); + assert.throws(TypeError, () => Temporal.PlainDate.compare(new Temporal.PlainDate(1976, 11, 18), arg), `${description} is not a valid property bag and does not convert to a string (nested property, second argument)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => Temporal.PlainDate.compare(arg, new Temporal.PlainDate(1976, 11, 18)), `nested undefined calendar property is always a RangeError (first argument)`); +assert.throws(RangeError, () => Temporal.PlainDate.compare(new Temporal.PlainDate(1976, 11, 18), arg), `nested undefined calendar property is always a RangeError (second argument)`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..2c18317f3336 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/compare/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.compare +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; + +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => Temporal.PlainDate.compare(arg, new Temporal.PlainDate(1976, 11, 18)), + "reject minus zero as extended year (first argument)" + ); + assert.throws( + RangeError, + () => Temporal.PlainDate.compare(new Temporal.PlainDate(1976, 11, 18), arg), + "reject minus zero as extended year (second argument)" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/compare/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/compare/argument-wrong-type.js new file mode 100644 index 000000000000..1c12d974c431 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/compare/argument-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.compare +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => Temporal.PlainDate.compare(arg, new Temporal.PlainDate(1976, 11, 18)), `${description} does not convert to a valid ISO string (first argument)`); + assert.throws(RangeError, () => Temporal.PlainDate.compare(new Temporal.PlainDate(1976, 11, 18), arg), `${description} does not convert to a valid ISO string (second argument)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => Temporal.PlainDate.compare(arg, new Temporal.PlainDate(1976, 11, 18)), `${description} is not a valid property bag and does not convert to a string (first argument)`); + assert.throws(TypeError, () => Temporal.PlainDate.compare(new Temporal.PlainDate(1976, 11, 18), arg), `${description} is not a valid property bag and does not convert to a string (second argument)`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/compare/leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/compare/leap-second.js new file mode 100644 index 000000000000..1d4807f7de05 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/compare/leap-second.js @@ -0,0 +1,23 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.compare +description: Leap second is a valid ISO string for PlainDate +features: [Temporal] +---*/ + +let arg = "2016-12-31T23:59:60"; +let result = Temporal.PlainDate.compare(arg, new Temporal.PlainDate(2016, 12, 31)); +assert.sameValue(result, 0, "leap second is a valid ISO string for PlainDate (first argument)"); +result = Temporal.PlainDate.compare(new Temporal.PlainDate(2016, 12, 31), arg); +assert.sameValue(result, 0, "leap second is a valid ISO string for PlainDate (second argument)"); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +result = Temporal.PlainDate.compare(arg, new Temporal.PlainDate(2016, 12, 31)); +assert.sameValue(result, 0, "second: 60 is ignored in property bag for PlainDate (first argument)"); +result = Temporal.PlainDate.compare(new Temporal.PlainDate(2016, 12, 31), arg); +assert.sameValue(result, 0, "second: 60 is ignored in property bag for PlainDate (second argument)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/compare/year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/compare/year-zero.js index 864f12679de8..7c6f99506bd9 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDate/compare/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/compare/year-zero.js @@ -9,16 +9,23 @@ features: [Temporal] ---*/ const instance = new Temporal.PlainDate(2000, 5, 2); -const bad = "-000000-08-24"; +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; -assert.throws(RangeError, - () => Temporal.PlainDate.compare(bad, instance), - "Minus zero is an invalid extended year (first argument)" -); +invalidStrings.forEach((arg) => { + assert.throws(RangeError, + () => Temporal.PlainDate.compare(arg, instance), + "Minus zero is an invalid extended year (first argument)" + ); -assert.throws(RangeError, - () => Temporal.PlainDate.compare(instance, bad), - "Minus zero is an invalid extended year (second argument)" -); + assert.throws(RangeError, + () => Temporal.PlainDate.compare(instance, arg), + "Minus zero is an invalid extended year (second argument)" + ); +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/from/argument-number.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/from/argument-number.js index 50f5a7420018..a917b595e614 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDate/from/argument-number.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/from/argument-number.js @@ -4,12 +4,28 @@ /*--- esid: sec-temporal.plaindate.from -description: various interesting string arguments. +description: A number is converted to a string, then to Temporal.PlainDate includes: [temporalHelpers.js] features: [Temporal] ---*/ -const result = Temporal.PlainDate.from(19761118); -TemporalHelpers.assertPlainDate(result, 1976, 11, "M11", 18); +const arg = 19761118; + +const result = Temporal.PlainDate.from(arg); +TemporalHelpers.assertPlainDate(result, 1976, 11, "M11", 18, "19761118 is a valid ISO string for PlainDate"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => Temporal.PlainDate.from(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDate` + ); +} reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/from/argument-plaindate.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/from/argument-plaindate.js index d04a718f7568..cb9dcd88e247 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDate/from/argument-plaindate.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/from/argument-plaindate.js @@ -5,13 +5,23 @@ /*--- esid: sec-temporal.plaindate.from description: A PlainDate object is copied, not returned directly -includes: [compareArray.js, temporalHelpers.js] +includes: [temporalHelpers.js] features: [Temporal] ---*/ -const plainDate = new Temporal.PlainDate(2000, 5, 2); -const result = Temporal.PlainDate.from(plainDate); -assert.notSameValue(result, plainDate); -TemporalHelpers.assertPlainDate(result, 2000, 5, "M05", 2); +const orig = new Temporal.PlainDate(2000, 5, 2); +const result = Temporal.PlainDate.from(orig); + +TemporalHelpers.assertPlainDate( + result, + 2000, 5, "M05", 2, + "PlainDate is copied" +); + +assert.notSameValue( + result, + orig, + "When a PlainDate is given, the returned value is not the original PlainDate" +); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..a066c471bf1e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.from +description: Leap second is a valid ISO string for a calendar in a property bag +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = Temporal.PlainDate.from(arg); +TemporalHelpers.assertPlainDate( + result1, + 1976, 11, "M11", 18, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = Temporal.PlainDate.from(arg); +TemporalHelpers.assertPlainDate( + result2, + 1976, 11, "M11", 18, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..6d4888de988a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-number.js @@ -0,0 +1,43 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.from +description: A number as calendar in a property bag is converted to a string, then to a calendar +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = Temporal.PlainDate.from(arg); +TemporalHelpers.assertPlainDate(result1, 1976, 11, "M11", 18, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = Temporal.PlainDate.from(arg); +TemporalHelpers.assertPlainDate(result2, 1976, 11, "M11", 18, "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + assert.throws( + RangeError, + () => Temporal.PlainDate.from(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; + assert.throws( + RangeError, + () => Temporal.PlainDate.from(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..6ec7900fd03e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,47 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.from +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => Temporal.PlainDate.from(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => Temporal.PlainDate.from(arg), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => Temporal.PlainDate.from(arg), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => Temporal.PlainDate.from(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => Temporal.PlainDate.from(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..b85d4b931f70 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/from/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.from +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; + +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => Temporal.PlainDate.from(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/from/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/from/argument-wrong-type.js new file mode 100644 index 000000000000..0c1a35778788 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/from/argument-wrong-type.js @@ -0,0 +1,37 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.from +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => Temporal.PlainDate.from(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => Temporal.PlainDate.from(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/from/leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/from/leap-second.js new file mode 100644 index 000000000000..847239acf9fd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/from/leap-second.js @@ -0,0 +1,44 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.from +description: Leap second is a valid ISO string for PlainDate +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +let arg = "2016-12-31T23:59:60"; + +const result1 = Temporal.PlainDate.from(arg); +TemporalHelpers.assertPlainDate( + result1, + 2016, 12, "M12", 31, + "leap second is a valid ISO string for PlainDate" +); + +const result2 = Temporal.PlainDate.from(arg, { overflow: "reject" }); +TemporalHelpers.assertPlainDate( + result2, + 2016, 12, "M12", 31, + "leap second is a valid ISO string for PlainDate" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; + +const result3 = Temporal.PlainDate.from(arg); +TemporalHelpers.assertPlainDate( + result3, + 2016, 12, "M12", 31, + "second: 60 is ignored in property bag for PlainDate" +); + +const result4 = Temporal.PlainDate.from(arg, { overflow: "reject" }); +TemporalHelpers.assertPlainDate( + result4, + 2016, 12, "M12", 31, + "second: 60 is ignored in property bag for PlainDate even with overflow: reject" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/from/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/from/options-wrong-type.js new file mode 100644 index 000000000000..0b78758962cd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/from/options-wrong-type.js @@ -0,0 +1,25 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.from +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +for (const value of badOptions) { + assert.throws(TypeError, () => Temporal.PlainDate.from({ year: 1976, month: 11, day: 18 }, value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/from/year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/from/year-zero.js index 6e671898cbb7..68aaab8e3e81 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDate/from/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/from/year-zero.js @@ -5,16 +5,22 @@ /*--- esid: sec-temporal.plaindate.from description: Negative zero, as an extended year, is rejected -features: [Temporal] +features: [Temporal, arrow-function] ---*/ -const arg = "-000000-10-31"; +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; -assert.throws( +invalidStrings.forEach((arg) => { + assert.throws( RangeError, - () => { Temporal.PlainDate.from(arg); }, + () => Temporal.PlainDate.from(arg), "reject minus zero as extended year" -); - + ); +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/add/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/add/options-wrong-type.js new file mode 100644 index 000000000000..adcee8e6870e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/add/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.add +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.PlainDate(2000, 5, 2); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.add({ months: 1 }, value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/equals/argument-number.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/equals/argument-number.js new file mode 100644 index 000000000000..8def2a53657d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/equals/argument-number.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.equals +description: A number is converted to a string, then to Temporal.PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDate(1976, 11, 18); + +const arg = 19761118; + +const result = instance.equals(arg); +assert.sameValue(result, true, "19761118 is a valid ISO string for PlainDate"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.equals(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/equals/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/equals/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..8797de145589 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/equals/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,31 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.equals +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDate(1976, 11, 18); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.equals(arg); +assert.sameValue( + result1, + true, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.equals(arg); +assert.sameValue( + result2, + true, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/equals/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/equals/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..59fd00b9e6e6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/equals/argument-propertybag-calendar-number.js @@ -0,0 +1,44 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.equals +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDate(1976, 11, 18); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.equals(arg); +assert.sameValue(result1, true, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.equals(arg); +assert.sameValue(result2, true, "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + assert.throws( + RangeError, + () => instance.equals(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.equals(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/equals/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/equals/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..37890485fd6a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/equals/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.equals +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.PlainDate(2000, 5, 2); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.equals(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.equals(arg), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.equals(arg), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.equals(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.equals(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/equals/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/equals/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..0e3582b36eff --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/equals/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.equals +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.PlainDate(2000, 5, 2); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.equals(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/equals/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/equals/argument-wrong-type.js index caa70ef84dfe..b9f0ef23641b 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/equals/argument-wrong-type.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/equals/argument-wrong-type.js @@ -1,20 +1,39 @@ // |reftest| skip -- Temporal is not supported -// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// Copyright (C) 2022 Igalia, S.L. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. /*--- esid: sec-temporal.plaindate.prototype.equals -description: Appropriate error thrown when argument cannot be converted to a valid string -features: [Symbol, Temporal] +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] ---*/ -const instance = Temporal.PlainDate.from({ year: 2000, month: 5, day: 2 }); +const instance = new Temporal.PlainDate(2000, 5, 2); -assert.throws(RangeError, () => instance.equals(undefined), "undefined"); -assert.throws(RangeError, () => instance.equals(null), "null"); -assert.throws(RangeError, () => instance.equals(true), "true"); -assert.throws(RangeError, () => instance.equals(""), "empty string"); -assert.throws(TypeError, () => instance.equals(Symbol()), "symbol"); -assert.throws(RangeError, () => instance.equals(1), "1"); +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.equals(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.equals(arg), `${description} is not a valid property bag and does not convert to a string`); +} reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/equals/leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/equals/leap-second.js new file mode 100644 index 000000000000..828ff32533d2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/equals/leap-second.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.equals +description: Leap second is a valid ISO string for PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDate(2016, 12, 31); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.equals(arg); +assert.sameValue( + result1, + true, + "leap second is a valid ISO string for PlainDate" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.equals(arg); +assert.sameValue( + result2, + true, + "second: 60 is ignored in property bag for PlainDate" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/equals/year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/equals/year-zero.js index ae3b8f3f9cef..426836e09ab8 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/equals/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/equals/year-zero.js @@ -8,13 +8,19 @@ description: Negative zero, as an extended year, is rejected features: [Temporal, arrow-function] ---*/ -const arg = "-000000-10-31"; +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; const instance = new Temporal.PlainDate(2000, 5, 2); - -assert.throws( +invalidStrings.forEach((arg) => { + assert.throws( RangeError, - () => { instance.equals(arg); }, + () => instance.equals(arg), "reject minus zero as extended year" -); + ); +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/argument-number.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/argument-number.js new file mode 100644 index 000000000000..babc3217b558 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/argument-number.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.since +description: A number is converted to a string, then to Temporal.PlainDate +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDate(1976, 11, 18); + +const arg = 19761118; + +const result = instance.since(arg); +TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19761118 is a valid ISO string for PlainDate"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.since(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..e4c8e396c306 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.since +description: Leap second is a valid ISO string for a calendar in a property bag +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDate(1976, 11, 18); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.since(arg); +TemporalHelpers.assertDuration( + result1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.since(arg); +TemporalHelpers.assertDuration( + result2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..bb9faf2a64ea --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-number.js @@ -0,0 +1,45 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.since +description: A number as calendar in a property bag is converted to a string, then to a calendar +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDate(1976, 11, 18); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.since(arg); +TemporalHelpers.assertDuration(result1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.since(arg); +TemporalHelpers.assertDuration(result2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + assert.throws( + RangeError, + () => instance.since(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.since(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..3a5bf907e742 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.since +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.PlainDate(2000, 5, 2); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.since(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.since(arg), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.since(arg), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.since(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.since(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..8037421f0c14 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.since +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.PlainDate(2000, 5, 2); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.since(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/argument-wrong-type.js new file mode 100644 index 000000000000..b14ab08988a2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/argument-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.since +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.PlainDate(2000, 5, 2); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.since(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.since(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/largestunit-default.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/largestunit-default.js index 26942960236c..1eeb974cf958 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/largestunit-default.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/largestunit-default.js @@ -11,12 +11,12 @@ features: [Temporal] const feb20 = Temporal.PlainDate.from("2020-02-01"); const feb21 = Temporal.PlainDate.from("2021-02-01"); -TemporalHelpers.assertDuration(feb21.since(feb20), 0, 0, 0, /* days = */ 366, 0, 0, 0, 0, 0, 0, 0, "no options"); -TemporalHelpers.assertDuration(feb21.since(feb20, undefined), 0, 0, 0, /* days = */ 366, 0, 0, 0, 0, 0, 0, 0, "undefined options"); -TemporalHelpers.assertDuration(feb21.since(feb20, {}), 0, 0, 0, /* days = */ 366, 0, 0, 0, 0, 0, 0, 0, "no largestUnit"); -TemporalHelpers.assertDuration(feb21.since(feb20, { largestUnit: undefined }), 0, 0, 0, /* days = */ 366, 0, 0, 0, 0, 0, 0, 0, "undefined largestUnit"); -TemporalHelpers.assertDuration(feb21.since(feb20, { largestUnit: "days" }), 0, 0, 0, /* days = */ 366, 0, 0, 0, 0, 0, 0, 0, "days"); -TemporalHelpers.assertDuration(feb21.since(feb20, { largestUnit: "auto" }), 0, 0, 0, /* days = */ 366, 0, 0, 0, 0, 0, 0, 0, "auto"); -TemporalHelpers.assertDuration(feb21.since(feb20, () => {}), 0, 0, 0, /* days = */ 366, 0, 0, 0, 0, 0, 0, 0, "no largestUnit (function)"); +TemporalHelpers.assertDuration(feb21.since(feb20), 0, 0, 0, /* days = */ 366, 0, 0, 0, 0, 0, 0, "no options"); +TemporalHelpers.assertDuration(feb21.since(feb20, undefined), 0, 0, 0, /* days = */ 366, 0, 0, 0, 0, 0, 0, "undefined options"); +TemporalHelpers.assertDuration(feb21.since(feb20, {}), 0, 0, 0, /* days = */ 366, 0, 0, 0, 0, 0, 0, "no largestUnit"); +TemporalHelpers.assertDuration(feb21.since(feb20, { largestUnit: undefined }), 0, 0, 0, /* days = */ 366, 0, 0, 0, 0, 0, 0, "undefined largestUnit"); +TemporalHelpers.assertDuration(feb21.since(feb20, { largestUnit: "days" }), 0, 0, 0, /* days = */ 366, 0, 0, 0, 0, 0, 0, "days"); +TemporalHelpers.assertDuration(feb21.since(feb20, { largestUnit: "auto" }), 0, 0, 0, /* days = */ 366, 0, 0, 0, 0, 0, 0, "auto"); +TemporalHelpers.assertDuration(feb21.since(feb20, () => {}), 0, 0, 0, /* days = */ 366, 0, 0, 0, 0, 0, 0, "no largestUnit (function)"); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/largestunit-higher-units.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/largestunit-higher-units.js index ba1c1804a899..f1d52e2b7484 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/largestunit-higher-units.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/largestunit-higher-units.js @@ -18,11 +18,11 @@ const feb20 = Temporal.PlainDate.from("2020-02-01"); const feb21 = Temporal.PlainDate.from("2021-02-01"); TemporalHelpers.assertDuration(feb21.since(feb20, { largestUnit: "years" }), /* years = */ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "start of February, years"); TemporalHelpers.assertDuration(feb21.since(feb20, { largestUnit: "months" }), 0, /* months = */ 12, 0, 0, 0, 0, 0, 0, 0, 0, "start of February, months"); -TemporalHelpers.assertDuration(feb21.since(feb20, { largestUnit: "weeks" }), 0, 0, /* weeks = */ 52, /* days = */ 2, 0, 0, 0, 0, 0, 0, 0, "start of February, weeks"); +TemporalHelpers.assertDuration(feb21.since(feb20, { largestUnit: "weeks" }), 0, 0, /* weeks = */ 52, /* days = */ 2, 0, 0, 0, 0, 0, 0, "start of February, weeks"); const lastFeb20 = Temporal.PlainDate.from("2020-02-29"); const lastFeb21 = Temporal.PlainDate.from("2021-02-28"); -TemporalHelpers.assertDuration(lastFeb21.since(lastFeb20, { largestUnit: "years" }), 0, /* months = */ 11, 0, /* days = */ 28, 0, 0, 0, 0, 0, 0, 0, "end of February, years"); +TemporalHelpers.assertDuration(lastFeb21.since(lastFeb20, { largestUnit: "years" }), 0, /* months = */ 11, 0, /* days = */ 28, 0, 0, 0, 0, 0, 0, "end of February, years"); TemporalHelpers.assertDuration(lastFeb21.since(lastFeb20, { largestUnit: "months" }), 0, /* months = */ 11, 0, /* days = */ 28, 0, 0, 0, 0, 0, 0, "end of February, months"); TemporalHelpers.assertDuration(lastFeb21.since(lastFeb20, { largestUnit: "weeks" }), 0, 0, /* weeks = */ 52, /* days = */ 1, 0, 0, 0, 0, 0, 0, "end of February, weeks"); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/largestunit-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/largestunit-invalid-string.js index 4bec8f148112..1e9ea39b0476 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/largestunit-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/largestunit-invalid-string.js @@ -10,9 +10,32 @@ features: [Temporal] const earlier = new Temporal.PlainDate(2000, 5, 2); const later = new Temporal.PlainDate(2001, 6, 3); -const values = ["era", "eraYear", "hours", "minutes", "seconds", "milliseconds", "microseconds", "nanoseconds", "other string"]; -for (const largestUnit of values) { - assert.throws(RangeError, () => later.since(earlier, { largestUnit })); +const badValues = [ + "era", + "eraYear", + "hour", + "minute", + "second", + "millisecond", + "microsecond", + "nanosecond", + "month\0", + "YEAR", + "eras", + "eraYears", + "hours", + "minutes", + "seconds", + "milliseconds", + "microseconds", + "nanoseconds", + "months\0", + "YEARS", + "other string" +]; +for (const largestUnit of badValues) { + assert.throws(RangeError, () => later.since(earlier, { largestUnit }), + `"${largestUnit}" is not a valid value for largestUnit`); } reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/leap-second.js new file mode 100644 index 000000000000..553e7d53084a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/leap-second.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.since +description: Leap second is a valid ISO string for PlainDate +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDate(2016, 12, 31); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.since(arg); +TemporalHelpers.assertDuration( + result1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "leap second is a valid ISO string for PlainDate" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.since(arg); +TemporalHelpers.assertDuration( + result2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "second: 60 is ignored in property bag for PlainDate" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/options-wrong-type.js new file mode 100644 index 000000000000..e0b7c53efe6f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.since +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.PlainDate(2000, 5, 2); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.since(new Temporal.PlainDate(1976, 11, 18), value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/smallestunit-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/smallestunit-invalid-string.js index 84ec4be86000..7b71bb2f356d 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/smallestunit-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/smallestunit-invalid-string.js @@ -10,9 +10,32 @@ features: [Temporal] const earlier = new Temporal.PlainDate(2000, 5, 2); const later = new Temporal.PlainDate(2001, 6, 3); -const values = ["era", "eraYear", "hours", "minutes", "seconds", "milliseconds", "microseconds", "nanoseconds", "other string"]; -for (const smallestUnit of values) { - assert.throws(RangeError, () => later.since(earlier, { smallestUnit })); +const badValues = [ + "era", + "eraYear", + "hour", + "minute", + "second", + "millisecond", + "microsecond", + "nanosecond", + "month\0", + "YEAR", + "eras", + "eraYears", + "hours", + "minutes", + "seconds", + "milliseconds", + "microseconds", + "nanoseconds", + "months\0", + "YEARS", + "other string", +]; +for (const smallestUnit of badValues) { + assert.throws(RangeError, () => later.since(earlier, { smallestUnit }), + `"${smallestUnit}" is not a valid value for smallest unit`); } reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/year-zero.js index e7914107c33c..3c1a8b66da0c 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/since/year-zero.js @@ -8,13 +8,19 @@ description: Negative zero, as an extended year, is rejected features: [Temporal, arrow-function] ---*/ -const arg = "-000000-10-31"; +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; const instance = new Temporal.PlainDate(2000, 5, 2); - -assert.throws( +invalidStrings.forEach((arg) => { + assert.throws( RangeError, - () => { instance.since(arg); }, + () => instance.since(arg), "reject minus zero as extended year" -); + ); +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/subtract/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/subtract/options-wrong-type.js new file mode 100644 index 000000000000..b9788c182f0f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/subtract/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.subtract +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.PlainDate(2000, 5, 2); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.subtract({ months: 1 }, value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/argument-number.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/argument-number.js new file mode 100644 index 000000000000..12c1055026dc --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/argument-number.js @@ -0,0 +1,34 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.toplaindatetime +description: A number is converted to a string, then to Temporal.PlainTime +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDate(2000, 5, 2); + +const arg = 123456.987654321; + +const result = instance.toPlainDateTime(arg); +TemporalHelpers.assertPlainDateTime(result, 2000, 5, "M05", 2, 12, 34, 56, 987, 654, 321, "123456.987654321 is a valid ISO string for PlainTime"); + +const numbers = [ + 1, + -123456.987654321, + 1234567, + 123456.9876543219, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.toPlainDateTime(arg), + `Number ${arg} does not convert to a valid ISO string for PlainTime` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/argument-string-time-designator-required-for-disambiguation.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/argument-string-time-designator-required-for-disambiguation.js index 631bb87251c1..408dea51207a 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/argument-string-time-designator-required-for-disambiguation.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/argument-string-time-designator-required-for-disambiguation.js @@ -33,7 +33,7 @@ ambiguousStrings.forEach((string) => { assert.throws( RangeError, () => instance.toPlainDateTime(arg), - 'space is not accepted as a substitute for T prefix' + "space is not accepted as a substitute for T prefix" ); }); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/argument-wrong-type.js new file mode 100644 index 000000000000..a193894387e9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/argument-wrong-type.js @@ -0,0 +1,38 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.toplaindatetime +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainTime +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.PlainDate(2000, 5, 2); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.toPlainDateTime(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainTime, "Temporal.PlainTime, object"], + [Temporal.PlainTime.prototype, "Temporal.PlainTime.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.toPlainDateTime(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/leap-second.js new file mode 100644 index 000000000000..fcfccffab54c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/leap-second.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.toplaindatetime +description: Leap second is a valid ISO string for PlainTime +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDate(2000, 5, 2); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.toPlainDateTime(arg); +TemporalHelpers.assertPlainDateTime( + result1, + 2000, 5, "M05", 2, 23, 59, 59, 0, 0, 0, + "leap second is a valid ISO string for PlainTime" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.toPlainDateTime(arg); +TemporalHelpers.assertPlainDateTime( + result2, + 2000, 5, "M05", 2, 23, 59, 59, 0, 0, 0, + "second: 60 is ignored in property bag for PlainTime" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/limits.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/limits.js new file mode 100644 index 000000000000..4e67599c0af8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/limits.js @@ -0,0 +1,42 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.toplaindatetime +description: Checking limits of representable PlainDateTime +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const midnight = new Temporal.PlainTime(0, 0); +const firstNs = new Temporal.PlainTime(0, 0, 0, 0, 0, 1); +const lastNs = new Temporal.PlainTime(23, 59, 59, 999, 999, 999); +const min = new Temporal.PlainDate(-271821, 4, 19); +const max = new Temporal.PlainDate(275760, 9, 13); + +assert.throws( + RangeError, + () => min.toPlainDateTime(midnight), + "Cannot go below representable limit for PlainDateTime" +); + +TemporalHelpers.assertPlainDateTime( + max.toPlainDateTime(midnight), + 275760, 9, "M09", 13, 0, 0, 0, 0, 0, 0, + "Midnight on maximal representable PlainDate" +); + +TemporalHelpers.assertPlainDateTime( + min.toPlainDateTime(firstNs), + -271821, 4, "M04", 19, 0, 0, 0, 0, 0, 1, + "Computing the minimum (earliest) representable PlainDateTime" +); + +TemporalHelpers.assertPlainDateTime( + max.toPlainDateTime(lastNs), + 275760, 9, "M09", 13, 23, 59, 59, 999, 999, 999, + "Computing the maximum (latest) representable PlainDateTime" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/plaintime-propertybag-no-time-units.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/plaintime-propertybag-no-time-units.js index 821e8c877351..638d28d40e48 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/plaintime-propertybag-no-time-units.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/plaintime-propertybag-no-time-units.js @@ -12,7 +12,7 @@ features: [Temporal] const instance = new Temporal.PlainDate(2000, 1, 1); const props = {}; -assert.throws(TypeError, () => instance.toPlainDateTime(props), "TypeError if at least one property is not present"); +assert.throws(TypeError, () => instance.toPlainDateTime(props), "TypeError if no properties are present"); props.minute = 30; const result = instance.toPlainDateTime(props); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/year-zero.js index 9fa9ac163458..1fbbe37578be 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/year-zero.js @@ -9,8 +9,9 @@ features: [Temporal, arrow-function] ---*/ const invalidStrings = [ - '-000000-12-07T03:24:30', - '-000000-12-07T03:24:30+01:00[UTC]' + "-000000-12-07T03:24:30", + "-000000-12-07T03:24:30+01:00", + "-000000-12-07T03:24:30+00:00[UTC]", ]; const instance = new Temporal.PlainDate(2000, 5, 2); invalidStrings.forEach((arg) => { diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toString/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toString/options-wrong-type.js new file mode 100644 index 000000000000..663c6c6d1433 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toString/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.tostring +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.PlainDate(2000, 5, 2); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.toString(value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/argument-number.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/argument-number.js new file mode 100644 index 000000000000..6f2c10a90aab --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/argument-number.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.tozoneddatetime +description: A number is converted to a string, then to Temporal.PlainTime +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDate(2000, 5, 2); + +const arg = 123456.987654321; + +const result = instance.toZonedDateTime({ plainTime: arg, timeZone: "UTC" }); +assert.sameValue(result.epochNanoseconds, 957270896_987_654_321n, "123456.987654321 is a valid ISO string for PlainTime"); + +const numbers = [ + 1, + -123456.987654321, + 1234567, + 123456.9876543219, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.toZonedDateTime({ plainTime: arg, timeZone: "UTC" }), + `Number ${arg} does not convert to a valid ISO string for PlainTime` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/argument-string-time-designator-required-for-disambiguation.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/argument-string-time-designator-required-for-disambiguation.js index 9afb3241fe64..7d97a9be36dc 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/argument-string-time-designator-required-for-disambiguation.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/argument-string-time-designator-required-for-disambiguation.js @@ -33,7 +33,7 @@ ambiguousStrings.forEach((string) => { assert.throws( RangeError, () => instance.toZonedDateTime({ plainTime: arg, timeZone: "UTC" }), - 'space is not accepted as a substitute for T prefix' + "space is not accepted as a substitute for T prefix" ); }); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/argument-wrong-type.js new file mode 100644 index 000000000000..57deb6735d34 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/argument-wrong-type.js @@ -0,0 +1,38 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.tozoneddatetime +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainTime +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.PlainDate(2000, 5, 2); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.toZonedDateTime({ plainTime: arg, timeZone: "UTC" }), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainTime, "Temporal.PlainTime, object"], + [Temporal.PlainTime.prototype, "Temporal.PlainTime.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.toZonedDateTime({ plainTime: arg, timeZone: "UTC" }), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/leap-second.js new file mode 100644 index 000000000000..257f6ce9c18b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/leap-second.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.tozoneddatetime +description: Leap second is a valid ISO string for PlainTime +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDate(2000, 5, 2); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.toZonedDateTime({ plainTime: arg, timeZone: "UTC" }); +assert.sameValue( + result1.epochNanoseconds, + 957311999_000_000_000n, + "leap second is a valid ISO string for PlainTime" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.toZonedDateTime({ plainTime: arg, timeZone: "UTC" }); +assert.sameValue( + result2.epochNanoseconds, + 957311999_000_000_000n, + "second: 60 is ignored in property bag for PlainTime" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/plaintime-propertybag-no-time-units.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/plaintime-propertybag-no-time-units.js index b71730b466b9..80d1eda8531b 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/plaintime-propertybag-no-time-units.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/plaintime-propertybag-no-time-units.js @@ -11,7 +11,7 @@ features: [Temporal] const instance = new Temporal.PlainDate(2000, 1, 1); const props = {}; -assert.throws(TypeError, () => instance.toZonedDateTime({ plainTime: props, timeZone: "UTC" }), "TypeError if at least one property is not present"); +assert.throws(TypeError, () => instance.toZonedDateTime({ plainTime: props, timeZone: "UTC" }), "TypeError if no properties are present"); props.minute = 30; const result = instance.toZonedDateTime({ plainTime: props, timeZone: "UTC" }); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-string-leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-string-leap-second.js new file mode 100644 index 000000000000..a2aa45df5b02 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-string-leap-second.js @@ -0,0 +1,23 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.tozoneddatetime +description: Leap second is a valid ISO string for TimeZone +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDate(2000, 5, 2); +let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; + +const result1 = instance.toZonedDateTime(timeZone); +assert.sameValue(result1.timeZone.id, "UTC", "leap second is a valid ISO string for TimeZone"); +const result2 = instance.toZonedDateTime({ timeZone }); +assert.sameValue(result2.timeZone.id, "UTC", "leap second is a valid ISO string for TimeZone (nested property)"); + +timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; +assert.throws(RangeError, () => instance.toZonedDateTime(timeZone), "leap second in time zone name not valid"); +assert.throws(RangeError, () => instance.toZonedDateTime({ timeZone }), "leap second in time zone name not valid (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-string-year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-string-year-zero.js new file mode 100644 index 000000000000..a3ced9572e1f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-string-year-zero.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.tozoneddatetime +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.PlainDate(2000, 5, 2); +invalidStrings.forEach((timeZone) => { + assert.throws( + RangeError, + () => instance.toZonedDateTime(timeZone), + "reject minus zero as extended year" + ); + assert.throws( + RangeError, + () => instance.toZonedDateTime({ timeZone }), + "reject minus zero as extended year (nested property)" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-wrong-type.js new file mode 100644 index 000000000000..17cd9c6a0807 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-wrong-type.js @@ -0,0 +1,41 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.tozoneddatetime +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for TimeZone +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.PlainDate(2000, 5, 2); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], +]; + +for (const [timeZone, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.toZonedDateTime(timeZone), `${description} does not convert to a valid ISO string`); + assert.throws(RangeError, () => instance.toZonedDateTime({ timeZone }), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [timeZone, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.toZonedDateTime(timeZone), `${description} is not a valid object and does not convert to a string`); + assert.throws(TypeError, () => instance.toZonedDateTime({ timeZone }), `${description} is not a valid object and does not convert to a string (nested property)`); +} + +const timeZone = undefined; +assert.throws(RangeError, () => instance.toZonedDateTime({ timeZone }), `undefined is always a RangeError as nested property`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/year-zero.js index 419a55765201..8d7d385433e7 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/toZonedDateTime/year-zero.js @@ -9,8 +9,9 @@ features: [Temporal, arrow-function] ---*/ const invalidStrings = [ - '-000000-12-07T03:24:30', - '-000000-12-07T03:24:30+01:00[UTC]' + "-000000-12-07T03:24:30", + "-000000-12-07T03:24:30+01:00", + "-000000-12-07T03:24:30+00:00[UTC]", ]; const instance = new Temporal.PlainDate(2000, 5, 2); invalidStrings.forEach((arg) => { diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/argument-number.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/argument-number.js new file mode 100644 index 000000000000..d278cc1826c3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/argument-number.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.until +description: A number is converted to a string, then to Temporal.PlainDate +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDate(1976, 11, 18); + +const arg = 19761118; + +const result = instance.until(arg); +TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19761118 is a valid ISO string for PlainDate"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.until(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..dc51de2e5c27 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.until +description: Leap second is a valid ISO string for a calendar in a property bag +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDate(1976, 11, 18); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.until(arg); +TemporalHelpers.assertDuration( + result1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.until(arg); +TemporalHelpers.assertDuration( + result2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..66ddca48a301 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/argument-propertybag-calendar-number.js @@ -0,0 +1,45 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.until +description: A number as calendar in a property bag is converted to a string, then to a calendar +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDate(1976, 11, 18); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.until(arg); +TemporalHelpers.assertDuration(result1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.until(arg); +TemporalHelpers.assertDuration(result2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + assert.throws( + RangeError, + () => instance.until(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.until(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..b8083193edca --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.until +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.PlainDate(2000, 5, 2); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.until(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.until(arg), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.until(arg), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.until(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.until(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..2a85f6fae451 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.until +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.PlainDate(2000, 5, 2); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.until(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/argument-wrong-type.js new file mode 100644 index 000000000000..aba6a2294476 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/argument-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.until +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.PlainDate(2000, 5, 2); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.until(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.until(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/largestunit-default.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/largestunit-default.js index c087087eb22d..95039049b283 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/largestunit-default.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/largestunit-default.js @@ -11,12 +11,12 @@ features: [Temporal] const feb20 = Temporal.PlainDate.from("2020-02-01"); const feb21 = Temporal.PlainDate.from("2021-02-01"); -TemporalHelpers.assertDuration(feb20.until(feb21), 0, 0, 0, /* days = */ 366, 0, 0, 0, 0, 0, 0, 0, "no options"); -TemporalHelpers.assertDuration(feb20.until(feb21, undefined), 0, 0, 0, /* days = */ 366, 0, 0, 0, 0, 0, 0, 0, "undefined options"); -TemporalHelpers.assertDuration(feb20.until(feb21, {}), 0, 0, 0, /* days = */ 366, 0, 0, 0, 0, 0, 0, 0, "no largestUnit"); -TemporalHelpers.assertDuration(feb20.until(feb21, { largestUnit: undefined }), 0, 0, 0, /* days = */ 366, 0, 0, 0, 0, 0, 0, 0, "undefined largestUnit"); -TemporalHelpers.assertDuration(feb20.until(feb21, { largestUnit: "days" }), 0, 0, 0, /* days = */ 366, 0, 0, 0, 0, 0, 0, 0, "days"); -TemporalHelpers.assertDuration(feb20.until(feb21, { largestUnit: "auto" }), 0, 0, 0, /* days = */ 366, 0, 0, 0, 0, 0, 0, 0, "auto"); -TemporalHelpers.assertDuration(feb20.until(feb21, () => {}), 0, 0, 0, /* days = */ 366, 0, 0, 0, 0, 0, 0, 0, "no largestUnit (function)"); +TemporalHelpers.assertDuration(feb20.until(feb21), 0, 0, 0, /* days = */ 366, 0, 0, 0, 0, 0, 0, "no options"); +TemporalHelpers.assertDuration(feb20.until(feb21, undefined), 0, 0, 0, /* days = */ 366, 0, 0, 0, 0, 0, 0, "undefined options"); +TemporalHelpers.assertDuration(feb20.until(feb21, {}), 0, 0, 0, /* days = */ 366, 0, 0, 0, 0, 0, 0, "no largestUnit"); +TemporalHelpers.assertDuration(feb20.until(feb21, { largestUnit: undefined }), 0, 0, 0, /* days = */ 366, 0, 0, 0, 0, 0, 0, "undefined largestUnit"); +TemporalHelpers.assertDuration(feb20.until(feb21, { largestUnit: "days" }), 0, 0, 0, /* days = */ 366, 0, 0, 0, 0, 0, 0, "days"); +TemporalHelpers.assertDuration(feb20.until(feb21, { largestUnit: "auto" }), 0, 0, 0, /* days = */ 366, 0, 0, 0, 0, 0, 0, "auto"); +TemporalHelpers.assertDuration(feb20.until(feb21, () => {}), 0, 0, 0, /* days = */ 366, 0, 0, 0, 0, 0, 0, "no largestUnit (function)"); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/largestunit-higher-units.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/largestunit-higher-units.js index 5f68a47561f8..f502ed15d398 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/largestunit-higher-units.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/largestunit-higher-units.js @@ -18,7 +18,7 @@ const feb20 = Temporal.PlainDate.from("2020-02-01"); const feb21 = Temporal.PlainDate.from("2021-02-01"); TemporalHelpers.assertDuration(feb20.until(feb21, { largestUnit: "years" }), /* years = */ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "start of February, years"); TemporalHelpers.assertDuration(feb20.until(feb21, { largestUnit: "months" }), 0, /* months = */ 12, 0, 0, 0, 0, 0, 0, 0, 0, "start of February, months"); -TemporalHelpers.assertDuration(feb20.until(feb21, { largestUnit: "weeks" }), 0, 0, /* weeks = */ 52, /* days = */ 2, 0, 0, 0, 0, 0, 0, 0, "start of February, weeks"); +TemporalHelpers.assertDuration(feb20.until(feb21, { largestUnit: "weeks" }), 0, 0, /* weeks = */ 52, /* days = */ 2, 0, 0, 0, 0, 0, 0, "start of February, weeks"); const lastFeb20 = Temporal.PlainDate.from("2020-02-29"); const lastFeb21 = Temporal.PlainDate.from("2021-02-28"); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/largestunit-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/largestunit-invalid-string.js index ddb3605a02cc..a7c84205b91b 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/largestunit-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/largestunit-invalid-string.js @@ -10,9 +10,32 @@ features: [Temporal] const earlier = new Temporal.PlainDate(2000, 5, 2); const later = new Temporal.PlainDate(2001, 6, 3); -const values = ["era", "eraYear", "hours", "minutes", "seconds", "milliseconds", "microseconds", "nanoseconds", "other string"]; -for (const largestUnit of values) { - assert.throws(RangeError, () => earlier.until(later, { largestUnit })); +const badValues = [ + "era", + "eraYear", + "hour", + "minute", + "second", + "millisecond", + "microsecond", + "nanosecond", + "month\0", + "YEAR", + "eras", + "eraYears", + "hours", + "minutes", + "seconds", + "milliseconds", + "microseconds", + "nanoseconds", + "months\0", + "YEARS", + "other string" +]; +for (const largestUnit of badValues) { + assert.throws(RangeError, () => earlier.until(later, { largestUnit }), + `"${largestUnit}" is not a valid value for largestUnit`); } reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/leap-second.js new file mode 100644 index 000000000000..691dc1ad44d3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/leap-second.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.until +description: Leap second is a valid ISO string for PlainDate +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDate(2016, 12, 31); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.until(arg); +TemporalHelpers.assertDuration( + result1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "leap second is a valid ISO string for PlainDate" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.until(arg); +TemporalHelpers.assertDuration( + result2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "second: 60 is ignored in property bag for PlainDate" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/options-wrong-type.js new file mode 100644 index 000000000000..9913234c9dec --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.until +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.PlainDate(2000, 5, 2); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.until(new Temporal.PlainDate(1976, 11, 18), value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/smallestunit-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/smallestunit-invalid-string.js index 005e5a9b0ecc..474e505a88d9 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/smallestunit-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/smallestunit-invalid-string.js @@ -10,9 +10,32 @@ features: [Temporal] const earlier = new Temporal.PlainDate(2000, 5, 2); const later = new Temporal.PlainDate(2001, 6, 3); -const values = ["era", "eraYear", "hours", "minutes", "seconds", "milliseconds", "microseconds", "nanoseconds", "other string"]; -for (const smallestUnit of values) { - assert.throws(RangeError, () => earlier.until(later, { smallestUnit })); +const badValues = [ + "era", + "eraYear", + "hour", + "minute", + "second", + "millisecond", + "microsecond", + "nanosecond", + "month\0", + "YEAR", + "eras", + "eraYears", + "hours", + "minutes", + "seconds", + "milliseconds", + "microseconds", + "nanoseconds", + "months\0", + "YEARS", + "other string", +]; +for (const smallestUnit of badValues) { + assert.throws(RangeError, () => earlier.until(later, { smallestUnit }), + `"${smallestUnit}" is not a valid value for smallest unit`); } reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/year-zero.js index 87a320654da9..36fb006eea38 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/until/year-zero.js @@ -8,13 +8,19 @@ description: Negative zero, as an extended year, is rejected features: [Temporal, arrow-function] ---*/ -const arg = "-000000-10-31"; +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; const instance = new Temporal.PlainDate(2000, 5, 2); - -assert.throws( +invalidStrings.forEach((arg) => { + assert.throws( RangeError, - () => { instance.until(arg); }, + () => instance.until(arg), "reject minus zero as extended year" -); + ); +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/with/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/with/options-wrong-type.js new file mode 100644 index 000000000000..39b087351977 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/with/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.with +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.PlainDate(2000, 5, 2); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.with({ day: 5 }, value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-number.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-number.js new file mode 100644 index 000000000000..142b81e4e0fd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-number.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.withcalendar +description: A number is converted to a string, then to Temporal.Calendar +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDate(1976, 11, 18, { id: "replace-me" }); + +const arg = 19761118; + +const result = instance.withCalendar(arg); +assert.sameValue(result.calendar.id, "iso8601", "19761118 is a valid ISO string for Calendar"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.withCalendar(arg), + `Number ${arg} does not convert to a valid ISO string for Calendar` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-string-leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-string-leap-second.js new file mode 100644 index 000000000000..bb218ed58234 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-string-leap-second.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.withcalendar +description: Leap second is a valid ISO string for Calendar +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDate(1976, 11, 18, { id: "replace-me" }); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.withCalendar(arg); +assert.sameValue( + result1.calendar.id, + "iso8601", + "leap second is a valid ISO string for Calendar" +); + +arg = { calendar: "2016-12-31T23:59:60" }; +const result2 = instance.withCalendar(arg); +assert.sameValue( + result2.calendar.id, + "iso8601", + "leap second is a valid ISO string for Calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-wrong-type.js new file mode 100644 index 000000000000..9735d7b0981d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-wrong-type.js @@ -0,0 +1,35 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.withcalendar +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for Calendar +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.PlainDate(1976, 11, 18, { id: "replace-me" }); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.withCalendar(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.withCalendar(arg), `${description} is not a valid object and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDate/shell.js b/js/src/tests/test262/built-ins/Temporal/PlainDate/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDate/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDate/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/calendar-number.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/calendar-number.js new file mode 100644 index 000000000000..f53edcaee97f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/calendar-number.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime +description: A number is converted to a string, then to Temporal.Calendar +features: [Temporal] +---*/ + +const arg = 19761118; + +const result = new Temporal.PlainDateTime(2000, 5, 2, 15, 23, 30, 987, 654, 321, arg); +assert.sameValue(result.calendar.id, "iso8601", "19761118 is a valid ISO string for Calendar"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => new Temporal.PlainDateTime(2000, 5, 2, 15, 23, 30, 987, 654, 321, arg), + `Number ${arg} does not convert to a valid ISO string for Calendar` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/calendar-wrong-type.js new file mode 100644 index 000000000000..7a8fed854fd6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/calendar-wrong-type.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for Calendar +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => new Temporal.PlainDateTime(2000, 5, 2, 15, 23, 30, 987, 654, 321, arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => new Temporal.PlainDateTime(2000, 5, 2, 15, 23, 30, 987, 654, 321, arg), `${description} is not a valid object and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/compare/argument-number.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/compare/argument-number.js new file mode 100644 index 000000000000..b018e5cf6df2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/compare/argument-number.js @@ -0,0 +1,37 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.compare +description: A number is converted to a string, then to Temporal.PlainDateTime +features: [Temporal] +---*/ + +let arg = 19761118; + +const result1 = Temporal.PlainDateTime.compare(arg, new Temporal.PlainDateTime(1976, 11, 18)); +assert.sameValue(result1, 0, "19761118 is a valid ISO string for PlainDateTime (first argument)"); +const result2 = Temporal.PlainDateTime.compare(new Temporal.PlainDateTime(1976, 11, 18), arg); +assert.sameValue(result2, 0, "19761118 is a valid ISO string for PlainDateTime (second argument)"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => Temporal.PlainDateTime.compare(arg, new Temporal.PlainDateTime(1976, 11, 18)), + `Number ${arg} does not convert to a valid ISO string for PlainDateTime (first argument)` + ); + assert.throws( + RangeError, + () => Temporal.PlainDateTime.compare(new Temporal.PlainDateTime(1976, 11, 18), arg), + `Number ${arg} does not convert to a valid ISO string for PlainDateTime (second argument)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..47be01a7a775 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.compare +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = Temporal.PlainDateTime.compare(arg, new Temporal.PlainDateTime(1976, 11, 18)); +assert.sameValue(result1, 0, "leap second is a valid ISO string for calendar (first argument)"); +const result2 = Temporal.PlainDateTime.compare(new Temporal.PlainDateTime(1976, 11, 18), arg); +assert.sameValue(result2, 0, "leap second is a valid ISO string for calendar (second argument)"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result3 = Temporal.PlainDateTime.compare(arg, new Temporal.PlainDateTime(1976, 11, 18)); +assert.sameValue(result3, 0, "leap second is a valid ISO string for calendar (nested property, first argument)"); +const result4 = Temporal.PlainDateTime.compare(new Temporal.PlainDateTime(1976, 11, 18), arg); +assert.sameValue(result4, 0, "leap second is a valid ISO string for calendar (nested property, second argument)"); + + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..d118a9efda79 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-number.js @@ -0,0 +1,56 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.compare +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = Temporal.PlainDateTime.compare(arg, new Temporal.PlainDateTime(1976, 11, 18)); +assert.sameValue(result1, 0, "19970327 is a valid ISO string for calendar (first argument)"); +const result2 = Temporal.PlainDateTime.compare(new Temporal.PlainDateTime(1976, 11, 18), arg); +assert.sameValue(result2, 0, "19970327 is a valid ISO string for calendar (second argument)"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result3 = Temporal.PlainDateTime.compare(arg, new Temporal.PlainDateTime(1976, 11, 18)); +assert.sameValue(result3, 0, "19970327 is a valid ISO string for calendar (nested property, first argument)"); +const result4 = Temporal.PlainDateTime.compare(new Temporal.PlainDateTime(1976, 11, 18), arg); +assert.sameValue(result4, 0, "19970327 is a valid ISO string for calendar (nested property, second argument)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + assert.throws( + RangeError, + () => Temporal.PlainDateTime.compare(arg, new Temporal.PlainDateTime(1976, 11, 18)), + `Number ${calendar} does not convert to a valid ISO string for calendar (first argument)` + ); + assert.throws( + RangeError, + () => Temporal.PlainDateTime.compare(new Temporal.PlainDateTime(1976, 11, 18), arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (second argument)` + ); + arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; + assert.throws( + RangeError, + () => Temporal.PlainDateTime.compare(arg, new Temporal.PlainDateTime(1976, 11, 18)), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property, first argument)` + ); + assert.throws( + RangeError, + () => Temporal.PlainDateTime.compare(new Temporal.PlainDateTime(1976, 11, 18), arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property, second argument)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..aad98db2d461 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,52 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.compare +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => Temporal.PlainDateTime.compare(arg, new Temporal.PlainDateTime(1976, 11, 18)), `${description} does not convert to a valid ISO string (first argument)`); + assert.throws(RangeError, () => Temporal.PlainDateTime.compare(new Temporal.PlainDateTime(1976, 11, 18), arg), `${description} does not convert to a valid ISO string (second argument)`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => Temporal.PlainDateTime.compare(arg, new Temporal.PlainDateTime(1976, 11, 18)), `${description} does not convert to a valid ISO string (nested property, first argument)`); + assert.throws(RangeError, () => Temporal.PlainDateTime.compare(new Temporal.PlainDateTime(1976, 11, 18), arg), `${description} does not convert to a valid ISO string (nested property, second argument)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => Temporal.PlainDateTime.compare(arg, new Temporal.PlainDateTime(1976, 11, 18)), `${description} is not a valid property bag and does not convert to a string (first argument)`); + assert.throws(TypeError, () => Temporal.PlainDateTime.compare(new Temporal.PlainDateTime(1976, 11, 18), arg), `${description} is not a valid property bag and does not convert to a string (second argument)`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => Temporal.PlainDateTime.compare(arg, new Temporal.PlainDateTime(1976, 11, 18)), `${description} is not a valid property bag and does not convert to a string (nested property, first argument)`); + assert.throws(TypeError, () => Temporal.PlainDateTime.compare(new Temporal.PlainDateTime(1976, 11, 18), arg), `${description} is not a valid property bag and does not convert to a string (nested property, second argument)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => Temporal.PlainDateTime.compare(arg, new Temporal.PlainDateTime(1976, 11, 18)), `nested undefined calendar property is always a RangeError (first argument)`); +assert.throws(RangeError, () => Temporal.PlainDateTime.compare(new Temporal.PlainDateTime(1976, 11, 18), arg), `nested undefined calendar property is always a RangeError (second argument)`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..9c4c3e75f3f4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/compare/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.compare +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; + +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => Temporal.PlainDateTime.compare(arg, new Temporal.PlainDateTime(1976, 11, 18)), + "reject minus zero as extended year (first argument)" + ); + assert.throws( + RangeError, + () => Temporal.PlainDateTime.compare(new Temporal.PlainDateTime(1976, 11, 18), arg), + "reject minus zero as extended year (second argument)" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/compare/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/compare/argument-wrong-type.js new file mode 100644 index 000000000000..53c739249b54 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/compare/argument-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.compare +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDateTime +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => Temporal.PlainDateTime.compare(arg, new Temporal.PlainDateTime(1976, 11, 18)), `${description} does not convert to a valid ISO string (first argument)`); + assert.throws(RangeError, () => Temporal.PlainDateTime.compare(new Temporal.PlainDateTime(1976, 11, 18), arg), `${description} does not convert to a valid ISO string (second argument)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDateTime, "Temporal.PlainDateTime, object"], + [Temporal.PlainDateTime.prototype, "Temporal.PlainDateTime.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => Temporal.PlainDateTime.compare(arg, new Temporal.PlainDateTime(1976, 11, 18)), `${description} is not a valid property bag and does not convert to a string (first argument)`); + assert.throws(TypeError, () => Temporal.PlainDateTime.compare(new Temporal.PlainDateTime(1976, 11, 18), arg), `${description} is not a valid property bag and does not convert to a string (second argument)`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/compare/basic.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/compare/basic.js index 65f9123e65a2..f41de6639c4c 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/compare/basic.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/compare/basic.js @@ -10,23 +10,16 @@ features: [Temporal] const dt1 = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789); const dt2 = new Temporal.PlainDateTime(2019, 10, 29, 10, 46, 38, 271, 986, 102); +const dt3 = new Temporal.PlainDateTime(2019, 10, 29, 10, 46, 38, 271, 986, 102); +const dt4 = new Temporal.PlainDateTime(2019, 10, 29, 15, 23, 30, 123, 456, 789); +const dt5 = new Temporal.PlainDateTime(1976, 11, 18, 10, 46, 38, 271, 986, 102); -assert.sameValue( - Temporal.PlainDateTime.compare(dt1, dt1), - 0, - "equal" -); +assert.sameValue(Temporal.PlainDateTime.compare(dt1, dt1), 0, "equal"); +assert.sameValue(Temporal.PlainDateTime.compare(dt1, dt2), -1, "smaller/larger"); +assert.sameValue(Temporal.PlainDateTime.compare(dt2, dt1), 1, "larger/smaller"); +assert.sameValue(Temporal.PlainDateTime.compare(dt2, dt3), 0, "equal different object"); +assert.sameValue(Temporal.PlainDateTime.compare(dt3, dt4), -1, "same date, earlier time"); +assert.sameValue(Temporal.PlainDateTime.compare(dt3, dt5), 1, "same time, later date"); -assert.sameValue( - Temporal.PlainDateTime.compare(dt1, dt2), - -1, - "smaller/larger" -); - -assert.sameValue( - Temporal.PlainDateTime.compare(dt2, dt1), - 1, - "larger/smaller" -); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/compare/calendar-ignored.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/compare/calendar-ignored.js new file mode 100644 index 000000000000..a1b517c6a448 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/compare/calendar-ignored.js @@ -0,0 +1,22 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.compare +description: Calendar is not taken into account for the comparison. +features: [Temporal] +---*/ + +const calendar1 = { toString() { throw new Test262Error("should not call calendar1.toString") } }; +const calendar2 = { toString() { throw new Test262Error("should not call calendar2.toString") } }; +const dt1 = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789, calendar1); +const dt2 = new Temporal.PlainDateTime(2019, 10, 29, 10, 46, 38, 271, 986, 102, calendar1); +const dt3 = new Temporal.PlainDateTime(2019, 10, 29, 10, 46, 38, 271, 986, 102, calendar1); +const dt4 = new Temporal.PlainDateTime(2019, 10, 29, 10, 46, 38, 271, 986, 102, calendar2); + +assert.sameValue(Temporal.PlainDateTime.compare(dt1, dt2), -1, "smaller"); +assert.sameValue(Temporal.PlainDateTime.compare(dt2, dt3), 0, "equal with same calendar"); +assert.sameValue(Temporal.PlainDateTime.compare(dt2, dt4), 0, "equal with different calendar"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/compare/leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/compare/leap-second.js new file mode 100644 index 000000000000..89552a4502b6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/compare/leap-second.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.compare +description: Leap second is a valid ISO string for PlainDateTime +features: [Temporal] +---*/ + +let arg = "2016-12-31T23:59:60"; +const result1 = Temporal.PlainDateTime.compare(arg, new Temporal.PlainDateTime(2016, 12, 31, 23, 59, 59)); +assert.sameValue(result1, 0, "leap second is a valid ISO string for PlainDateTime (first argument)"); +const result2 = Temporal.PlainDateTime.compare(new Temporal.PlainDateTime(2016, 12, 31, 23, 59, 59), arg); +assert.sameValue(result2, 0, "leap second is a valid ISO string for PlainDateTime (second argument)"); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; + +const result3 = Temporal.PlainDateTime.compare(arg, new Temporal.PlainDateTime(2016, 12, 31, 23, 59, 59)); +assert.sameValue(result3, 0, "second: 60 is constrained in property bag for PlainDateTime (first argument)"); +const result4 = Temporal.PlainDateTime.compare(new Temporal.PlainDateTime(2016, 12, 31, 23, 59, 59), arg); +assert.sameValue(result4, 0, "second: 60 is constrained in property bag for PlainDateTime (second argument)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/compare/year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/compare/year-zero.js index d1bdf1c987f4..4cd7fdf2c5a1 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/compare/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/compare/year-zero.js @@ -9,16 +9,23 @@ features: [Temporal] ---*/ const ok = new Temporal.PlainDateTime(2000, 5, 2, 15); -const bad = "-000000-12-07T03:24:30"; +const invalidStrings = [ + "-000000-12-07", + "-000000-12-07T03:24:30", + "-000000-12-07T03:24:30+01:00", + "-000000-12-07T03:24:30+00:00[UTC]", +]; -assert.throws(RangeError, - () => Temporal.PlainDateTime.compare(bad,ok), - "Cannot use minus zero as extended year (first argument)" -); +invalidStrings.forEach((arg) => { + assert.throws(RangeError, + () => Temporal.PlainDateTime.compare(arg, ok), + "Cannot use minus zero as extended year (first argument)" + ); -assert.throws(RangeError, - () => Temporal.PlainDateTime.compare(ok, bad), - "Cannot use minus zero as extended year (second argument)" -); + assert.throws(RangeError, + () => Temporal.PlainDateTime.compare(ok, arg), + "Cannot use minus zero as extended year (second argument)" + ); +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-number.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-number.js new file mode 100644 index 000000000000..e0a1b043f6ba --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-number.js @@ -0,0 +1,31 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.from +description: A number is converted to a string, then to Temporal.PlainDateTime +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +let arg = 19761118; + +const result = Temporal.PlainDateTime.from(arg); +TemporalHelpers.assertPlainDateTime(result, 1976, 11, "M11", 18, 0, 0, 0, 0, 0, 0, "19761118 is a valid ISO string for PlainDateTime"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => Temporal.PlainDateTime.from(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDateTime` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-object-month.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-object-month.js new file mode 100644 index 000000000000..bdb8ceb49a18 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-object-month.js @@ -0,0 +1,35 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.from +description: A plain object argument needs to specify a month +features: [Temporal] +---*/ + +assert.throws( + RangeError, + () => Temporal.PlainDateTime.from({year: 1976, month: 11, monthCode: "M12", day: 18}), + "month and monthCode must agree" +); + +assert.throws( + TypeError, + () => Temporal.PlainDateTime.from({year: 1976, month: undefined, monthCode: undefined, day: 18}), + "required prop undefined throws" +); + +assert.throws( + TypeError, + () => Temporal.PlainDateTime.from({year: 1976, day: 18, hour: 15, minute: 23, second: 30, millisecond: 123}), + "required prop missing throws" +); + +assert.throws( + TypeError, + () => Temporal.PlainDateTime.from({year: 1976, months: 11, day: 18}), + "plural \"months\" is not acceptable" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-object.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-object.js new file mode 100644 index 000000000000..8fb7d933656a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-object.js @@ -0,0 +1,43 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.from +description: Plain objects are acceptable +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +TemporalHelpers.assertPlainDateTime( + Temporal.PlainDateTime.from({year: 1976, month: 11, monthCode: "M11", day: 18}), + 1976, 11, "M11", 18, 0, 0, 0, 0, 0, 0, + "plain object with month & month code" +); + +assert.throws( + TypeError, + () => Temporal.PlainDateTime.from({}), + "empty object throws" +); + +TemporalHelpers.assertPlainDateTime( + Temporal.PlainDateTime.from({year: 1976, month: 11, day: 18, millisecond: 123}), + 1976, 11, "M11", 18, 0, 0, 0, 123, 0, 0, + "plain object with month but not month code" +); + +TemporalHelpers.assertPlainDateTime( + Temporal.PlainDateTime.from({year: 1976, monthCode: "M09", day: 18, millisecond: 123}), + 1976, 9, "M09", 18, 0, 0, 0, 123, 0, 0, + "plain object with month code but not month" +); + + +TemporalHelpers.assertPlainDateTime( + Temporal.PlainDateTime.from({year: 1976, month: 11, day: 18, hours: 12}), + 1976, 11, "M11", 18, 0, 0, 0, 0, 0, 0, + "incorrectly-spelled properties (e.g., plural \"hours\") are ignored" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-plaindatetime.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-plaindatetime.js new file mode 100644 index 000000000000..244b3303f682 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-plaindatetime.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.from +description: A PlainDateTime object is copied, not returned directly +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const orig = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 20, 123, 456, 789); +const result = Temporal.PlainDateTime.from(orig); + +TemporalHelpers.assertPlainDateTime( + result, + 1976, 11, "M11", 18, 15, 23, 20, 123, 456, 789, + "PlainDateTime is copied" +); + +assert.notSameValue( + result, + orig, + "When a PlainDateTime is given, the returned value is not the original PlainDateTime" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..50162eb7a0e9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.from +description: Leap second is a valid ISO string for a calendar in a property bag +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = Temporal.PlainDateTime.from(arg); +TemporalHelpers.assertPlainDateTime( + result1, + 1976, 11, "M11", 18, 0, 0, 0, 0, 0, 0, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = Temporal.PlainDateTime.from(arg); +TemporalHelpers.assertPlainDateTime( + result2, + 1976, 11, "M11", 18, 0, 0, 0, 0, 0, 0, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..50462e3f4f84 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-number.js @@ -0,0 +1,43 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.from +description: A number as calendar in a property bag is converted to a string, then to a calendar +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = Temporal.PlainDateTime.from(arg); +TemporalHelpers.assertPlainDateTime(result1, 1976, 11, "M11", 18, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = Temporal.PlainDateTime.from(arg); +TemporalHelpers.assertPlainDateTime(result2, 1976, 11, "M11", 18, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + assert.throws( + RangeError, + () => Temporal.PlainDateTime.from(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; + assert.throws( + RangeError, + () => Temporal.PlainDateTime.from(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..69553d990650 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,47 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.from +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => Temporal.PlainDateTime.from(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => Temporal.PlainDateTime.from(arg), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => Temporal.PlainDateTime.from(arg), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => Temporal.PlainDateTime.from(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => Temporal.PlainDateTime.from(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..a379fe898fe4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.from +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; + +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => Temporal.PlainDateTime.from(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-string-comma-decimal-separator.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-string-comma-decimal-separator.js new file mode 100644 index 000000000000..5bfeb6f2dcd7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-string-comma-decimal-separator.js @@ -0,0 +1,18 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.from +description: Comma may be used as a decimal separator +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +TemporalHelpers.assertPlainDateTime( + Temporal.PlainDateTime.from("1976-11-18T15:23:30,12"), + 1976, 11, "M11", 18, 15, 23, 30, 120, 0, 0, + "comma decimal separator" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-string-invalid.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-string-invalid.js new file mode 100644 index 000000000000..ec48e749fde5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-string-invalid.js @@ -0,0 +1,62 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.from +description: Reject string argument if it cannot be parsed +features: [Temporal] +---*/ + +const invalidStrings = [ + // invalid ISO strings: + "", + "obviously invalid", + "2020-01-00", + "2020-01-32", + "2020-02-30", + "2021-02-29", + "2020-00-01", + "2020-13-01", + "2020-01-01T", + "2020-01-01T25:00:00", + "2020-01-01T01:60:00", + "2020-01-01T01:60:61", + "2020-01-01junk", + "2020-01-01T00:00:00junk", + "2020-01-01T00:00:00+00:00junk", + "2020-01-01T00:00:00+00:00[UTC]junk", + "2020-01-01T00:00:00+00:00[UTC][u-ca=iso8601]junk", + "02020-01-01", + "2020-001-01", + "2020-01-001", + "2020-01-01T001", + "2020-01-01T01:001", + "2020-01-01T01:01:001", + // valid, but forms not supported in Temporal: + "2020-W01-1", + "2020-001", + "+0002020-01-01", + // valid, but this calendar must not exist: + "2020-01-01[u-ca=notexist]", + // may be valid in other contexts, but insufficient information for PlainDateTime: + "2020-01", + "+002020-01", + "01-01", + "2020-W01", + "P1Y", + "-P12Y", + // valid, but outside the supported range: + "-999999-01-01", + "+999999-01-01", +]; + +invalidStrings.forEach((s) => { + assert.throws( + RangeError, + () => Temporal.PlainDateTime.from(s), + `invalid date-time string (${s})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-string-minus-sign.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-string-minus-sign.js new file mode 100644 index 000000000000..cfd7fcd3aa2a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-string-minus-sign.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.from +description: Non-ASCII minus sign is acceptable +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +TemporalHelpers.assertPlainDateTime( + Temporal.PlainDateTime.from("1976-11-18T15:23:30.12\u221202:00"), + 1976, 11, "M11", 18, 15, 23, 30, 120, 0, 0, + "variant minus sign (offset)" +); + +TemporalHelpers.assertPlainDateTime( + Temporal.PlainDateTime.from("\u2212009999-11-18T15:23:30.12"), + -9999, 11, "M11", 18, 15, 23, 30, 120, 0, 0, + "variant minus sign (leading minus)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-string-offset.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-string-offset.js new file mode 100644 index 000000000000..6ea4739a0c51 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-string-offset.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.from +description: Extended format may be used +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const expected = [1976, 11, "M11", 18, 15, 23, 30, 100, 0, 0]; + +const strs = [ + "1976-11-18T152330.1+00:00", + "19761118T15:23:30.1+00:00", + "1976-11-18T15:23:30.1+0000", + "1976-11-18T152330.1+0000", + "19761118T15:23:30.1+0000", + "19761118T152330.1+00:00", + "19761118T152330.1+0000", + "+001976-11-18T152330.1+00:00", + "+0019761118T15:23:30.1+00:00", + "+001976-11-18T15:23:30.1+0000", + "+001976-11-18T152330.1+0000", + "+0019761118T15:23:30.1+0000", + "+0019761118T152330.1+00:00", + "+0019761118T152330.1+0000" +]; + +strs.forEach((s) => { + TemporalHelpers.assertPlainDateTime( + Temporal.PlainDateTime.from(s), + ...expected, + `mixture of basic and extended format (${s})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-string-optional-data.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-string-optional-data.js new file mode 100644 index 000000000000..0cfadf4176f2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-string-optional-data.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.from +description: Some parts of a string argument may be omitted +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +TemporalHelpers.assertPlainDateTime( + Temporal.PlainDateTime.from("1976-11-18T15:23:30+00"), + 1976, 11, "M11", 18, 15, 23, 30, 0, 0, 0, + "optional parts (no minute after offset)" +); + +TemporalHelpers.assertPlainDateTime( + Temporal.PlainDateTime.from("1976-11-18T15"), + 1976, 11, "M11", 18, 15, 0, 0, 0, 0, 0, + "optional parts (no minute in time part)" +); + +TemporalHelpers.assertPlainDateTime( + Temporal.PlainDateTime.from("1976-11-18"), + 1976, 11, "M11", 18, 0, 0, 0, 0, 0, 0, + "optional parts (no time part)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-string-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-string-out-of-range.js new file mode 100644 index 000000000000..0d79dded5b9f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-string-out-of-range.js @@ -0,0 +1,35 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.from +description: Invalid ISO string not acceptable even with overflow = constrain +features: [Temporal] +---*/ + +assert.throws( + RangeError, + () => Temporal.PlainDateTime.from("2020-13-34T24:60", {}), + "constrain has no effect on invalid ISO string (empty options argument)" +); + +assert.throws( + RangeError, + () => Temporal.PlainDateTime.from("2020-13-34T24:60", () => {}), + "constrain has no effect on invalid ISO string (nullary empty object function argument)" +); + +assert.throws( + RangeError, + () => Temporal.PlainDateTime.from("2020-13-34T24:60", {overflow: "constrain"}), + "overflow = constrain has no effect on invalid ISO string" +); + +assert.throws( + RangeError, + () => Temporal.PlainDateTime.from("2020-13-34T24:60", {overflow: "reject"}), + "overflow = reject has no effect on invalid ISO string" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-string-subsecond.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-string-subsecond.js new file mode 100644 index 000000000000..eba9a4c8a1f2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-string-subsecond.js @@ -0,0 +1,72 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.from +description: Up to nine digits of sub-second precision are acceptable +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +TemporalHelpers.assertPlainDateTime( + Temporal.PlainDateTime.from("1976-11-18T15:23:30.1"), + 1976, 11, "M11", 18, 15, 23, 30, 100, 0, 0, + "various precisions are possible (one decimal digit)" +); + +TemporalHelpers.assertPlainDateTime( + Temporal.PlainDateTime.from("1976-11-18T15:23:30.12"), + 1976, 11, "M11", 18, 15, 23, 30, 120, 0, 0, + "various precisions are possible (two decimal digits)" +); + +TemporalHelpers.assertPlainDateTime( + Temporal.PlainDateTime.from("1976-11-18T15:23:30.123"), + 1976, 11, "M11", 18, 15, 23, 30, 123, 0, 0, + "various precisions are possible (three decimal digits)" +); + +TemporalHelpers.assertPlainDateTime( + Temporal.PlainDateTime.from("1976-11-18T15:23:30.1234"), + 1976, 11, "M11", 18, 15, 23, 30, 123, 400, 0, + "various precisions are possible (four decimal digits)" +); + +TemporalHelpers.assertPlainDateTime( + Temporal.PlainDateTime.from("1976-11-18T15:23:30.12345"), + 1976, 11, "M11", 18, 15, 23, 30, 123, 450, 0, + "various precisions are possible (five decimal digits)" +); + +TemporalHelpers.assertPlainDateTime( + Temporal.PlainDateTime.from("1976-11-18T15:23:30.123456"), + 1976, 11, "M11", 18, 15, 23, 30, 123, 456, 0, + "various precisions are possible (six decimal digits)" +); + +TemporalHelpers.assertPlainDateTime( + Temporal.PlainDateTime.from("1976-11-18T15:23:30.1234567"), + 1976, 11, "M11", 18, 15, 23, 30, 123, 456, 700, + "various precisions are possible (seven decimal digits)" +); + +TemporalHelpers.assertPlainDateTime( + Temporal.PlainDateTime.from("1976-11-18T15:23:30.12345678"), + 1976, 11, "M11", 18, 15, 23, 30, 123, 456, 780, + "various precisions are possible (eight decimal digits)" +); + +TemporalHelpers.assertPlainDateTime( + Temporal.PlainDateTime.from("1976-11-18T15:23:30.123456789"), + 1976, 11, "M11", 18, 15, 23, 30, 123, 456, 789, + "various precisions are possible (nine decimal digits)" +); + +assert.throws( + RangeError, + () => Temporal.PlainDateTime.from("1976-11-18T15:23:30.1234567891"), + "ten decimal digits is too much" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-string-time-separators.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-string-time-separators.js new file mode 100644 index 000000000000..1b82a8084ac8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-string-time-separators.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.from +description: Time separator in string argument can vary +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const expected = [1976, 11, "M11", 18, 15, 23, 0, 0, 0, 0]; + +TemporalHelpers.assertPlainDateTime( + Temporal.PlainDateTime.from("1976-11-18T15:23"), + ...expected, + "variant time separators (uppercase T)" +); + +TemporalHelpers.assertPlainDateTime( + Temporal.PlainDateTime.from("1976-11-18t15:23"), + ...expected, + "variant time separators (lowercase T)" +); + +TemporalHelpers.assertPlainDateTime( + Temporal.PlainDateTime.from("1976-11-18 15:23"), + ...expected, + "variant time separators (space between date and time)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-string-timezone.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-string-timezone.js new file mode 100644 index 000000000000..9381475c7937 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-string-timezone.js @@ -0,0 +1,18 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.from +description: Timezone, if specified, is ignored +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +TemporalHelpers.assertPlainDateTime( + Temporal.PlainDateTime.from("2020-01-01T01:23:45[Asia/Kolkata]"), + 2020, 1, "M01", 1, 1, 23, 45, 0, 0, 0, + "ignores if a timezone is specified" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-string.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-string.js new file mode 100644 index 000000000000..f07549798844 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-string.js @@ -0,0 +1,36 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.from +description: String arguments are acceptable +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +TemporalHelpers.assertPlainDateTime( + Temporal.PlainDateTime.from("1976-11-18T15:23:30"), + 1976, 11, "M11", 18, 15, 23, 30, 0, 0, 0, + "date and time (no subseconds)" +); + +TemporalHelpers.assertPlainDateTime( + Temporal.PlainDateTime.from("1976-11-18T15:23:30.001"), + 1976, 11, "M11", 18, 15, 23, 30, 1, 0, 0, + "date and time (millisecond)" +); + +TemporalHelpers.assertPlainDateTime( + Temporal.PlainDateTime.from("1976-11-18T15:23:30.001123"), + 1976, 11, "M11", 18, 15, 23, 30, 1, 123, 0, + "date and time (microsecond)" +); + +TemporalHelpers.assertPlainDateTime( + Temporal.PlainDateTime.from("1976-11-18T15:23:30.001123456"), + 1976, 11, "M11", 18, 15, 23, 30, 1, 123, 456, + "date and time (nanosecond)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-wrong-type.js new file mode 100644 index 000000000000..d102e9cb5864 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/argument-wrong-type.js @@ -0,0 +1,37 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.from +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDateTime +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => Temporal.PlainDateTime.from(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDateTime, "Temporal.PlainDateTime, object"], + [Temporal.PlainDateTime.prototype, "Temporal.PlainDateTime.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => Temporal.PlainDateTime.from(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/leap-second.js new file mode 100644 index 000000000000..73ec3908c3d3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/leap-second.js @@ -0,0 +1,43 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.from +description: Leap second is a valid ISO string for PlainDateTime +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +let arg = "2016-12-31T23:59:60"; + +const result1 = Temporal.PlainDateTime.from(arg); +TemporalHelpers.assertPlainDateTime( + result1, + 2016, 12, "M12", 31, 23, 59, 59, 0, 0, 0, + "leap second is a valid ISO string for PlainDateTime" +); + +const result2 = Temporal.PlainDateTime.from(arg); +TemporalHelpers.assertPlainDateTime( + result2, + 2016, 12, "M12", 31, 23, 59, 59, 0, 0, 0, + "leap second is a valid ISO string for PlainDateTime even with overflow: reject" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; + +const result3 = Temporal.PlainDateTime.from(arg); +TemporalHelpers.assertPlainDateTime( + result3, + 2016, 12, "M12", 31, 23, 59, 59, 0, 0, 0, + "second: 60 is constrained in property bag for PlainDateTime" +); + +assert.throws( + RangeError, + () => Temporal.PlainDateTime.from(arg, { overflow: "reject" }), + "second: 60 is rejected in property bag for PlainDateTime with overflow: reject" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/limits.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/limits.js new file mode 100644 index 000000000000..57438f2cf2d8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/limits.js @@ -0,0 +1,73 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.from +description: Checking limits of representable PlainDateTime +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +["reject", "constrain"].forEach((overflow) => { + assert.throws( + RangeError, + () => Temporal.PlainDateTime.from({ year: -271821, month: 4, day: 19 }, { overflow }), + `negative out of bounds (plain object, overflow = ${overflow})` + ); + assert.throws( + RangeError, + () => Temporal.PlainDateTime.from({ year: 275760, month: 9, day: 14 }, { overflow }), + `positive out of bounds (plain object, overflow = ${overflow})` + ); +}); + +TemporalHelpers.assertPlainDateTime( + Temporal.PlainDateTime.from({ year: -271821, month: 4, day: 19, nanosecond: 1 }), + -271821, 4, "M04", 19, 0, 0, 0, 0, 0, 1, + "construct from property bag (negative boundary)" +); + +TemporalHelpers.assertPlainDateTime( + Temporal.PlainDateTime.from( + { + year: 275760, + month: 9, + day: 13, + hour: 23, + minute: 59, + second: 59, + millisecond: 999, + microsecond: 999, + nanosecond: 999 + } + ), + 275760, 9, "M09", 13, 23, 59, 59, 999, 999, 999, + "construct from property bag (positive boundary)" +); + +assert.throws( + RangeError, + () => Temporal.PlainDateTime.from("-271821-04-19T00:00"), + "out-of-bounds ISO string (negative case)" +); + +assert.throws( + RangeError, + () => Temporal.PlainDateTime.from("+275760-09-14T00:00"), + "out-of-bounds ISO string (positive case)" +); + +TemporalHelpers.assertPlainDateTime( + Temporal.PlainDateTime.from("-271821-04-19T00:00:00.000000001"), + -271821, 4, "M04", 19, 0, 0, 0, 0, 0, 1, + "boundary ISO string (negative case)" +); + +TemporalHelpers.assertPlainDateTime( + Temporal.PlainDateTime.from("+275760-09-13T23:59:59.999999999"), + 275760, 9, "M09", 13, 23, 59, 59, 999, 999, 999, + "boundary ISO string (positive case)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/options-wrong-type.js new file mode 100644 index 000000000000..4a7dbdda3780 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/options-wrong-type.js @@ -0,0 +1,25 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.from +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +for (const value of badOptions) { + assert.throws(TypeError, () => Temporal.PlainDateTime.from({ year: 1976, month: 11, day: 18 }, value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/overflow-default-constrain.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/overflow-default-constrain.js new file mode 100644 index 000000000000..f6aea8a40885 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/overflow-default-constrain.js @@ -0,0 +1,40 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.from +description: By default, overflow = constrain +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const date = {year: 2019, month: 1, day: 32}; +const data = [2019, 1, "M01", 31, 0, 0, 0, 0, 0, 0]; + +TemporalHelpers.assertPlainDateTime( + Temporal.PlainDateTime.from(date), + ...data, + "by default, overflow is constrain (overflow options argument absent)" +); + +TemporalHelpers.assertPlainDateTime( + Temporal.PlainDateTime.from(date, {}), + ...data, + "by default, overflow is constrain (options argument is empty plain object)" +); + +TemporalHelpers.assertPlainDateTime( + Temporal.PlainDateTime.from(date, () => {}), + ...data, + "by default, overflow is constrain (options argument is empty function)" +); + + +TemporalHelpers.assertPlainDateTime( + Temporal.PlainDateTime.from(date, {overflow: "constrain"}), + ...data, + "by default, overflow is constrain (overflow options argument present)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/overflow-reject.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/overflow-reject.js new file mode 100644 index 000000000000..d2f1cfecca78 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/overflow-reject.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.from +description: Possibly throw if overflow is reject +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +TemporalHelpers.assertPlainDateTime( + Temporal.PlainDateTime.from({year: 2019, month: 1, day: 31}, {overflow: "reject"}), + 2019, 1, "M01", 31, 0, 0, 0, 0, 0, 0, + "overflow reject, acceptable argument" +); + +assert.throws( + RangeError, + () => Temporal.PlainDateTime.from({year: 2019, month: 1, day: 32}, {overflow: "reject"}), + "overflow reject, unacceptable argument" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/year-zero.js index 6962a671d48e..0cc025a1ee3f 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/from/year-zero.js @@ -9,13 +9,16 @@ features: [Temporal, arrow-function] ---*/ const invalidStrings = [ + "-000000-12-07", "-000000-12-07T03:24:30", - "-000000-12-07T03:24:30+01:00[UTC]" + "-000000-12-07T03:24:30+01:00", + "-000000-12-07T03:24:30+00:00[UTC]", ]; + invalidStrings.forEach((arg) => { assert.throws( RangeError, - () => { Temporal.PlainDateTime.from(arg); }, + () => Temporal.PlainDateTime.from(arg), "reject minus zero as extended year" ); }); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/limits.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/limits.js new file mode 100644 index 000000000000..7b7c09d352b1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/limits.js @@ -0,0 +1,22 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime +description: Checking limits of representable PlainDateTime +features: [Temporal] +---*/ + +assert.throws( + RangeError, + () => new Temporal.PlainDateTime(-271821, 4, 19, 0, 0, 0, 0, 0, 0), + "negative year out of bounds" +); +assert.throws( + RangeError, + () => new Temporal.PlainDateTime(275760, 9, 14, 0, 0, 0, 0, 0, 0), + "positive year out of bounds" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/add/limits.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/add/limits.js new file mode 100644 index 000000000000..2aabcc752969 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/add/limits.js @@ -0,0 +1,28 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.add +description: Checking limits of representable PlainDateTime +features: [Temporal] +---*/ + +const min = new Temporal.PlainDateTime(-271821, 4, 19, 0, 0, 0, 0, 0, 1); +const max = new Temporal.PlainDateTime(275760, 9, 13, 23, 59, 59, 999, 999, 999); + +["reject", "constrain"].forEach((overflow) => { + assert.throws( + RangeError, + () => max.add({ nanoseconds: 1 }, { overflow }), + `adding 1 nanosecond beyond maximum limit (overflow = ${overflow})` + ); + assert.throws( + RangeError, + () => min.add({ nanoseconds: -1 }, { overflow }), + `adding -1 nanosecond beyond minimum limit (overflow = ${overflow})` + ); + +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/add/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/add/options-wrong-type.js new file mode 100644 index 000000000000..4fe46d50770e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/add/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.add +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.PlainDateTime(2000, 5, 2); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.add({ months: 1 }, value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/equals/argument-number.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/equals/argument-number.js new file mode 100644 index 000000000000..095fe1c01a39 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/equals/argument-number.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.equals +description: A number is converted to a string, then to Temporal.PlainDateTime +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDateTime(1976, 11, 18); + +let arg = 19761118; + +const result = instance.equals(arg); +assert.sameValue(result, true, "19761118 is a valid ISO string for PlainDateTime"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.equals(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDateTime` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/equals/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/equals/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..be43e3b6d54f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/equals/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,31 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.equals +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDateTime(1976, 11, 18); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.equals(arg); +assert.sameValue( + result1, + true, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.equals(arg); +assert.sameValue( + result2, + true, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/equals/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/equals/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..ac8e71867c7e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/equals/argument-propertybag-calendar-number.js @@ -0,0 +1,44 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.equals +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDateTime(1976, 11, 18); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.equals(arg); +assert.sameValue(result1, true, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.equals(arg); +assert.sameValue(result2, true, "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + assert.throws( + RangeError, + () => instance.equals(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.equals(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/equals/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/equals/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..27a7b1a73e94 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/equals/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.equals +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.equals(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.equals(arg), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.equals(arg), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.equals(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.equals(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/equals/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/equals/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..6b15768d9d04 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/equals/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.equals +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.equals(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/equals/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/equals/argument-wrong-type.js index fd3742fdf23c..e8f2b1a5aed0 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/equals/argument-wrong-type.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/equals/argument-wrong-type.js @@ -1,23 +1,39 @@ // |reftest| skip -- Temporal is not supported -// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// Copyright (C) 2022 Igalia, S.L. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. /*--- esid: sec-temporal.plaindatetime.prototype.equals -description: Appropriate error thrown when argument cannot be converted to a valid string -features: [Symbol, Temporal] +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDateTime +features: [BigInt, Symbol, Temporal] ---*/ -const instance = Temporal.PlainDateTime.from({ year: 2000, month: 5, day: 2, minute: 34, second: 56, millisecond: 987, microsecond: 654, nanosecond: 321 }); +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); -assert.throws(RangeError, () => instance.equals(undefined), "undefined"); -assert.throws(RangeError, () => instance.equals(null), "null"); -assert.throws(RangeError, () => instance.equals(true), "true"); -assert.throws(RangeError, () => instance.equals(""), "empty string"); -assert.throws(TypeError, () => instance.equals(Symbol()), "symbol"); -assert.throws(RangeError, () => instance.equals(1), "1"); -assert.throws(TypeError, () => instance.equals({}), "plain object"); -assert.throws(TypeError, () => instance.equals(Temporal.PlainDateTime), "Temporal.PlainDateTime"); -assert.throws(TypeError, () => instance.equals(Temporal.PlainDateTime.prototype), "Temporal.PlainDateTime.prototype"); +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.equals(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDateTime, "Temporal.PlainDateTime, object"], + [Temporal.PlainDateTime.prototype, "Temporal.PlainDateTime.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.equals(arg), `${description} is not a valid property bag and does not convert to a string`); +} reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/equals/basic.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/equals/basic.js index 6a19a4256506..4560c15dd891 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/equals/basic.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/equals/basic.js @@ -10,8 +10,14 @@ features: [Temporal] const dt1 = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789); const dt2 = new Temporal.PlainDateTime(2019, 10, 29, 10, 46, 38, 271, 986, 102); +const dt3 = new Temporal.PlainDateTime(2019, 10, 29, 10, 46, 38, 271, 986, 102); +const dt4 = new Temporal.PlainDateTime(2019, 10, 29, 15, 23, 30, 123, 456, 789); +const dt5 = new Temporal.PlainDateTime(1976, 11, 18, 10, 46, 38, 271, 986, 102); assert.sameValue(dt1.equals(dt1), true, "equal"); assert.sameValue(dt1.equals(dt2), false, "unequal"); +assert.sameValue(dt2.equals(dt3), true, "equal with different objects"); +assert.sameValue(dt2.equals(dt4), false, "same date, different time"); +assert.sameValue(dt2.equals(dt5), false, "same time, different date"); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/equals/calendar-checked.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/equals/calendar-checked.js new file mode 100644 index 000000000000..1756232d5e1b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/equals/calendar-checked.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.equals +description: Calendar is taken into account if the ISO data is equal +includes: [compareArray.js,temporalHelpers.js] +features: [Temporal] +---*/ + +const actual = []; +const calendar1 = TemporalHelpers.toPrimitiveObserver(actual, "A", "calendar1"); +const calendar2 = TemporalHelpers.toPrimitiveObserver(actual, "A", "calendar2"); +const calendar3 = TemporalHelpers.toPrimitiveObserver(actual, "B", "calendar3"); +const dt1 = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789, calendar1); +const dt1b = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789, calendar1); +const dt2 = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789, calendar2); +const dt3 = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789, calendar3); + +assert.sameValue(dt1.equals(dt1b), true, "same calendar object"); +assert.compareArray(actual, []); + +assert.sameValue(dt1.equals(dt2), true, "same calendar string"); +assert.compareArray(actual, ["get calendar1.toString", "call calendar1.toString", "get calendar2.toString", "call calendar2.toString"]); + +actual.splice(0, actual.length); // empty it for the next check +assert.sameValue(dt1.equals(dt3), false, "different calendar string"); +assert.compareArray(actual, ["get calendar1.toString", "call calendar1.toString", "get calendar3.toString", "call calendar3.toString"]); + +const calendar4 = { toString() { throw new Test262Error("should not call calendar4.toString") } }; +const calendar5 = { toString() { throw new Test262Error("should not call calendar5.toString") } }; +const dt4 = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789, calendar4); +const dt5 = new Temporal.PlainDateTime(2019, 10, 29, 10, 46, 38, 271, 986, 102, calendar4); +const dt6 = new Temporal.PlainDateTime(2019, 10, 29, 10, 46, 38, 271, 986, 102, calendar5); +assert.sameValue(dt4.equals(dt5), false, "not equal same calendar"); +assert.sameValue(dt4.equals(dt6), false, "not equal different calendar"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/equals/leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/equals/leap-second.js new file mode 100644 index 000000000000..d92425d8cbdd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/equals/leap-second.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.equals +description: Leap second is a valid ISO string for PlainDateTime +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDateTime(2016, 12, 31, 23, 59, 59); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.equals(arg); +assert.sameValue( + result1, + true, + "leap second is a valid ISO string for PlainDateTime" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.equals(arg); +assert.sameValue( + result2, + true, + "second: 60 is ignored in property bag for PlainDateTime" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/equals/year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/equals/year-zero.js index 4ca9b24c241e..48c33a2603ac 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/equals/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/equals/year-zero.js @@ -9,14 +9,16 @@ features: [Temporal, arrow-function] ---*/ const invalidStrings = [ + "-000000-12-07", "-000000-12-07T03:24:30", - "-000000-12-07T03:24:30+01:00[UTC]" + "-000000-12-07T03:24:30+01:00", + "-000000-12-07T03:24:30+00:00[UTC]", ]; const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); invalidStrings.forEach((arg) => { assert.throws( RangeError, - () => { instance.equals(arg); }, + () => instance.equals(arg), "reject minus zero as extended year" ); }); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/balance.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/balance.js new file mode 100644 index 000000000000..adbde3ceb9c7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/balance.js @@ -0,0 +1,22 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.round +description: Rounding balances to the next smallest unit +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const dt = new Temporal.PlainDateTime(1976, 11, 18, 23, 59, 59, 999, 999, 999); + +["day", "hour", "minute", "second", "millisecond", "microsecond"].forEach((smallestUnit) => { + TemporalHelpers.assertPlainDateTime( + dt.round({ smallestUnit }), + 1976, 11, "M11", 19, 0, 0, 0, 0, 0, 0, + `balances to next ${smallestUnit}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/limits.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/limits.js new file mode 100644 index 000000000000..0abe722e3de9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/limits.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.round +description: Checking limits of representable PlainDateTime +features: [Temporal] +---*/ + +const min = new Temporal.PlainDateTime(-271821, 4, 19, 0, 0, 0, 0, 0, 1); +const max = new Temporal.PlainDateTime(275760, 9, 13, 23, 59, 59, 999, 999, 999); + +["day", "hour", "minute", "second", "millisecond", "microsecond"].forEach((smallestUnit) => { + assert.throws( + RangeError, + () => min.round({ smallestUnit, roundingMode: "floor" }), + `rounding beyond limit (unit = ${smallestUnit}, rounding mode = floor)` + ); + assert.throws( + RangeError, + () => max.round({ smallestUnit, roundingMode: "ceil" }), + `rounding beyond limit (unit = ${smallestUnit}, rounding mode = ceil)` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/options-wrong-type.js new file mode 100644 index 000000000000..3a06e282fef7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/options-wrong-type.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.round +description: TypeError thrown when options argument is missing or a non-string primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + undefined, + null, + true, + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.PlainDateTime(2000, 5, 2); +assert.throws(TypeError, () => instance.round(), "TypeError on missing options argument"); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.round(value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/rounding-direction.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/rounding-direction.js new file mode 100644 index 000000000000..660856189ac6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/rounding-direction.js @@ -0,0 +1,34 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.round +description: Rounding down is towards the Big Bang, not the epoch or 1 BCE +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDateTime(-99, 12, 15, 12, 0, 0, 500); +TemporalHelpers.assertPlainDateTime( + instance.round({ smallestUnit: "second", roundingMode: "floor" }), + -99, 12, "M12", 15, 12, 0, 0, 0, 0, 0, + "Rounding down is towards the Big Bang, not the epoch or 1 BCE (roundingMode floor)" +); +TemporalHelpers.assertPlainDateTime( + instance.round({ smallestUnit: "second", roundingMode: "trunc" }), + -99, 12, "M12", 15, 12, 0, 0, 0, 0, 0, + "Rounding down is towards the Big Bang, not the epoch or 1 BCE (roundingMode trunc)" +); +TemporalHelpers.assertPlainDateTime( + instance.round({ smallestUnit: "second", roundingMode: "ceil" }), + -99, 12, "M12", 15, 12, 0, 1, 0, 0, 0, + "Rounding up is away from the Big Bang, not the epoch or 1 BCE (roundingMode ceil)" +); +TemporalHelpers.assertPlainDateTime( + instance.round({ smallestUnit: "second", roundingMode: "halfExpand" }), + -99, 12, "M12", 15, 12, 0, 1, 0, 0, 0, + "Rounding up is away from the Big Bang, not the epoch or 1 BCE (roundingMode halfExpand)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/roundingincrement-divides.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/roundingincrement-divides.js new file mode 100644 index 000000000000..d9c398342b42 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/roundingincrement-divides.js @@ -0,0 +1,56 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.round +description: Rounding increment should properly divide the relevant time unit +features: [Temporal] +---*/ + +const dt = new Temporal.PlainDateTime(1976, 11, 18, 14, 23, 30, 123, 456, 789); + +[1, 2, 3, 4, 6, 8, 12].forEach((roundingIncrement) => { + assert.sameValue( + dt.round({ smallestUnit: "hour", roundingIncrement }) instanceof Temporal.PlainDateTime, + true, + `valid hour increments divide into 24 (rounding increment = ${roundingIncrement})`); +}); + +["minute", "second"].forEach((smallestUnit) => { + [1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30].forEach((roundingIncrement) => { + assert.sameValue( + dt.round({ smallestUnit, roundingIncrement }) instanceof Temporal.PlainDateTime, + true, + `valid ${smallestUnit} increments divide into 60 (rounding increment = ${roundingIncrement})` + ); + }); +}); + +["millisecond", "microsecond", "nanosecond"].forEach((smallestUnit) => { + [1, 2, 4, 5, 8, 10, 20, 25, 40, 50, 100, 125, 200, 250, 500].forEach((roundingIncrement) => { + assert.sameValue( + dt.round({ smallestUnit, roundingIncrement }) instanceof Temporal.PlainDateTime, + true, + `valid ${smallestUnit} increments divide into 1000 (rounding increment = ${roundingIncrement})`); + }); +}); + +const nextIncrements = { + "hour": 24, + "minute": 60, + "second": 60, + "millisecond": 1000, + "microsecond": 1000, + "nanosecond": 1000 +}; + +Object.entries(nextIncrements).forEach(([unit, next]) => { + assert.throws( + RangeError, + () => dt.round({ smallestUnit: unit, roundingIncrement: next }), + `throws on increments that are equal to the next highest (unit = ${unit}, increment = ${next})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/roundingincrement-does-not-divide.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/roundingincrement-does-not-divide.js new file mode 100644 index 000000000000..9a88e0fd61a7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/roundingincrement-does-not-divide.js @@ -0,0 +1,21 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.round +description: Throw exception if the rounding unit does not properly divide the relevant time unit +features: [Temporal] +---*/ + +const dt = new Temporal.PlainDateTime(1976, 11, 18, 14, 23, 30, 123, 456, 789); +const units = ["day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond"]; +units.forEach((unit) => { + assert.throws( + RangeError, + () => dt.round({ smallestUnit: unit, roundingIncrement: 29 }), + `throws on increments that do not divide evenly into the next highest (unit = ${unit})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/roundingincrement-one-day.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/roundingincrement-one-day.js new file mode 100644 index 000000000000..a366c618af62 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/roundingincrement-one-day.js @@ -0,0 +1,20 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.round +description: One day is a valid rounding increment +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const dt = new Temporal.PlainDateTime(1976, 11, 18, 14, 23, 30, 123, 456, 789); + +TemporalHelpers.assertPlainDateTime( + dt.round({ smallestUnit: "day", roundingIncrement: 1 }), + 1976, 11, "M11", 19, 0, 0, 0, 0, 0, 0, + "1 day is a valid increment" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/roundingmode-basic.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/roundingmode-basic.js new file mode 100644 index 000000000000..69c617563e88 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/roundingmode-basic.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.round +description: Basic checks for rounding mode +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const dt = new Temporal.PlainDateTime(1976, 11, 18, 14, 23, 30, 123, 456, 789); + +TemporalHelpers.assertPlainDateTime( + dt.round({ smallestUnit: "hour", roundingIncrement: 4 }), + 1976, 11, "M11", 18, 16, 0, 0, 0, 0, 0, + "rounds to an increment of hours" +); + +TemporalHelpers.assertPlainDateTime( + dt.round({ smallestUnit: "minute", roundingIncrement: 15 }), + 1976, 11, "M11", 18, 14, 30, 0, 0, 0, 0, + "rounds to an increment of minutes" +); + +TemporalHelpers.assertPlainDateTime( + dt.round({ smallestUnit: "second", roundingIncrement: 30 }), + 1976, 11, "M11", 18, 14, 23, 30, 0, 0, 0, + "rounds to an increment of seconds" +); + +TemporalHelpers.assertPlainDateTime( + dt.round({ smallestUnit: "millisecond", roundingIncrement: 10 }), + 1976, 11, "M11", 18, 14, 23, 30, 120, 0, 0, + "rounds to an increment of milliseconds" +); + +TemporalHelpers.assertPlainDateTime( + dt.round({ smallestUnit: "microsecond", roundingIncrement: 10 }), + 1976, 11, "M11", 18, 14, 23, 30, 123, 460, 0, + "rounds to an increment of microseconds" +); + +TemporalHelpers.assertPlainDateTime( + dt.round({ smallestUnit: "nanosecond", roundingIncrement: 10 }), + 1976, 11, "M11", 18, 14, 23, 30, 123, 456, 790, + "rounds to an increment of nanoseconds" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/roundingmode-ceil-basic.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/roundingmode-ceil-basic.js new file mode 100644 index 000000000000..e556d51aa04e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/roundingmode-ceil-basic.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.round +description: Basic checks for ceiling rounding mode +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const dt = new Temporal.PlainDateTime(1976, 11, 18, 14, 23, 30, 123, 456, 789); + +const incrementOneCeil = { + "day": [1976, 11, "M11", 19, 0, 0, 0, 0, 0, 0], + "hour": [1976, 11, "M11", 18, 15, 0, 0, 0, 0, 0], + "minute": [1976, 11, "M11", 18, 14, 24, 0, 0, 0, 0], + "second": [1976, 11, "M11", 18, 14, 23, 31, 0, 0, 0], + "millisecond": [1976, 11, "M11", 18, 14, 23, 30, 124, 0, 0], + "microsecond": [1976, 11, "M11", 18, 14, 23, 30, 123, 457, 0], + "nanosecond": [1976, 11, "M11", 18, 14, 23, 30, 123, 456, 789] +}; + +Object.entries(incrementOneCeil).forEach(([smallestUnit, expected]) => { + TemporalHelpers.assertPlainDateTime( + dt.round({ smallestUnit, roundingMode: "ceil" }), + ...expected, + `rounds up to ${smallestUnit} (ceil)`, + undefined + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/roundingmode-floor-basic.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/roundingmode-floor-basic.js new file mode 100644 index 000000000000..485b598a594b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/roundingmode-floor-basic.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.round +description: Basic checks for the floor rounding mode +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const dt = new Temporal.PlainDateTime(1976, 11, 18, 14, 23, 30, 123, 456, 789); + +const incrementOneFloor = { + "day": [1976, 11, "M11", 18, 0, 0, 0, 0, 0, 0], + "hour": [1976, 11, "M11", 18, 14, 0, 0, 0, 0, 0], + "minute": [1976, 11, "M11", 18, 14, 23, 0, 0, 0, 0], + "second": [1976, 11, "M11", 18, 14, 23, 30, 0, 0, 0], + "millisecond": [1976, 11, "M11", 18, 14, 23, 30, 123, 0, 0], + "microsecond": [1976, 11, "M11", 18, 14, 23, 30, 123, 456, 0], + "nanosecond": [1976, 11, "M11", 18, 14, 23, 30, 123, 456, 789] +}; + +Object.entries(incrementOneFloor).forEach(([smallestUnit, expected]) => { + TemporalHelpers.assertPlainDateTime( + dt.round({ smallestUnit, roundingMode: "floor" }), + ...expected, + `rounds down to ${smallestUnit} (floor)` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/roundingmode-halfexpand-basic.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/roundingmode-halfexpand-basic.js new file mode 100644 index 000000000000..2b820b6abbe9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/roundingmode-halfexpand-basic.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.round +description: Basic checks for half-expand rounding mode +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const dt = new Temporal.PlainDateTime(1976, 11, 18, 14, 23, 30, 123, 456, 789); + +const incrementOneNearest = { + "day": [1976, 11, "M11", 19, 0, 0, 0, 0, 0, 0], + "hour": [1976, 11, "M11", 18, 14, 0, 0, 0, 0, 0], + "minute": [1976, 11, "M11", 18, 14, 24, 0, 0, 0, 0], + "second": [1976, 11, "M11", 18, 14, 23, 30, 0, 0, 0], + "millisecond": [1976, 11, "M11", 18, 14, 23, 30, 123, 0, 0], + "microsecond": [1976, 11, "M11", 18, 14, 23, 30, 123, 457, 0], + "nanosecond": [1976, 11, "M11", 18, 14, 23, 30, 123, 456, 789] +}; + +Object.entries(incrementOneNearest).forEach(([smallestUnit, expected]) => { + TemporalHelpers.assertPlainDateTime( + dt.round({ smallestUnit, roundingMode: "halfExpand" }), + ...expected, + `rounds to nearest ${smallestUnit} (half-expand)`, + undefined + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/roundingmode-halfexpand-is-default.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/roundingmode-halfexpand-is-default.js new file mode 100644 index 000000000000..ae1c2ece325b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/roundingmode-halfexpand-is-default.js @@ -0,0 +1,34 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.round +description: Half-expand is the default rounding mode +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const dt = new Temporal.PlainDateTime(1976, 11, 18, 14, 23, 30, 123, 456, 789); + +const units = { + "day": [1976, 11, "M11", 19, 0, 0, 0, 0, 0, 0], + "hour": [1976, 11, "M11", 18, 14, 0, 0, 0, 0, 0], + "minute": [1976, 11, "M11", 18, 14, 24, 0, 0, 0, 0], + "second": [1976, 11, "M11", 18, 14, 23, 30, 0, 0, 0], + "millisecond": [1976, 11, "M11", 18, 14, 23, 30, 123, 0, 0], + "microsecond": [1976, 11, "M11", 18, 14, 23, 30, 123, 457, 0], + "nanosecond": [1976, 11, "M11", 18, 14, 23, 30, 123, 456, 789] +}; + +const expected = [1976, 11, "M11", 18, 0, 0, 0, 0, 0, 0]; + +Object.entries(units).forEach(([unit, expected]) => { + TemporalHelpers.assertPlainDateTime( + dt.round({ smallestUnit: unit }), + ...expected, + `halfExpand is the default (smallest unit = ${unit}, rounding mode absent)` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/roundingmode-trunc-basic.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/roundingmode-trunc-basic.js new file mode 100644 index 000000000000..5d65e5307d78 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/roundingmode-trunc-basic.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.round +description: Basic checks for truncation rounding mode +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const dt = new Temporal.PlainDateTime(1976, 11, 18, 14, 23, 30, 123, 456, 789); + +const incrementOneFloor = { + "day": [1976, 11, "M11", 18, 0, 0, 0, 0, 0, 0], + "hour": [1976, 11, "M11", 18, 14, 0, 0, 0, 0, 0], + "minute": [1976, 11, "M11", 18, 14, 23, 0, 0, 0, 0], + "second": [1976, 11, "M11", 18, 14, 23, 30, 0, 0, 0], + "millisecond": [1976, 11, "M11", 18, 14, 23, 30, 123, 0, 0], + "microsecond": [1976, 11, "M11", 18, 14, 23, 30, 123, 456, 0], + "nanosecond": [1976, 11, "M11", 18, 14, 23, 30, 123, 456, 789] +}; + +Object.entries(incrementOneFloor).forEach(([smallestUnit, expected]) => { + TemporalHelpers.assertPlainDateTime( + dt.round({ smallestUnit, roundingMode: "trunc" }), + ...expected, + `truncates to ${smallestUnit}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/roundto-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/roundto-invalid-string.js new file mode 100644 index 000000000000..9b1f5f8732dd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/roundto-invalid-string.js @@ -0,0 +1,36 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.round +description: RangeError thrown when smallestUnit option not one of the allowed string values +features: [Temporal] +---*/ + +const datetime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 123, 987, 500); +const badValues = [ + "era", + "eraYear", + "year", + "month", + "week", + "millisecond\0", + "mill\u0131second", + "SECOND", + "eras", + "eraYears", + "years", + "months", + "weeks", + "milliseconds\0", + "mill\u0131seconds", + "SECONDS", + "other string", +]; +for (const smallestUnit of badValues) { + assert.throws(RangeError, () => datetime.round(smallestUnit), + `"${smallestUnit}" is not a valid value for smallest unit`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/smallestunit-disallowed-units.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/smallestunit-disallowed-units.js deleted file mode 100644 index 2ccc733e297e..000000000000 --- a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/smallestunit-disallowed-units.js +++ /dev/null @@ -1,35 +0,0 @@ -// |reftest| skip -- Temporal is not supported -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.plaindatetime.prototype.round -description: Specifically disallowed units for the smallestUnit option -features: [Temporal, arrow-function] ----*/ - -const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 789, 999, 999); -const invalidUnits = [ - "era", - "eras", - "year", - "month", - "week", - "years", - "months", - "weeks", -]; -invalidUnits.forEach((smallestUnit) => { - assert.throws( - RangeError, - () => instance.round({ smallestUnit }), - `{ smallestUnit: "${smallestUnit}" } should not be allowed as an argument to round` - ); - assert.throws( - RangeError, - () => instance.round(smallestUnit), - `"${smallestUnit}" should not be allowed as an argument to round` - ); -}); - -reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/smallestunit-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/smallestunit-invalid-string.js index 7626ceec045d..74a1ef299753 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/smallestunit-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/smallestunit-invalid-string.js @@ -9,6 +9,28 @@ features: [Temporal] ---*/ const datetime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 123, 987, 500); -assert.throws(RangeError, () => datetime.round({ smallestUnit: "other string" })); +const badValues = [ + "era", + "eraYear", + "year", + "month", + "week", + "millisecond\0", + "mill\u0131second", + "SECOND", + "eras", + "eraYears", + "years", + "months", + "weeks", + "milliseconds\0", + "mill\u0131seconds", + "SECONDS", + "other string", +]; +for (const smallestUnit of badValues) { + assert.throws(RangeError, () => datetime.round({ smallestUnit }), + `"${smallestUnit}" is not a valid value for smallest unit`); +} reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/throws-argument-object-insufficient-data.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/throws-argument-object-insufficient-data.js new file mode 100644 index 000000000000..784053c4f6ae --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/throws-argument-object-insufficient-data.js @@ -0,0 +1,19 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.round +description: Throw if smallest unit is missing from argument +features: [Temporal] +---*/ + +const dt = new Temporal.PlainDateTime(1976, 11, 18, 14, 23, 30, 123, 456, 789); + +assert.throws( + RangeError, + () => dt.round({ roundingIncrement: 1, roundingMode: "ceil" }), + "throws without required smallestUnit parameter" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/throws-argument-object.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/throws-argument-object.js new file mode 100644 index 000000000000..8b7bde4fb0c9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/throws-argument-object.js @@ -0,0 +1,19 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.round +description: Throw if argument is an empty plain object +features: [Temporal] +---*/ + +const dt = new Temporal.PlainDateTime(1976, 11, 18, 14, 23, 30, 123, 456, 789); + +assert.throws( + RangeError, + () => dt.round({}), + "throws on empty object" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/throws-no-argument.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/throws-no-argument.js new file mode 100644 index 000000000000..8ea7cf2157b8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/throws-no-argument.js @@ -0,0 +1,19 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.round +description: Throw if no arguments at all are given +features: [Temporal] +---*/ + +const dt = new Temporal.PlainDateTime(1976, 11, 18, 14, 23, 30, 123, 456, 789); + +assert.throws( + TypeError, + () => dt.round(), + "throws without any parameters" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/throws-undefined.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/throws-undefined.js new file mode 100644 index 000000000000..2dce25c040f9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/round/throws-undefined.js @@ -0,0 +1,19 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.round +description: Throw if sole argument is undefined +features: [Temporal] +---*/ + +const dt = new Temporal.PlainDateTime(1976, 11, 18, 14, 23, 30, 123, 456, 789); + +assert.throws( + TypeError, + () => dt.round(undefined), + "throws without undefined as sole parameter" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/argument-number.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/argument-number.js new file mode 100644 index 000000000000..6b2b4b123f18 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/argument-number.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.since +description: A number is converted to a string, then to Temporal.PlainDateTime +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDateTime(1976, 11, 18); + +let arg = 19761118; + +const result = instance.since(arg); +TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19761118 is a valid ISO string for PlainDateTime"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.since(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDateTime` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/argument-object.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/argument-object.js new file mode 100644 index 000000000000..e4c650f32c0f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/argument-object.js @@ -0,0 +1,20 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.since +description: Plain objects are accepted as an argument +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const dt = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789); + +TemporalHelpers.assertDuration( + dt.since({ year: 2019, month: 10, day: 29, hour: 10 }), + 0, 0, 0, -15684, -18, -36, -29, -876, -543, -211, + "casts argument (plain object)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..ef0f458531ca --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.since +description: Leap second is a valid ISO string for a calendar in a property bag +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDateTime(1976, 11, 18); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.since(arg); +TemporalHelpers.assertDuration( + result1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.since(arg); +TemporalHelpers.assertDuration( + result2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..a4d2858ed8ab --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-number.js @@ -0,0 +1,45 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.since +description: A number as calendar in a property bag is converted to a string, then to a calendar +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDateTime(1976, 11, 18); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.since(arg); +TemporalHelpers.assertDuration(result1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.since(arg); +TemporalHelpers.assertDuration(result2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + assert.throws( + RangeError, + () => instance.since(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.since(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..8fcc52d73753 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.since +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.since(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.since(arg), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.since(arg), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.since(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.since(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..ae3cf42a4883 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.since +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.since(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/argument-string.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/argument-string.js new file mode 100644 index 000000000000..455adcbd2d18 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/argument-string.js @@ -0,0 +1,20 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.since +description: Date-like string arguments are acceptable +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const dt = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789); + +TemporalHelpers.assertDuration( + dt.since("2019-10-29T10:46:38.271986102"), + 0, 0, 0, -15684, -19, -23, -8, -148, -529, -313, + "casts argument (string)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/argument-wrong-type.js new file mode 100644 index 000000000000..c9663041b655 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/argument-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.since +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDateTime +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.since(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDateTime, "Temporal.PlainDateTime, object"], + [Temporal.PlainDateTime.prototype, "Temporal.PlainDateTime.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.since(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/different-calendars-throws.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/different-calendars-throws.js new file mode 100644 index 000000000000..79ea03eaa5b7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/different-calendars-throws.js @@ -0,0 +1,20 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.since +description: Fail if the argument is a PlainDateTime with a different calendar +features: [Temporal] +---*/ + +const dt1 = new Temporal.PlainDateTime(2000, 1, 1, 0, 0, 0, 0, 0, 0); +const dt2 = new Temporal.PlainDateTime(2000, 1, 1, 0, 0, 0, 0, 0, 0, {}); + +assert.throws( + RangeError, + () => dt1.since(dt2), + "different calendars not allowed" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/largestunit-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/largestunit-invalid-string.js index 23ce028f885c..cec41ee5d967 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/largestunit-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/largestunit-invalid-string.js @@ -10,9 +10,22 @@ features: [Temporal] const earlier = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 0, 0, 0); const later = new Temporal.PlainDateTime(2001, 6, 3, 13, 35, 57, 987, 654, 321); -const values = ["era", "eraYear", "other string"]; -for (const largestUnit of values) { - assert.throws(RangeError, () => later.since(earlier, { largestUnit })); +const badValues = [ + "era", + "eraYear", + "millisecond\0", + "mill\u0131second", + "SECOND", + "eras", + "eraYears", + "milliseconds\0", + "mill\u0131seconds", + "SECONDS", + "other string" +]; +for (const largestUnit of badValues) { + assert.throws(RangeError, () => later.since(earlier, { largestUnit }), + `"${largestUnit}" is not a valid value for largestUnit`); } reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/leap-second.js new file mode 100644 index 000000000000..a5f47669b9a1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/leap-second.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.since +description: Leap second is a valid ISO string for PlainDateTime +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDateTime(2016, 12, 31, 23, 59, 59); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.since(arg); +TemporalHelpers.assertDuration( + result1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "leap second is a valid ISO string for PlainDateTime" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.since(arg); +TemporalHelpers.assertDuration( + result2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "second: 60 is ignored in property bag for PlainDateTime" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/no-unnecessary-units.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/no-unnecessary-units.js new file mode 100644 index 000000000000..7229960e0aca --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/no-unnecessary-units.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.since +description: Do not return Durations with unnecessary units +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const feb2 = new Temporal.PlainDateTime(2020, 2, 2, 0, 0); +const feb28 = new Temporal.PlainDateTime(2021, 2, 28, 0, 0); + +TemporalHelpers.assertDuration( + feb28.since(feb2), + 0, 0, 0, 392, 0, 0, 0, 0, 0, 0, + "does not include higher units than necessary (no largest unit)" +); + +TemporalHelpers.assertDuration( + feb28.since(feb2, { largestUnit: "months" }), + 0, 12, 0, 26, 0, 0, 0, 0, 0, 0, + "does not include higher units than necessary (largest unit = months)" +); + +TemporalHelpers.assertDuration( + feb28.since(feb2, { largestUnit: "years" }), + 1, 0, 0, 26, 0, 0, 0, 0, 0, 0, + "does not include higher units than necessary (largest unit = years)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/options-empty.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/options-empty.js new file mode 100644 index 000000000000..d406e9f96670 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/options-empty.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.since +description: Empty objects are acceptable +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const feb20 = new Temporal.PlainDateTime(2020, 2, 1, 0, 0); +const feb21 = new Temporal.PlainDateTime(2021, 2, 1, 0, 0); + +TemporalHelpers.assertDuration( + feb21.since(feb20, {}), + 0, 0, 0, 366, 0, 0, 0, 0, 0, 0, + "empty plain object options" +); + +TemporalHelpers.assertDuration( + feb21.since(feb20, () => {}), + 0, 0, 0, 366, 0, 0, 0, 0, 0, 0, + "empty function object options" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/options-invalid.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/options-invalid.js new file mode 100644 index 000000000000..e9372847d26f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/options-invalid.js @@ -0,0 +1,23 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.since +description: A variety of bad options (type error thrown) +features: [Temporal, Symbol] +---*/ + +const feb20 = new Temporal.PlainDateTime(2020, 2, 1, 0, 0); +const feb21 = new Temporal.PlainDateTime(2021, 2, 1, 0, 0); + +const badOptions = [null, 1, 'hello', true, Symbol('foo'), 1n]; +badOptions.forEach((bad) => { + assert.throws( + TypeError, + () => feb21.since(feb20, bad), + `bad options (${typeof bad})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/options-wrong-type.js new file mode 100644 index 000000000000..699523064a31 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.since +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.PlainDateTime(2000, 5, 2); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.since(new Temporal.PlainDateTime(1976, 11, 18), value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/returns-days.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/returns-days.js new file mode 100644 index 000000000000..3bff2041bb91 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/returns-days.js @@ -0,0 +1,47 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.since +description: Days are the default level of specificity +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const feb_1_2020 = new Temporal.PlainDateTime(2020, 2, 1, 0, 0); +const feb_1_2021 = new Temporal.PlainDateTime(2021, 2, 1, 0, 0); + +TemporalHelpers.assertDuration( + feb_1_2021.since(feb_1_2020), + 0, 0, 0, 366, 0, 0, 0, 0, 0, 0, + "defaults to returning days (no options)" +); + +TemporalHelpers.assertDuration( + feb_1_2021.since(feb_1_2020, { largestUnit: "auto" }), + 0, 0, 0, 366, 0, 0, 0, 0, 0, 0, + "defaults to returning days (largest unit = auto)" +); + +TemporalHelpers.assertDuration( + feb_1_2021.since(feb_1_2020, { largestUnit: "days" }), + 0, 0, 0, 366, 0, 0, 0, 0, 0, 0, + "defaults to returning days (largest unit = days)" +); + +const dt = new Temporal.PlainDateTime(2020, 2, 1, 0, 0, 0, 0, 0, 1); + +TemporalHelpers.assertDuration( + dt.since(feb_1_2020), + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + "defaults to returning days (nanosecond)" +); + +TemporalHelpers.assertDuration( + feb_1_2021.since(dt), + 0, 0, 0, 365, 23, 59, 59, 999, 999, 999, + "defaults to returning days (nanosecond)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/round-relative-to-receiver.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/round-relative-to-receiver.js new file mode 100644 index 000000000000..90864bb3e976 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/round-relative-to-receiver.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.since +description: Values are rounded relative to the receiver +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const dt1 = new Temporal.PlainDateTime(2019, 1, 1); +const dt2 = new Temporal.PlainDateTime(2020, 7, 2); + +TemporalHelpers.assertDuration( + dt2.since(dt1, { smallestUnit: "years", roundingMode: "halfExpand" }), + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "rounds relative to the receiver (positive case)" +); + +TemporalHelpers.assertDuration( + dt1.since(dt2, { smallestUnit: "years", roundingMode: "halfExpand" }), + -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "rounds relative to the receiver (negative case)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/roundingincrement-basic.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/roundingincrement-basic.js new file mode 100644 index 000000000000..919984ef5f7d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/roundingincrement-basic.js @@ -0,0 +1,51 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.since +description: Round to different smallest increments +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const earlier = new Temporal.PlainDateTime(2019, 1, 8, 8, 22, 36, 123, 456, 789); +const later = new Temporal.PlainDateTime(2021, 9, 7, 12, 39, 40, 987, 654, 321); + +TemporalHelpers.assertDuration( + later.since(earlier, { smallestUnit: "hours", roundingIncrement: 3, roundingMode: "halfExpand" }), + 0, 0, 0, 973, 3, 0, 0, 0, 0, 0, + "rounds to an increment of hours" +); + +TemporalHelpers.assertDuration( + later.since(earlier, { smallestUnit: "minutes", roundingIncrement: 30, roundingMode: "halfExpand" }), + 0, 0, 0, 973, 4, 30, 0, 0, 0,0, + "rounds to an increment of minutes" +); + +TemporalHelpers.assertDuration( + later.since(earlier, { smallestUnit: "seconds", roundingIncrement: 15, roundingMode: "halfExpand" }), + 0, 0, 0, 973, 4, 17, 0, 0, 0, 0, + "rounds to an increment of seconds" +); + +TemporalHelpers.assertDuration( + later.since(earlier, { smallestUnit: "milliseconds", roundingIncrement: 10, roundingMode: "halfExpand" }), + 0, 0, 0, 973, 4, 17, 4, 860, 0, 0, + "rounds to an increment of milliseconds" +); + +TemporalHelpers.assertDuration( + later.since(earlier, { smallestUnit: "microseconds", roundingIncrement: 10, roundingMode: "halfExpand" }), + 0, 0, 0, 973, 4, 17, 4, 864, 200, 0, + "rounds to an increment of microseconds" +); + +TemporalHelpers.assertDuration( + later.since(earlier, { smallestUnit: "nanoseconds", roundingIncrement: 10, roundingMode: "halfExpand" }), + 0, 0, 0, 973, 4, 17, 4, 864, 197, 530, + "rounds to an increment of nanoseconds" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/roundingincrement-cleanly-divides.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/roundingincrement-cleanly-divides.js new file mode 100644 index 000000000000..cbf568fec363 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/roundingincrement-cleanly-divides.js @@ -0,0 +1,42 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.since +description: Rounding argument cleanly divides the relevant smallest unit +features: [Temporal] +---*/ + +const earlier = new Temporal.PlainDateTime(2019, 1, 8, 8, 22, 36, 123, 456, 789); +const later = new Temporal.PlainDateTime(2021, 9, 7, 12, 39, 40, 987, 654, 321); + +[1, 2, 3, 4, 6, 8, 12].forEach((roundingIncrement) => { + const options = { smallestUnit: "hours", roundingIncrement }; + assert( + later.since(earlier, options) instanceof Temporal.Duration, + `valid hour increments divide into 24 (rounding increment = ${roundingIncrement}, smallest unit = hours)` + ); +}); + +["minutes", "seconds"].forEach((smallestUnit) => { + [1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30].forEach((roundingIncrement) => { + const options = { smallestUnit, roundingIncrement }; + assert( + later.since(earlier, options) instanceof Temporal.Duration, + `valid ${smallestUnit} increments divide into 60 (rounding increment = ${roundingIncrement})` + ); + }); +}); + +["milliseconds", "microseconds", "nanoseconds"].forEach((smallestUnit) => { + [1, 2, 4, 5, 8, 10, 20, 25, 40, 50, 100, 125, 200, 250, 500].forEach((roundingIncrement) => { + const options = { smallestUnit, roundingIncrement }; + assert( + later.since(earlier, options) instanceof Temporal.Duration, + `valid ${smallestUnit} increments divide into 1000 (rounding increment = ${roundingIncrement})` + ); + }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/roundingincrement-does-not-divide.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/roundingincrement-does-not-divide.js new file mode 100644 index 000000000000..19335142273f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/roundingincrement-does-not-divide.js @@ -0,0 +1,48 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.since +description: Throw if rounding increment does not cleanly divide the relevant unit +features: [Temporal] +---*/ + +const earlier = new Temporal.PlainDateTime(2019, 1, 8, 8, 22, 36, 123, 456, 789); +const later = new Temporal.PlainDateTime(2021, 9, 7, 12, 39, 40, 987, 654, 321); + +const badIncrements = { + "hours": 11, + "minutes": 29, + "seconds": 29, + "milliseconds": 29, + "microseconds": 29, + "nanoseconds": 29 +}; + +Object.entries(badIncrements).forEach(([unit, bad]) => { + assert.throws( + RangeError, + () => later.since(earlier, { smallestUnit: unit, roundingIncrement: bad }), + `throws on increments that do not divide evenly into the next highest (unit = ${unit}, increment = ${bad})` + ); +}); + +const fullIncrements = { + "hours": 24, + "minutes": 60, + "seconds": 60, + "milliseconds": 1000, + "microseconds": 1000, + "nanoseconds": 1000 +}; + +Object.entries(fullIncrements).forEach(([unit, bad]) => { + assert.throws( + RangeError, + () => later.since(earlier, { smallestUnit: unit, roundingIncrement: bad }), + `throws on increments that are equal to the next highest (unit = ${unit}, rounding increment = ${bad}` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/roundingmode-ceil-basic.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/roundingmode-ceil-basic.js new file mode 100644 index 000000000000..e55c86d0b2e0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/roundingmode-ceil-basic.js @@ -0,0 +1,43 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.since +description: Ceiling rounding mode basic tests +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const earlier = new Temporal.PlainDateTime(2019, 1, 8, 8, 22, 36, 123, 456, 789); +const later = new Temporal.PlainDateTime(2021, 9, 7, 12, 39, 40, 987, 654, 321); + +const incrementOneCeil = [ + ["years", [3], [-2]], + ["months", [0, 32], [0, -31]], + ["weeks", [0, 0, 140], [0, 0, -139]], + ["days", [0, 0, 0, 974], [0, 0, 0, -973]], + ["hours", [0, 0, 0, 973, 5], [0, 0, 0, -973, -4]], + ["minutes", [0, 0, 0, 973, 4, 18], [0, 0, 0, -973, -4, -17]], + ["seconds", [0, 0, 0, 973, 4, 17, 5], [0, 0, 0, -973, -4, -17, -4]], + ["milliseconds", [0, 0, 0, 973, 4, 17, 4, 865], [0, 0, 0, -973, -4, -17, -4, -864]], + ["microseconds", [0, 0, 0, 973, 4, 17, 4, 864, 198], [0, 0, 0, -973, -4, -17, -4, -864, -197]], + ["nanoseconds", [0, 0, 0, 973, 4, 17, 4, 864, 197, 532], [0, 0, 0, -973, -4, -17, -4, -864, -197, -532]] +]; +const roundingMode = "ceil"; +incrementOneCeil.forEach(([smallestUnit, expectedPositive, expectedNegative]) => { + const [py, pm = 0, pw = 0, pd = 0, ph = 0, pmin = 0, ps = 0, pms = 0, pµs = 0, pns = 0] = expectedPositive; + const [ny, nm = 0, nw = 0, nd = 0, nh = 0, nmin = 0, ns = 0, nms = 0, nµs = 0, nns = 0] = expectedNegative; + TemporalHelpers.assertDuration( + earlier.until(later, { smallestUnit, roundingMode }), + py, pm, pw, pd, ph, pmin, ps, pms, pµs, pns, + `rounds up to ${smallestUnit} (roundingMode = ceil, positive case)` + ); + TemporalHelpers.assertDuration( + later.until(earlier, { smallestUnit, roundingMode }), + ny, nm, nw, nd, nh, nmin, ns, nms, nµs, nns, + `rounds up to ${smallestUnit} (rounding mode = ceil, negative case)` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/roundingmode-floor-basic.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/roundingmode-floor-basic.js new file mode 100644 index 000000000000..3636fbf64795 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/roundingmode-floor-basic.js @@ -0,0 +1,45 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.since +description: Floor rounding mode basic tests +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const earlier = new Temporal.PlainDateTime(2019, 1, 8, 8, 22, 36, 123, 456, 789); +const later = new Temporal.PlainDateTime(2021, 9, 7, 12, 39, 40, 987, 654, 321); + +const incrementOneFloor = [ + ["years", [2], [-3]], + ["months", [0, 31], [0, -32]], + ["weeks", [0, 0, 139], [0, 0, -140]], + ["days", [0, 0, 0, 973], [0, 0, 0, -974]], + ["hours", [0, 0, 0, 973, 4], [0, 0, 0, -973, -5]], + ["minutes", [0, 0, 0, 973, 4, 17], [0, 0, 0, -973, -4, -18]], + ["seconds", [0, 0, 0, 973, 4, 17, 4], [0, 0, 0, -973, -4, -17, -5]], + ["milliseconds", [0, 0, 0, 973, 4, 17, 4, 864], [0, 0, 0, -973, -4, -17, -4, -865]], + ["microseconds", [0, 0, 0, 973, 4, 17, 4, 864, 197], [0, 0, 0, -973, -4, -17, -4, -864, -198]], + ["nanoseconds", [0, 0, 0, 973, 4, 17, 4, 864, 197, 532], [0, 0, 0, -973, -4, -17, -4, -864, -197, -532]] +]; + +const roundingMode = "floor"; + +incrementOneFloor.forEach(([smallestUnit, expectedPositive, expectedNegative]) => { + const [py, pm = 0, pw = 0, pd = 0, ph = 0, pmin = 0, ps = 0, pms = 0, pµs = 0, pns = 0] = expectedPositive; + const [ny, nm = 0, nw = 0, nd = 0, nh = 0, nmin = 0, ns = 0, nms = 0, nµs = 0, nns = 0] = expectedNegative; + TemporalHelpers.assertDuration( + later.since(earlier, { smallestUnit, roundingMode }), + py, pm, pw, pd, ph, pmin, ps, pms, pµs, pns, + `rounds down to ${smallestUnit} (rounding mode = ${roundingMode}, positive case)` + ); + TemporalHelpers.assertDuration( + earlier.since(later, { smallestUnit, roundingMode }), + ny, nm, nw, nd, nh, nmin, ns, nms, nµs, nns, + `rounds down to ${smallestUnit} (rounding mode = ${roundingMode}, negative case)` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/roundingmode-halfexpand-basic.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/roundingmode-halfexpand-basic.js new file mode 100644 index 000000000000..d113ce3acc6f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/roundingmode-halfexpand-basic.js @@ -0,0 +1,55 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.since +description: Half-expand rounding mode basic tests +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const earlier = new Temporal.PlainDateTime(2019, 1, 8, 8, 22, 36, 123, 456, 789); +const later = new Temporal.PlainDateTime(2021, 9, 7, 12, 39, 40, 987, 654, 321); + +function ensureUnsignedZero(x) { + return Object.is(x, -0) ? 0 : x; +} + +const incrementOneNearest = [ + ["years", [3]], + ["months", [0, 32]], + ["weeks", [0, 0, 139]], + ["days", [0, 0, 0, 973]], + ["hours", [0, 0, 0, 973, 4]], + ["minutes", [0, 0, 0, 973, 4, 17]], + ["seconds", [0, 0, 0, 973, 4, 17, 5]], + ["milliseconds", [0, 0, 0, 973, 4, 17, 4, 864]], + ["microseconds", [0, 0, 0, 973, 4, 17, 4, 864, 198]], + ["nanoseconds", [0, 0, 0, 973, 4, 17, 4, 864, 197, 532]] +]; +const roundingMode = "halfExpand"; +incrementOneNearest.forEach(([smallestUnit, expected]) => { + const [y, m = 0, w = 0, d = 0, h = 0, min = 0, s = 0, ms = 0, µs = 0, ns = 0] = expected; + TemporalHelpers.assertDuration( + later.since(earlier, { smallestUnit, roundingMode }), + y, m, w, d, h, min, s, ms, µs, ns, + `rounds to nearest ${smallestUnit} (rounding mode = ${roundingMode}, positive case)` + ); + TemporalHelpers.assertDuration( + earlier.since(later, { smallestUnit, roundingMode }), + ensureUnsignedZero(-y), + ensureUnsignedZero(-m), + ensureUnsignedZero(-w), + ensureUnsignedZero(-d), + ensureUnsignedZero(-h), + ensureUnsignedZero(-min), + ensureUnsignedZero(-s), + ensureUnsignedZero(-ms), + ensureUnsignedZero(-µs), + ensureUnsignedZero(-ns), + `rounds to nearest ${smallestUnit} (rounding mode = ${roundingMode}, negative case)` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/roundingmode-halfexpand-default-changes.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/roundingmode-halfexpand-default-changes.js new file mode 100644 index 000000000000..ddfd5f45543c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/roundingmode-halfexpand-default-changes.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.since +description: A different default for largest unit will be used if smallest unit is larger than "days" +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const earlier = new Temporal.PlainDateTime(2019, 1, 8, 8, 22, 36, 123, 456, 789); +const later = new Temporal.PlainDateTime(2021, 9, 7, 12, 39, 40, 987, 654, 321); + +TemporalHelpers.assertDuration( + later.since(earlier, { smallestUnit: "years", roundingMode: "halfExpand" }), + 3, 0, 0, 0, 0, 0, 0, 0, 0,0, + "assumes a different default for largestUnit if smallestUnit is larger than days (smallest unit = years)" +); + +TemporalHelpers.assertDuration( + later.since(earlier, { smallestUnit: "months", roundingMode: "halfExpand" }), + 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, + "assumes a different default for largestUnit if smallestUnit is larger than days (smallest unit = months)" +); + +TemporalHelpers.assertDuration( + later.since(earlier, { smallestUnit: "weeks", roundingMode: "halfExpand" }), + 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, + "assumes a different default for largestUnit if smallestUnit is larger than days (smallest unit = weeks)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/roundingmode-trunc-basic.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/roundingmode-trunc-basic.js new file mode 100644 index 000000000000..63ed7b58609f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/roundingmode-trunc-basic.js @@ -0,0 +1,57 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.since +description: Truncation rounding mode basic tests +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const earlier = new Temporal.PlainDateTime(2019, 1, 8, 8, 22, 36, 123, 456, 789); +const later = new Temporal.PlainDateTime(2021, 9, 7, 12, 39, 40, 987, 654, 321); + +function ensureUnsignedZero(x) { + return Object.is(x, -0) ? 0 : x; +} + +const incrementOneTrunc = [ + ["years", [2]], + ["months", [0, 31]], + ["weeks", [0, 0, 139]], + ["days", [0, 0, 0, 973]], + ["hours", [0, 0, 0, 973, 4]], + ["minutes", [0, 0, 0, 973, 4, 17]], + ["seconds", [0, 0, 0, 973, 4, 17, 4]], + ["milliseconds", [0, 0, 0, 973, 4, 17, 4, 864]], + ["microseconds", [0, 0, 0, 973, 4, 17, 4, 864, 197]], + ["nanoseconds", [0, 0, 0, 973, 4, 17, 4, 864, 197, 532]] +]; + +const roundingMode = "trunc"; + +incrementOneTrunc.forEach(([smallestUnit, expected]) => { + const [y, m = 0, w = 0, d = 0, h = 0, min = 0, s = 0, ms = 0, µs = 0, ns = 0] = expected; + TemporalHelpers.assertDuration( + later.since(earlier, { smallestUnit, roundingMode }), + y, m, w, d, h, min, s, ms, µs, ns, + `truncates to ${smallestUnit} (rounding mode = ${roundingMode}, positive case)` + ); + TemporalHelpers.assertDuration( + earlier.since(later, { smallestUnit, roundingMode }), + ensureUnsignedZero(-y), + ensureUnsignedZero(-m), + ensureUnsignedZero(-w), + ensureUnsignedZero(-d), + ensureUnsignedZero(-h), + ensureUnsignedZero(-min), + ensureUnsignedZero(-s), + ensureUnsignedZero(-ms), + ensureUnsignedZero(-µs), + ensureUnsignedZero(-ns), + `truncates to ${smallestUnit} (rounding mode = ${roundingMode}, negative case)` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/roundingmode-trunc-is-default.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/roundingmode-trunc-is-default.js new file mode 100644 index 000000000000..fc8d378e3a61 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/roundingmode-trunc-is-default.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.since +description: Truncation (trunc) is the default rounding mode +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const earlier = new Temporal.PlainDateTime(2019, 1, 8, 8, 22, 36, 123, 456, 789); +const later = new Temporal.PlainDateTime(2021, 9, 7, 12, 39, 40, 987, 654, 321); + +TemporalHelpers.assertDuration( + later.since(earlier, { smallestUnit: "minutes" }), + 0, 0, 0, 973, 4, 17, 0, 0, 0, 0, + "trunc is the default (round up)" +); + +TemporalHelpers.assertDuration( + later.since(earlier, { smallestUnit: "seconds" }), + 0, 0, 0, 973, 4, 17, 4, 0, 0, 0, + "trunc is the default (round down)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/smallestunit-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/smallestunit-invalid-string.js index 9673917b67b9..bec88f96ee85 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/smallestunit-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/smallestunit-invalid-string.js @@ -10,9 +10,22 @@ features: [Temporal] const earlier = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 0, 0, 0); const later = new Temporal.PlainDateTime(2000, 5, 3, 13, 35, 57, 987, 654, 321); -const values = ["era", "eraYear", "other string"]; -for (const smallestUnit of values) { - assert.throws(RangeError, () => later.since(earlier, { smallestUnit })); +const badValues = [ + "era", + "eraYear", + "millisecond\0", + "mill\u0131second", + "SECOND", + "eras", + "eraYears", + "milliseconds\0", + "mill\u0131seconds", + "SECONDS", + "other string", +]; +for (const smallestUnit of badValues) { + assert.throws(RangeError, () => later.since(earlier, { smallestUnit }), + `"${smallestUnit}" is not a valid value for smallest unit`); } reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/subseconds.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/subseconds.js new file mode 100644 index 000000000000..9a19cb5b99af --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/subseconds.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.since +description: Returned granularity may be finer than seconds +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const feb20 = new Temporal.PlainDateTime(2020, 2, 1, 0, 0); +const feb21 = new Temporal.PlainDateTime(2020, 2, 2, 0, 0, 0, 250, 250, 250); + +TemporalHelpers.assertDuration( + feb21.since(feb20, { largestUnit: "milliseconds" }), + 0, 0, 0, 0, 0, 0, 0, 86400250, 250, 250, + "can return subseconds (milliseconds)" +); + +TemporalHelpers.assertDuration( + feb21.since(feb20, { largestUnit: "microseconds" }), + 0, 0, 0, 0, 0, 0, 0, 0, 86400250250, 250, + "can return subseconds (microseconds)" +); + +TemporalHelpers.assertDuration( + feb21.since(feb20, { largestUnit: "nanoseconds" }), + 0, 0, 0, 0, 0, 0, 0, 0, 0, 86400250250250, + "can return subseconds (nanoseconds)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/weeks-months-mutually-exclusive.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/weeks-months-mutually-exclusive.js new file mode 100644 index 000000000000..2bd398f17bbb --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/weeks-months-mutually-exclusive.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.since +description: Weeks and months are mutually exclusive +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const dt = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789); +const laterDateTime = dt.add({ days: 42, hours: 3 }); + +TemporalHelpers.assertDuration( + laterDateTime.since(dt, { largestUnit: "weeks" }), + 0, 0, 6, 0, 3, 0, 0, 0, 0, 0, + "weeks and months are mutually exclusive (prefer weeks)" +); + +TemporalHelpers.assertDuration( + laterDateTime.since(dt, { largestUnit: "months" }), + 0, 1, 0, 12, 3, 0, 0, 0,0, 0, + "weeks and months are mutually exclusive (prefer months)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/year-zero.js index 7888ce9d0000..5e7f545821f9 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/since/year-zero.js @@ -9,14 +9,16 @@ features: [Temporal, arrow-function] ---*/ const invalidStrings = [ + "-000000-12-07", "-000000-12-07T03:24:30", - "-000000-12-07T03:24:30+01:00[UTC]" + "-000000-12-07T03:24:30+01:00", + "-000000-12-07T03:24:30+00:00[UTC]", ]; const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); invalidStrings.forEach((arg) => { assert.throws( RangeError, - () => { instance.since(arg); }, + () => instance.since(arg), "reject minus zero as extended year" ); }); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/subtract/limits.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/subtract/limits.js new file mode 100644 index 000000000000..01e44f74db65 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/subtract/limits.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.subtract +description: Checking limits of representable PlainDateTime +features: [Temporal] +---*/ + +const min = new Temporal.PlainDateTime(-271821, 4, 19, 0, 0, 0, 0, 0, 1); +const max = new Temporal.PlainDateTime(275760, 9, 13, 23, 59, 59, 999, 999, 999); + +["reject", "constrain"].forEach((overflow) => { + assert.throws( + RangeError, + () => min.subtract({ nanoseconds: 1 }, { overflow }), + `subtracting 1 nanosecond beyond minimum limit (overflow = ${overflow})` + ); + assert.throws( + RangeError, + () => max.subtract({ nanoseconds: -1 }, { overflow }), + `subtracting -1 nanosecond beyond maximum limit (overflow = ${overflow})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/subtract/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/subtract/options-wrong-type.js new file mode 100644 index 000000000000..69a2d81bf791 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/subtract/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.subtract +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.PlainDateTime(2000, 5, 2); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.subtract({ months: 1 }, value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-always.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-always.js new file mode 100644 index 000000000000..17af74496e77 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-always.js @@ -0,0 +1,19 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.tostring +description: Show ISO calendar if calendar name is "always" +features: [Temporal] +---*/ + +const dt = new Temporal.PlainDateTime(1976, 11, 18, 15, 23); + +assert.sameValue( + dt.toString({ calendarName: "always" }), + "1976-11-18T15:23:00[u-ca=iso8601]", + "shows ISO calendar if calendarName = always" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-auto.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-auto.js new file mode 100644 index 000000000000..519ca0a63aa7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-auto.js @@ -0,0 +1,38 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.tostring +description: Possibly display calendar when calendarName is "auto" +features: [Temporal] +---*/ + + +const dt = new Temporal.PlainDateTime(1976, 11, 18, 15, 23); +const customCal = { + toString() { return "bogus"; } +}; +const fakeISO8601Cal = { + toString() { return "iso8601"; } +}; +const expected = "1976-11-18T15:23:00"; + +assert.sameValue(dt.toString(), expected, "default is calendar = auto (zero arguments)"); +assert.sameValue(dt.toString({ calendarName: "auto" }), expected, "shows only non-ISO calendar if calendarName = auto"); + +assert.sameValue( + dt.withCalendar(fakeISO8601Cal).toString({ calendarName: "auto" }), + expected, + "Don't show ISO calendar even if calendarName = auto" +); + +const dt2 = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 0, 0, 0, 0, customCal); + +assert.sameValue( + dt2.toString({ calendarName: "auto" }), + "1976-11-18T15:23:00[u-ca=bogus]", + "Don't show calendar if calendarName = auto & PlainDateTime has non-ISO calendar" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-invalid-string.js index fe695be5aa97..05fab3f065f5 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-invalid-string.js @@ -16,6 +16,13 @@ features: [Temporal] ---*/ const datetime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); -assert.throws(RangeError, () => datetime.toString({ calendarName: "other string" })); +const invalidCals = ["other string", "ALWAYS", "sometimes", "auto\0"]; + +invalidCals.forEach((cal) => { + assert.throws( + RangeError, + () => datetime.toString({ calendarName: cal }), + `invalid calendar (${cal})`); +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-never.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-never.js new file mode 100644 index 000000000000..6c3dc8faedf7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-never.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.tostring +description: Do not show calendar if calendar name option is "never" +features: [Temporal] +---*/ + +const dt = new Temporal.PlainDateTime(1976, 11, 18, 15, 23); +const cal = { + toString() { return "bogus"; } +}; +const expected = "1976-11-18T15:23:00"; + +assert.sameValue( + dt.toString({ calendarName: "never" }), + expected, + "Do not show calendar if calendarName = never" +); + +assert.sameValue( + dt.withCalendar(cal).toString({ calendarName: "never" }), + expected, + "Do not show calendar when calendarName = never, even if non-ISO calendar is used" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/fractionalseconddigits-auto.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/fractionalseconddigits-auto.js new file mode 100644 index 000000000000..87c81f79ff1a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/fractionalseconddigits-auto.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.tostring +description: auto value for fractionalSecondDigits option +features: [Temporal] +---*/ + +const zeroSeconds = new Temporal.PlainDateTime(1976, 11, 18, 15, 23); +const wholeSeconds = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30); +const subSeconds = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 400); + +const tests = [ + [zeroSeconds, "1976-11-18T15:23:00"], + [wholeSeconds, "1976-11-18T15:23:30"], + [subSeconds, "1976-11-18T15:23:30.1234"], +]; + +for (const [datetime, expected] of tests) { + assert.sameValue(datetime.toString(), expected, "default is to emit seconds and drop trailing zeroes"); + assert.sameValue(datetime.toString({ fractionalSecondDigits: "auto" }), expected, "auto is the default"); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/fractionalseconddigits-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/fractionalseconddigits-invalid-string.js index c2bee94ca738..e2fe6cfc62b2 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/fractionalseconddigits-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/fractionalseconddigits-invalid-string.js @@ -11,12 +11,15 @@ info: | sec-temporal-tosecondsstringprecision step 9: 9. Let _digits_ be ? GetStringOrNumberOption(_normalizedOptions_, *"fractionalSecondDigits"*, « *"auto"* », 0, 9, *"auto"*). sec-temporal.plaindatetime.prototype.tostring step 4: - 4. Let _precision_ be ? ToDurationSecondsStringPrecision(_options_). + 4. Let _precision_ be ? ToSecondsStringPrecision(_options_). features: [Temporal] ---*/ const datetime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 650, 0); -assert.throws(RangeError, () => datetime.toString({ fractionalSecondDigits: "other string" })); +for (const fractionalSecondDigits of ["other string", "AUTO", "not-auto", "autos", "auto\0"]) { + assert.throws(RangeError, () => datetime.toString({ fractionalSecondDigits }), + `"${fractionalSecondDigits}" is not a valid value for fractionalSecondDigits`); +} reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/fractionalseconddigits-non-integer.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/fractionalseconddigits-non-integer.js index 565c8e410221..a9e9afb7e9e0 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/fractionalseconddigits-non-integer.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/fractionalseconddigits-non-integer.js @@ -11,7 +11,7 @@ info: | sec-temporal-tosecondsstringprecision step 9: 9. Let _digits_ be ? GetStringOrNumberOption(_normalizedOptions_, *"fractionalSecondDigits"*, « *"auto"* », 0, 9, *"auto"*). sec-temporal.plaindatetime.prototype.tostring step 4: - 4. Let _precision_ be ? ToDurationSecondsStringPrecision(_options_). + 4. Let _precision_ be ? ToSecondsStringPrecision(_options_). features: [Temporal] ---*/ diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/fractionalseconddigits-number.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/fractionalseconddigits-number.js new file mode 100644 index 000000000000..68267d1f0f02 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/fractionalseconddigits-number.js @@ -0,0 +1,36 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.tostring +description: Number for fractionalSecondDigits option +features: [Temporal] +---*/ + +const zeroSeconds = new Temporal.PlainDateTime(1976, 11, 18, 15, 23); +const wholeSeconds = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30); +const subSeconds = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 400); + +assert.sameValue(subSeconds.toString({ fractionalSecondDigits: 0 }), "1976-11-18T15:23:30", + "truncates 4 decimal places to 0"); +assert.sameValue(zeroSeconds.toString({ fractionalSecondDigits: 2 }), "1976-11-18T15:23:00.00", + "pads zero seconds to 2 decimal places"); +assert.sameValue(wholeSeconds.toString({ fractionalSecondDigits: 2 }), "1976-11-18T15:23:30.00", + "pads whole seconds to 2 decimal places"); +assert.sameValue(subSeconds.toString({ fractionalSecondDigits: 2 }), "1976-11-18T15:23:30.12", + "truncates 4 decimal places to 2"); +assert.sameValue(subSeconds.toString({ fractionalSecondDigits: 3 }), "1976-11-18T15:23:30.123", + "truncates 4 decimal places to 3"); +assert.sameValue(subSeconds.toString({ fractionalSecondDigits: 6 }), "1976-11-18T15:23:30.123400", + "pads 4 decimal places to 6"); +assert.sameValue(zeroSeconds.toString({ fractionalSecondDigits: 7 }), "1976-11-18T15:23:00.0000000", + "pads zero seconds to 7 decimal places"); +assert.sameValue(wholeSeconds.toString({ fractionalSecondDigits: 7 }), "1976-11-18T15:23:30.0000000", + "pads whole seconds to 7 decimal places"); +assert.sameValue(subSeconds.toString({ fractionalSecondDigits: 7 }), "1976-11-18T15:23:30.1234000", + "pads 4 decimal places to 7"); +assert.sameValue(subSeconds.toString({ fractionalSecondDigits: 9 }), "1976-11-18T15:23:30.123400000", + "pads 4 decimal places to 9"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/fractionalseconddigits-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/fractionalseconddigits-out-of-range.js index d7191cf3f23c..13691271aa2a 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/fractionalseconddigits-out-of-range.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/fractionalseconddigits-out-of-range.js @@ -11,13 +11,19 @@ info: | sec-temporal-tosecondsstringprecision step 9: 9. Let _digits_ be ? GetStringOrNumberOption(_normalizedOptions_, *"fractionalSecondDigits"*, « *"auto"* », 0, 9, *"auto"*). sec-temporal.plaindatetime.prototype.tostring step 4: - 4. Let _precision_ be ? ToDurationSecondsStringPrecision(_options_). + 4. Let _precision_ be ? ToSecondsStringPrecision(_options_). features: [Temporal] ---*/ const datetime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 650, 0); -assert.throws(RangeError, () => datetime.toString({ fractionalSecondDigits: -1 })); -assert.throws(RangeError, () => datetime.toString({ fractionalSecondDigits: 10 })); +assert.throws(RangeError, () => datetime.toString({ fractionalSecondDigits: -Infinity }), + "−∞ is out of range for fractionalSecondDigits"); +assert.throws(RangeError, () => datetime.toString({ fractionalSecondDigits: -1 }), + "−1 is out of range for fractionalSecondDigits"); +assert.throws(RangeError, () => datetime.toString({ fractionalSecondDigits: 10 }), + "10 is out of range for fractionalSecondDigits"); +assert.throws(RangeError, () => datetime.toString({ fractionalSecondDigits: Infinity }), + "∞ is out of range for fractionalSecondDigits"); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/fractionalseconddigits-undefined.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/fractionalseconddigits-undefined.js index 255114ed7b67..dc759ab10098 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/fractionalseconddigits-undefined.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/fractionalseconddigits-undefined.js @@ -9,19 +9,33 @@ info: | sec-getoption step 3: 3. If _value_ is *undefined*, return _fallback_. sec-getstringornumberoption step 2: - 2. Let _value_ be ? GetOption(_options_, _property_, *"stringOrNumber"*, *undefined*, _fallback_). + 2. Let _value_ be ? GetOption(_options_, _property_, « Number, String », *undefined*, _fallback_). sec-temporal-tosecondsstringprecision step 9: 9. Let _digits_ be ? GetStringOrNumberOption(_normalizedOptions_, *"fractionalSecondDigits"*, « *"auto"* », 0, 9, *"auto"*). sec-temporal.plaindatetime.prototype.tostring step 4: - 4. Let _precision_ be ? ToDurationSecondsStringPrecision(_options_). + 4. Let _precision_ be ? ToSecondsStringPrecision(_options_). features: [Temporal] ---*/ -const datetime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 650, 0); +const zeroSeconds = new Temporal.PlainDateTime(1976, 11, 18, 15, 23); +const wholeSeconds = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30); +const subSeconds = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 400); -const explicit = datetime.toString({ fractionalSecondDigits: undefined }); -assert.sameValue(explicit, "2000-05-02T12:34:56.98765", "default fractionalSecondDigits is auto"); +const tests = [ + [zeroSeconds, "1976-11-18T15:23:00"], + [wholeSeconds, "1976-11-18T15:23:30"], + [subSeconds, "1976-11-18T15:23:30.1234"], +]; -// See options-undefined.js for {} +for (const [datetime, expected] of tests) { + const explicit = datetime.toString({ fractionalSecondDigits: undefined }); + assert.sameValue(explicit, expected, "default fractionalSecondDigits is auto (property present but undefined)"); + + const implicit = datetime.toString({}); + assert.sameValue(implicit, expected, "default fractionalSecondDigits is auto (property not present)"); + + const lambda = datetime.toString(() => {}); + assert.sameValue(lambda, expected, "default fractionalSecondDigits is auto (property not present, function object)"); +} reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/fractionalseconddigits-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/fractionalseconddigits-wrong-type.js index a964c4f72eeb..c431fad71eea 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/fractionalseconddigits-wrong-type.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/fractionalseconddigits-wrong-type.js @@ -23,6 +23,28 @@ features: [Temporal] ---*/ const datetime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 650, 0); -TemporalHelpers.checkFractionalSecondDigitsOptionWrongType(datetime); + +assert.throws(RangeError, () => datetime.toString({ fractionalSecondDigits: null }), + "null is not a number and converts to the string 'null' which is not valid for fractionalSecondDigits"); +assert.throws(RangeError, () => datetime.toString({ fractionalSecondDigits: true }), + "true is not a number and converts to the string 'true' which is not valid for fractionalSecondDigits"); +assert.throws(RangeError, () => datetime.toString({ fractionalSecondDigits: false }), + "false is not a number and converts to the string 'false' which is not valid for fractionalSecondDigits"); +assert.throws(TypeError, () => datetime.toString({ fractionalSecondDigits: Symbol() }), + "symbols are not numbers and cannot convert to strings"); +assert.throws(RangeError, () => datetime.toString({ fractionalSecondDigits: 2n }), + "bigints are not numbers and convert to strings which are not valid for fractionalSecondDigits"); +assert.throws(RangeError, () => datetime.toString({ fractionalSecondDigits: {} }), + "plain objects are not numbers and convert to strings which are not valid for fractionalSecondDigits"); + +const expected = [ + "get fractionalSecondDigits.toString", + "call fractionalSecondDigits.toString", +]; +const actual = []; +const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); +const result = datetime.toString({ fractionalSecondDigits: observer }); +assert.sameValue(result, "2000-05-02T12:34:56.98765", "object with toString uses toString return value"); +assert.compareArray(actual, expected, "object with toString calls toString and not valueOf"); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/options-wrong-type.js new file mode 100644 index 000000000000..609e7a138f57 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.tostring +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.PlainDateTime(2000, 5, 2); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.toString(value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/rounding-cross-midnight.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/rounding-cross-midnight.js new file mode 100644 index 000000000000..802d9f23b83e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/rounding-cross-midnight.js @@ -0,0 +1,16 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.tostring +description: Rounding can cross midnight +features: [Temporal] +---*/ + +const plainDateTime = new Temporal.PlainDateTime(1999, 12, 31, 23, 59, 59, 999, 999, 999); // one nanosecond before 2000-01-01T00:00:00 +for (const roundingMode of ["ceil", "halfExpand"]) { + assert.sameValue(plainDateTime.toString({ fractionalSecondDigits: 8, roundingMode }), "2000-01-01T00:00:00.00000000"); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/rounding-direction.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/rounding-direction.js new file mode 100644 index 000000000000..2198c1cbdc7d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/rounding-direction.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.tostring +description: Rounding down is towards the Big Bang, not the epoch or 1 BCE +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDateTime(-99, 12, 15, 12, 0, 0, 500); +assert.sameValue( + instance.toString({ smallestUnit: "second", roundingMode: "floor" }), + "-000099-12-15T12:00:00", + "Rounding down is towards the Big Bang, not the epoch or 1 BCE" +); +assert.sameValue( + instance.toString({ smallestUnit: "second", roundingMode: "trunc" }), + "-000099-12-15T12:00:00", + "Rounding down is towards the Big Bang, not the epoch or 1 BCE (roundingMode trunc)" +); +assert.sameValue( + instance.toString({ smallestUnit: "second", roundingMode: "ceil" }), + "-000099-12-15T12:00:01", + "Rounding up is away from the Big Bang, not the epoch or 1 BCE (roundingMode ceil)" +); +assert.sameValue( + instance.toString({ smallestUnit: "second", roundingMode: "halfExpand" }), + "-000099-12-15T12:00:01", + "Rounding up is away from the Big Bang, not the epoch or 1 BCE (roundingMode halfExpand)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/roundingmode-ceil.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/roundingmode-ceil.js new file mode 100644 index 000000000000..d4edd3f85736 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/roundingmode-ceil.js @@ -0,0 +1,40 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.tostring +description: ceil value for roundingMode option +features: [Temporal] +---*/ + +const datetime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 123, 987, 500); + +const result1 = datetime.toString({ smallestUnit: "microsecond", roundingMode: "ceil" }); +assert.sameValue(result1, "2000-05-02T12:34:56.123988", + "roundingMode is ceil (with 6 digits from smallestUnit)"); + +const result2 = datetime.toString({ fractionalSecondDigits: 6, roundingMode: "ceil" }); +assert.sameValue(result2, "2000-05-02T12:34:56.123988", + "roundingMode is ceil (with 6 digits from fractionalSecondDigits)"); + +const result3 = datetime.toString({ smallestUnit: "millisecond", roundingMode: "ceil" }); +assert.sameValue(result3, "2000-05-02T12:34:56.124", + "roundingMode is ceil (with 3 digits from smallestUnit)"); + +const result4 = datetime.toString({ fractionalSecondDigits: 3, roundingMode: "ceil" }); +assert.sameValue(result4, "2000-05-02T12:34:56.124", + "roundingMode is ceil (with 3 digits from fractionalSecondDigits)"); + +const result5 = datetime.toString({ smallestUnit: "second", roundingMode: "ceil" }); +assert.sameValue(result5, "2000-05-02T12:34:57", + "roundingMode is ceil (with 0 digits from smallestUnit)"); + +const result6 = datetime.toString({ fractionalSecondDigits: 0, roundingMode: "ceil" }); +assert.sameValue(result6, "2000-05-02T12:34:57", + "roundingMode is ceil (with 0 digits from fractionalSecondDigits)"); + +const result7 = datetime.toString({ smallestUnit: "minute", roundingMode: "ceil" }); +assert.sameValue(result7, "2000-05-02T12:35", "roundingMode is ceil (round to minute)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/roundingmode-floor.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/roundingmode-floor.js new file mode 100644 index 000000000000..297f9c19e61f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/roundingmode-floor.js @@ -0,0 +1,40 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.tostring +description: floor value for roundingMode option +features: [Temporal] +---*/ + +const datetime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 123, 987, 500); + +const result1 = datetime.toString({ smallestUnit: "microsecond", roundingMode: "floor" }); +assert.sameValue(result1, "2000-05-02T12:34:56.123987", + "roundingMode is floor (with 6 digits from smallestUnit)"); + +const result2 = datetime.toString({ fractionalSecondDigits: 6, roundingMode: "floor" }); +assert.sameValue(result2, "2000-05-02T12:34:56.123987", + "roundingMode is floor (with 6 digits from fractionalSecondDigits)"); + +const result3 = datetime.toString({ smallestUnit: "millisecond", roundingMode: "floor" }); +assert.sameValue(result3, "2000-05-02T12:34:56.123", + "roundingMode is floor (with 3 digits from smallestUnit)"); + +const result4 = datetime.toString({ fractionalSecondDigits: 3, roundingMode: "floor" }); +assert.sameValue(result4, "2000-05-02T12:34:56.123", + "roundingMode is floor (with 3 digits from fractionalSecondDigits)"); + +const result5 = datetime.toString({ smallestUnit: "second", roundingMode: "floor" }); +assert.sameValue(result5, "2000-05-02T12:34:56", + "roundingMode is floor (with 0 digits from smallestUnit)"); + +const result6 = datetime.toString({ fractionalSecondDigits: 0, roundingMode: "floor" }); +assert.sameValue(result6, "2000-05-02T12:34:56", + "roundingMode is floor (with 0 digits from fractionalSecondDigits)"); + +const result7 = datetime.toString({ smallestUnit: "minute", roundingMode: "floor" }); +assert.sameValue(result7, "2000-05-02T12:34", "roundingMode is floor (round to minute)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/roundingmode-halfExpand.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/roundingmode-halfExpand.js new file mode 100644 index 000000000000..8a693900a79e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/roundingmode-halfExpand.js @@ -0,0 +1,40 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.tostring +description: halfExpand value for roundingMode option +features: [Temporal] +---*/ + +const datetime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 123, 987, 500); + +const result1 = datetime.toString({ smallestUnit: "microsecond", roundingMode: "halfExpand" }); +assert.sameValue(result1, "2000-05-02T12:34:56.123988", + "roundingMode is halfExpand (with 6 digits from smallestUnit)"); + +const result2 = datetime.toString({ fractionalSecondDigits: 6, roundingMode: "halfExpand" }); +assert.sameValue(result2, "2000-05-02T12:34:56.123988", + "roundingMode is halfExpand (with 6 digits from fractionalSecondDigits)"); + +const result3 = datetime.toString({ smallestUnit: "millisecond", roundingMode: "halfExpand" }); +assert.sameValue(result3, "2000-05-02T12:34:56.124", + "roundingMode is halfExpand (with 3 digits from smallestUnit)"); + +const result4 = datetime.toString({ fractionalSecondDigits: 3, roundingMode: "halfExpand" }); +assert.sameValue(result4, "2000-05-02T12:34:56.124", + "roundingMode is halfExpand (with 3 digits from fractionalSecondDigits)"); + +const result5 = datetime.toString({ smallestUnit: "second", roundingMode: "halfExpand" }); +assert.sameValue(result5, "2000-05-02T12:34:56", + "roundingMode is halfExpand (with 0 digits from smallestUnit)"); + +const result6 = datetime.toString({ fractionalSecondDigits: 0, roundingMode: "halfExpand" }); +assert.sameValue(result6, "2000-05-02T12:34:56", + "roundingMode is halfExpand (with 0 digits from fractionalSecondDigits)"); + +const result7 = datetime.toString({ smallestUnit: "minute", roundingMode: "halfExpand" }); +assert.sameValue(result7, "2000-05-02T12:35", "roundingMode is halfExpand (round to minute)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/roundingmode-trunc.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/roundingmode-trunc.js new file mode 100644 index 000000000000..1ddd543c26ea --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/roundingmode-trunc.js @@ -0,0 +1,40 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.tostring +description: trunc value for roundingMode option +features: [Temporal] +---*/ + +const datetime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 123, 987, 500); + +const result1 = datetime.toString({ smallestUnit: "microsecond", roundingMode: "trunc" }); +assert.sameValue(result1, "2000-05-02T12:34:56.123987", + "roundingMode is trunc (with 6 digits from smallestUnit)"); + +const result2 = datetime.toString({ fractionalSecondDigits: 6, roundingMode: "trunc" }); +assert.sameValue(result2, "2000-05-02T12:34:56.123987", + "roundingMode is trunc (with 6 digits from fractionalSecondDigits)"); + +const result3 = datetime.toString({ smallestUnit: "millisecond", roundingMode: "trunc" }); +assert.sameValue(result3, "2000-05-02T12:34:56.123", + "roundingMode is trunc (with 3 digits from smallestUnit)"); + +const result4 = datetime.toString({ fractionalSecondDigits: 3, roundingMode: "trunc" }); +assert.sameValue(result4, "2000-05-02T12:34:56.123", + "roundingMode is trunc (with 3 digits from fractionalSecondDigits)"); + +const result5 = datetime.toString({ smallestUnit: "second", roundingMode: "trunc" }); +assert.sameValue(result5, "2000-05-02T12:34:56", + "roundingMode is trunc (with 0 digits from smallestUnit)"); + +const result6 = datetime.toString({ fractionalSecondDigits: 0, roundingMode: "trunc" }); +assert.sameValue(result6, "2000-05-02T12:34:56", + "roundingMode is trunc (with 0 digits from fractionalSecondDigits)"); + +const result7 = datetime.toString({ smallestUnit: "minute", roundingMode: "trunc" }); +assert.sameValue(result7, "2000-05-02T12:34", "roundingMode is trunc (round to minute)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/smallestunit-fractionalseconddigits.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/smallestunit-fractionalseconddigits.js new file mode 100644 index 000000000000..3da302ba50e5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/smallestunit-fractionalseconddigits.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.tostring +description: fractionalSecondDigits option is not used with smallestUnit present +features: [Temporal] +---*/ + +const datetime = new Temporal.PlainDateTime(1976, 11, 18, 12, 34, 56, 789, 999, 999); +const tests = [ + ["minute", "1976-11-18T12:34"], + ["second", "1976-11-18T12:34:56"], + ["millisecond", "1976-11-18T12:34:56.789"], + ["microsecond", "1976-11-18T12:34:56.789999"], + ["nanosecond", "1976-11-18T12:34:56.789999999"], +]; + +for (const [smallestUnit, expected] of tests) { + const string = datetime.toString({ + smallestUnit, + get fractionalSecondDigits() { throw new Test262Error("should not get fractionalSecondDigits") } + }); + assert.sameValue(string, expected, `smallestUnit: "${smallestUnit}" overrides fractionalSecondDigits`); +} + +assert.throws(RangeError, () => datetime.toString({ + smallestUnit: "hour", + get fractionalSecondDigits() { throw new Test262Error("should not get fractionalSecondDigits") } +}), "hour is an invalid smallestUnit but still overrides fractionalSecondDigits"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/smallestunit-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/smallestunit-invalid-string.js index a1a86b67b3da..2952fae8551b 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/smallestunit-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/smallestunit-invalid-string.js @@ -9,6 +9,32 @@ features: [Temporal] ---*/ const datetime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 123, 987, 500); -assert.throws(RangeError, () => datetime.toString({ smallestUnit: "other string" })); +const badValues = [ + "era", + "eraYear", + "year", + "month", + "week", + "day", + "hour", + "millisecond\0", + "mill\u0131second", + "SECOND", + "eras", + "eraYears", + "years", + "months", + "weeks", + "days", + "hours", + "milliseconds\0", + "mill\u0131seconds", + "SECONDS", + "other string", +]; +for (const smallestUnit of badValues) { + assert.throws(RangeError, () => datetime.toString({ smallestUnit }), + `"${smallestUnit}" is not a valid value for smallest unit`); +} reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/smallestunit-valid-units.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/smallestunit-valid-units.js index 45f9a886335c..453f36c7cd5d 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/smallestunit-valid-units.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toString/smallestunit-valid-units.js @@ -8,15 +8,41 @@ description: Valid units for the smallestUnit option features: [Temporal] ---*/ -const datetime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 789, 999, 999); +const datetime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 123, 456, 789); -assert.sameValue(datetime.toString({ smallestUnit: "minute" }), "2000-05-02T12:34"); -assert.sameValue(datetime.toString({ smallestUnit: "second" }), "2000-05-02T12:34:56"); -assert.sameValue(datetime.toString({ smallestUnit: "millisecond" }), "2000-05-02T12:34:56.789"); -assert.sameValue(datetime.toString({ smallestUnit: "microsecond" }), "2000-05-02T12:34:56.789999"); -assert.sameValue(datetime.toString({ smallestUnit: "nanosecond" }), "2000-05-02T12:34:56.789999999"); +function test(instance, expectations, description) { + for (const [smallestUnit, expectedResult] of expectations) { + assert.sameValue(instance.toString({ smallestUnit }), expectedResult, + `${description} with smallestUnit "${smallestUnit}"`); + } +} + +test( + datetime, + [ + ["minute", "2000-05-02T12:34"], + ["second", "2000-05-02T12:34:56"], + ["millisecond", "2000-05-02T12:34:56.123"], + ["microsecond", "2000-05-02T12:34:56.123456"], + ["nanosecond", "2000-05-02T12:34:56.123456789"], + ], + "subseconds toString" +); + +test( + new Temporal.PlainDateTime(2000, 5, 2, 12, 34), + [ + ["minute", "2000-05-02T12:34"], + ["second", "2000-05-02T12:34:00"], + ["millisecond", "2000-05-02T12:34:00.000"], + ["microsecond", "2000-05-02T12:34:00.000000"], + ["nanosecond", "2000-05-02T12:34:00.000000000"], + ], + "whole minutes toString" +); const notValid = [ + "era", "year", "month", "week", @@ -25,7 +51,8 @@ const notValid = [ ]; notValid.forEach((smallestUnit) => { - assert.throws(RangeError, () => datetime.toString({ smallestUnit }), smallestUnit); + assert.throws(RangeError, () => datetime.toString({ smallestUnit }), + `"${smallestUnit}" is not a valid unit for the smallestUnit option`); }); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/basic.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/basic.js new file mode 100644 index 000000000000..fe69aa0c5956 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/basic.js @@ -0,0 +1,18 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.tozoneddatetime +description: Straightforward case of using UTC +features: [Temporal] +---*/ + +const dt = new Temporal.PlainDateTime(2020, 1, 1, 0, 0); +const zdt = dt.toZonedDateTime("UTC"); + +assert.sameValue(zdt.epochNanoseconds, 1577836800000000000n, "nanoseconds"); +assert.sameValue(zdt.calendar.toString(), "iso8601", "calendar"); +assert.sameValue(zdt.timeZone.toString(), "UTC", "timezone"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/disambiguation-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/disambiguation-invalid-string.js index 1b5a2dab245f..a24bc6498978 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/disambiguation-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/disambiguation-invalid-string.js @@ -17,6 +17,13 @@ features: [Temporal] const datetime = new Temporal.PlainDateTime(2001, 9, 9, 1, 46, 40, 987, 654, 321); const timeZone = new Temporal.TimeZone("UTC"); -assert.throws(RangeError, () => datetime.toZonedDateTime(timeZone, { disambiguation: "other string" })); +const invalidStrings = ["obviously bad", "", "EARLIER", "earlıer", "late\u0131r", "reject\0"]; +invalidStrings.forEach((s) => { + assert.throws( + RangeError, + () => datetime.toZonedDateTime(timeZone, { disambiguation: s }), + `invalid disambiguation string (${s})`); +}); + reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/invalid-instant.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/invalid-instant.js new file mode 100644 index 000000000000..525b3b102f3e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/invalid-instant.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.tozoneddatetime +description: Convert to zoned datetime outside valid range +features: [Temporal] +---*/ + +const max = new Temporal.PlainDateTime(275760, 9, 13, 23, 59, 59, 999, 999, 999); +const min = new Temporal.PlainDateTime(-271821, 4, 19, 0, 0, 0, 0, 0, 1); + +assert.throws( + RangeError, + () => max.toZonedDateTime("UTC"), + "outside of Instant range (too big)" +); + +assert.throws( + RangeError, + () => min.toZonedDateTime("UTC"), + "outside of Instant range (too small)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/multiple-instants.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/multiple-instants.js new file mode 100644 index 000000000000..f9f94f4c6fe3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/multiple-instants.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.tozoneddatetime +description: Checking disambiguation options for daylight savings time changes +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const tz = TemporalHelpers.springForwardFallBackTimeZone(); + +const dt1 = new Temporal.PlainDateTime(2000, 4, 2, 2); + +const zdt1 = dt1.toZonedDateTime(tz); +const zdt1_compatible = dt1.toZonedDateTime(tz, { disambiguation: "compatible" }); +const zdt1_earlier = dt1.toZonedDateTime(tz, { disambiguation: "earlier" }); +const zdt1_later = dt1.toZonedDateTime(tz, { disambiguation: "later" }); + +assert.sameValue(zdt1.epochNanoseconds, 954669600000000000n, "Fall DST (no disambiguation)"); +assert.sameValue(zdt1_compatible.epochNanoseconds, 954669600000000000n, "Fall DST (disambiguation = compatible)"); +assert.sameValue(zdt1_earlier.epochNanoseconds, 954666000000000000n, "Fall DST (disambiguation = earlier)"); +assert.sameValue(zdt1_later.epochNanoseconds, 954669600000000000n, "Fall DST (disambiguation = later)"); + +assert.throws( + RangeError, + () => dt1.toZonedDateTime(tz, { disambiguation: "reject" }), + "Fall DST (disambiguation = reject)" +); + +const dt2 = new Temporal.PlainDateTime(2000, 10, 29, 1); + +const zdt2 = dt2.toZonedDateTime(tz); +const zdt2_compatible = dt2.toZonedDateTime(tz, { disambiguation: "compatible" }); +const zdt2_earlier = dt2.toZonedDateTime(tz, { disambiguation: "earlier" }); +const zdt2_later = dt2.toZonedDateTime(tz, { disambiguation: "later" }); + +assert.sameValue(zdt2.epochNanoseconds, 972806400000000000n, "Spring DST (no disambiguation)"); +assert.sameValue(zdt2_compatible.epochNanoseconds, 972806400000000000n, "Spring DST (disambiguation = compatible)"); +assert.sameValue(zdt2_earlier.epochNanoseconds, 972806400000000000n, "Spring DST (disambiguation = earlier)"); +assert.sameValue(zdt2_later.epochNanoseconds, 972810000000000000n, "Spring DST (disambiguation = later)"); + +assert.throws( + RangeError, + () => dt2.toZonedDateTime(tz, { disambiguation: "reject" }), + "Spring DST (disambiguation = reject)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/options-object.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/options-object.js new file mode 100644 index 000000000000..cc57f979f056 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/options-object.js @@ -0,0 +1,25 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.tozoneddatetime +description: Empty object may be used as options +features: [Temporal] +---*/ + +const dt = new Temporal.PlainDateTime(2019, 10, 29, 10, 46, 38, 271, 986, 102); + +assert.sameValue( + dt.toZonedDateTime("UTC", {}).epochNanoseconds, + 1572345998271986102n, + "options may be an empty plain object" +); + +assert.sameValue( + dt.toZonedDateTime("UTC", () => {}).epochNanoseconds, + 1572345998271986102n, + "options may be a function object" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/options-wrong-type.js new file mode 100644 index 000000000000..afa47869ffbb --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.tozoneddatetime +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.PlainDateTime(2000, 5, 2); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.toZonedDateTime("UTC", value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-string-leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-string-leap-second.js new file mode 100644 index 000000000000..4db1ef0a9965 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-string-leap-second.js @@ -0,0 +1,23 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.tozoneddatetime +description: Leap second is a valid ISO string for TimeZone +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDateTime(2000, 5, 2); +let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; + +const result1 = instance.toZonedDateTime(timeZone); +assert.sameValue(result1.timeZone.id, "UTC", "leap second is a valid ISO string for TimeZone"); +const result2 = instance.toZonedDateTime({ timeZone }); +assert.sameValue(result2.timeZone.id, "UTC", "leap second is a valid ISO string for TimeZone (nested property)"); + +timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; +assert.throws(RangeError, () => instance.toZonedDateTime(timeZone), "leap second in time zone name not valid"); +assert.throws(RangeError, () => instance.toZonedDateTime({ timeZone }), "leap second in time zone name not valid (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-string-year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-string-year-zero.js new file mode 100644 index 000000000000..e6c578cae7b9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-string-year-zero.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.tozoneddatetime +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.PlainDateTime(2000, 5, 2); +invalidStrings.forEach((timeZone) => { + assert.throws( + RangeError, + () => instance.toZonedDateTime(timeZone), + "reject minus zero as extended year" + ); + assert.throws( + RangeError, + () => instance.toZonedDateTime({ timeZone }), + "reject minus zero as extended year (nested property)" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-wrong-type.js new file mode 100644 index 000000000000..72fda3967479 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/timezone-wrong-type.js @@ -0,0 +1,41 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.tozoneddatetime +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for TimeZone +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.PlainDateTime(2000, 5, 2); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], +]; + +for (const [timeZone, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.toZonedDateTime(timeZone), `${description} does not convert to a valid ISO string`); + assert.throws(RangeError, () => instance.toZonedDateTime({ timeZone }), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [timeZone, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.toZonedDateTime(timeZone), `${description} is not a valid object and does not convert to a string`); + assert.throws(TypeError, () => instance.toZonedDateTime({ timeZone }), `${description} is not a valid object and does not convert to a string (nested property)`); +} + +const timeZone = undefined; +assert.throws(RangeError, () => instance.toZonedDateTime({ timeZone }), `undefined is always a RangeError as nested property`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/argument-number.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/argument-number.js new file mode 100644 index 000000000000..516ee44374e8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/argument-number.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.until +description: A number is converted to a string, then to Temporal.PlainDateTime +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDateTime(1976, 11, 18); + +let arg = 19761118; + +const result = instance.until(arg); +TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19761118 is a valid ISO string for PlainDateTime"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.until(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDateTime` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/argument-object.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/argument-object.js new file mode 100644 index 000000000000..33c81b42aff7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/argument-object.js @@ -0,0 +1,20 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.until +description: Plain objects are accepted as an argument +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const dt = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789); + +TemporalHelpers.assertDuration( + dt.until({ year: 2019, month: 10, day: 29, hour: 10 }), + 0, 0, 0, 15684, 18, 36, 29, 876, 543, 211, + "casts argument (plain object)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..c212b735e822 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.until +description: Leap second is a valid ISO string for a calendar in a property bag +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDateTime(1976, 11, 18); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.until(arg); +TemporalHelpers.assertDuration( + result1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.until(arg); +TemporalHelpers.assertDuration( + result2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..1905aa5a5496 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/argument-propertybag-calendar-number.js @@ -0,0 +1,45 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.until +description: A number as calendar in a property bag is converted to a string, then to a calendar +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDateTime(1976, 11, 18); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.until(arg); +TemporalHelpers.assertDuration(result1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.until(arg); +TemporalHelpers.assertDuration(result2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + assert.throws( + RangeError, + () => instance.until(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.until(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..cfc670b4bfb4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.until +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.until(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.until(arg), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.until(arg), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.until(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.until(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..c19d023f9439 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.until +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.until(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/argument-string.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/argument-string.js new file mode 100644 index 000000000000..e02d0773b79f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/argument-string.js @@ -0,0 +1,20 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.until +description: Date-like strings are accepted +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const dt = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789); + +TemporalHelpers.assertDuration( + dt.until("2019-10-29T10:46:38.271986102"), + 0, 0, 0, 15684, 19, 23, 8, 148, 529, 313, + "casts argument (string)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/argument-wrong-type.js new file mode 100644 index 000000000000..0737591123ed --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/argument-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.until +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDateTime +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.until(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDateTime, "Temporal.PlainDateTime, object"], + [Temporal.PlainDateTime.prototype, "Temporal.PlainDateTime.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.until(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/balance-negative-duration.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/balance-negative-duration.js index 3a8d97e43203..131576e4a73e 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/balance-negative-duration.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/balance-negative-duration.js @@ -26,12 +26,12 @@ features: [Temporal] const earlier1 = new Temporal.PlainDateTime(2000, 5, 2, 9); const later1 = new Temporal.PlainDateTime(2000, 5, 5, 10); -const result1 = later1.until(earlier1, { largestUnit: 'day' }); +const result1 = later1.until(earlier1, { largestUnit: "day" }); TemporalHelpers.assertDuration(result1, 0, 0, 0, -3, -1, 0, 0, 0, 0, 0, "date sign == time sign"); const earlier2 = new Temporal.PlainDateTime(2000, 5, 2, 10); const later2 = new Temporal.PlainDateTime(2000, 5, 5, 9); -const result2 = later2.until(earlier2, { largestUnit: 'day' }); +const result2 = later2.until(earlier2, { largestUnit: "day" }); TemporalHelpers.assertDuration(result2, 0, 0, 0, -2, -23, 0, 0, 0, 0, 0, "date sign != time sign"); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/balance.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/balance.js index bb664ddfa802..70b3889a16f3 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/balance.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/balance.js @@ -9,19 +9,19 @@ includes: [temporalHelpers.js] features: [Temporal] ---*/ -const a = Temporal.PlainDateTime.from('2017-10-05T08:07:14+00:00[UTC]'); -const b = Temporal.PlainDateTime.from('2021-03-05T03:32:45+00:00[UTC]'); -const c = Temporal.PlainDateTime.from('2021-03-05T09:32:45+00:00[UTC]'); +const a = Temporal.PlainDateTime.from("2017-10-05T08:07:14+00:00[UTC]"); +const b = Temporal.PlainDateTime.from("2021-03-05T03:32:45+00:00[UTC]"); +const c = Temporal.PlainDateTime.from("2021-03-05T09:32:45+00:00[UTC]"); -const r1 = a.until(b, { largestUnit: 'months' }); +const r1 = a.until(b, { largestUnit: "months" }); TemporalHelpers.assertDuration(r1, 0, 40, 0, 27, 19, 25, 31, 0, 0, 0, "r1"); assert.sameValue(a.add(r1).toString(), b.toString(), "a.add(r1)"); -const r2 = b.until(a, { largestUnit: 'months' }); +const r2 = b.until(a, { largestUnit: "months" }); TemporalHelpers.assertDuration(r2, 0, -40, 0, -30, -19, -25, -31, 0, 0, 0, "r2"); assert.sameValue(b.add(r2).toString(), a.toString(), "b.add(r2)"); -const r3 = c.until(a, { largestUnit: 'months' }); +const r3 = c.until(a, { largestUnit: "months" }); TemporalHelpers.assertDuration(r3, 0, -41, 0, 0, -1, -25, -31, 0, 0, 0, "r3"); assert.sameValue(c.add(r3).toString(), a.toString(), "c.add(r3)"); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/different-calendars-throws.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/different-calendars-throws.js index 14c6f18eca4f..c123a2a6ce38 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/different-calendars-throws.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/different-calendars-throws.js @@ -9,12 +9,7 @@ features: [Temporal] ---*/ const dt1 = new Temporal.PlainDateTime(2000, 1, 1, 0, 0, 0, 0, 0, 0); - -const cal = { - id: 'thisisnotiso' -}; - -const dt2 = new Temporal.PlainDateTime(2000, 1, 1, 0, 0, 0, 0, 0, 0, cal); +const dt2 = new Temporal.PlainDateTime(2000, 1, 1, 0, 0, 0, 0, 0, 0, {}); assert.throws( RangeError, diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/largestunit-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/largestunit-invalid-string.js index 1c33be37fc90..d7efde3f4719 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/largestunit-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/largestunit-invalid-string.js @@ -10,9 +10,22 @@ features: [Temporal] const earlier = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 0, 0, 0); const later = new Temporal.PlainDateTime(2001, 6, 3, 13, 35, 57, 987, 654, 321); -const values = ["era", "eraYear", "other string"]; -for (const largestUnit of values) { - assert.throws(RangeError, () => earlier.until(later, { largestUnit })); +const badValues = [ + "era", + "eraYear", + "millisecond\0", + "mill\u0131second", + "SECOND", + "eras", + "eraYears", + "milliseconds\0", + "mill\u0131seconds", + "SECONDS", + "other string" +]; +for (const largestUnit of badValues) { + assert.throws(RangeError, () => earlier.until(later, { largestUnit }), + `"${largestUnit}" is not a valid value for largestUnit`); } reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/leap-second.js new file mode 100644 index 000000000000..1639f54e9290 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/leap-second.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.until +description: Leap second is a valid ISO string for PlainDateTime +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDateTime(2016, 12, 31, 23, 59, 59); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.until(arg); +TemporalHelpers.assertDuration( + result1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "leap second is a valid ISO string for PlainDateTime" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.until(arg); +TemporalHelpers.assertDuration( + result2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "second: 60 is ignored in property bag for PlainDateTime" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/no-unnecessary-units.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/no-unnecessary-units.js index 3946ce1ac188..551ec8c4eabf 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/no-unnecessary-units.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/no-unnecessary-units.js @@ -9,17 +9,17 @@ features: [Temporal] includes: [temporalHelpers.js] ---*/ -const lastFeb20 = new Temporal.PlainDateTime(2020, 2, 29, 0, 0); -const lastFeb21 = new Temporal.PlainDateTime(2021, 2, 28, 0, 0); +const feb29 = new Temporal.PlainDateTime(2020, 2, 29, 0, 0); +const feb28 = new Temporal.PlainDateTime(2021, 2, 28, 0, 0); TemporalHelpers.assertDuration( - lastFeb20.until(lastFeb21, { largestUnit: "months" }), + feb29.until(feb28, { largestUnit: "months" }), 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, "does not include higher units than necessary (largest unit = months)" ); TemporalHelpers.assertDuration( - lastFeb20.until(lastFeb21, { largestUnit: "years" }), + feb29.until(feb28, { largestUnit: "years" }), 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "does not include higher units than necessary (largest unit = years)" ); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/options-empty.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/options-empty.js new file mode 100644 index 000000000000..f02bab55c0d4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/options-empty.js @@ -0,0 +1,23 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.until +description: Empty options are valid +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const feb20 = new Temporal.PlainDateTime(2020, 2, 1, 0, 0); +const feb21 = new Temporal.PlainDateTime(2021, 2, 1, 0, 0); + +TemporalHelpers.assertDuration(feb20.until(feb21, {}), + 0, 0, 0, 366, 0, 0, 0, 0, 0, 0, + "empty options (plain object) are acceptable"); + +TemporalHelpers.assertDuration(feb20.until(feb21, () => {}), + 0, 0, 0, 366, 0, 0, 0, 0, 0, 0, + "empty options (function object) are acceptable"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/options-invalid.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/options-invalid.js new file mode 100644 index 000000000000..b6726009a2d0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/options-invalid.js @@ -0,0 +1,23 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.until +description: A variety of invalid option arguments +features: [Temporal, Symbol] +---*/ + +const feb20 = new Temporal.PlainDateTime(2020, 2, 1, 0, 0); +const feb21 = new Temporal.PlainDateTime(2021, 2, 1, 0, 0); + +const badOptions = [null, 1, 'obviously invalid', true, Symbol('foo'), 1n]; +badOptions.forEach((bad) => { + assert.throws( + TypeError, + () => feb20.until(feb21, bad), + `unacceptable options (${typeof bad})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/options-wrong-type.js new file mode 100644 index 000000000000..432e7b5a81de --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.until +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.PlainDateTime(2000, 5, 2); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.until(new Temporal.PlainDateTime(1976, 11, 18), value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/round-relative-to-receiver.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/round-relative-to-receiver.js new file mode 100644 index 000000000000..9079b73683fe --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/round-relative-to-receiver.js @@ -0,0 +1,28 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.until +description: Rounding happens relative to receiver +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const dt1 = new Temporal.PlainDateTime(2019, 1, 1); +const dt2 = new Temporal.PlainDateTime(2020, 7, 2); +const options = { smallestUnit: "years", roundingMode: "halfExpand" }; + +TemporalHelpers.assertDuration( + dt1.until(dt2, options), + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "rounds relative to the receiver (positive case)" +); + +TemporalHelpers.assertDuration( + dt2.until(dt1, options), + -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "rounds relative to the receiver (negative case)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/roundingincrement-basic.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/roundingincrement-basic.js new file mode 100644 index 000000000000..95bfee26408c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/roundingincrement-basic.js @@ -0,0 +1,51 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.until +description: A variety of rounding increments +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const earlier = new Temporal.PlainDateTime(2019, 1, 8, 8, 22, 36, 123, 456, 789); +const later = new Temporal.PlainDateTime(2021, 9, 7, 12, 39, 40, 987, 654, 321); + +TemporalHelpers.assertDuration( + earlier.until(later, {smallestUnit: "hours", roundingIncrement: 3, roundingMode: "halfExpand"}), + 0, 0, 0, 973, 3, 0, 0, 0, 0, 0, + "rounds to an increment of hours" +); + +TemporalHelpers.assertDuration( + earlier.until(later, {smallestUnit: "minutes", roundingIncrement: 30, roundingMode: "halfExpand"}), + 0, 0, 0, 973, 4, 30, 0, 0, 0, 0, + "rounds to an increment of minutes" +); + +TemporalHelpers.assertDuration( + earlier.until(later, {smallestUnit: "seconds", roundingIncrement: 15, roundingMode: "halfExpand"}), + 0, 0, 0, 973, 4, 17, 0, 0, 0, 0, + "rounds to an increment of seconds" +); + +TemporalHelpers.assertDuration( + earlier.until(later, {smallestUnit: "milliseconds", roundingIncrement: 10, roundingMode: "halfExpand"}), + 0, 0, 0, 973, 4, 17, 4, 860, 0, 0, + "rounds to an increment of milliseconds" +); + +TemporalHelpers.assertDuration( + earlier.until(later, {smallestUnit: "microseconds", roundingIncrement: 10, roundingMode: "halfExpand"}), + 0, 0, 0, 973, 4, 17, 4, 864, 200, 0, + "rounds to an increment of microseconds" +); + +TemporalHelpers.assertDuration( + earlier.until(later, {smallestUnit: "nanoseconds", roundingIncrement: 10, roundingMode: "halfExpand"}), + 0, 0, 0, 973, 4, 17, 4, 864, 197, 530, + "rounds to an increment of nanoseconds" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/roundingincrement-cleanly-divides.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/roundingincrement-cleanly-divides.js new file mode 100644 index 000000000000..f53b5f610bab --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/roundingincrement-cleanly-divides.js @@ -0,0 +1,42 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.until +description: Rounding increments that cleanly divide relevant units +features: [Temporal] +---*/ + +const earlier = new Temporal.PlainDateTime(2019, 1, 8, 8, 22, 36, 123, 456, 789); +const later = new Temporal.PlainDateTime(2021, 9, 7, 12, 39, 40, 987, 654, 321); + +[1, 2, 3, 4, 6, 8, 12].forEach((roundingIncrement) => { + const options = {smallestUnit: "hours", roundingIncrement}; + assert( + earlier.until(later, options) instanceof Temporal.Duration, + `valid hour increments divide 24 (rounding increment = ${roundingIncrement})` + ); +}); + +["minutes", "seconds"].forEach((smallestUnit) => { + [1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30].forEach((roundingIncrement) => { + const options = {smallestUnit, roundingIncrement}; + assert( + earlier.until(later, options) instanceof Temporal.Duration, + `valid ${smallestUnit} increments divide 60 (rounding increment = ${roundingIncrement})` + ); + }); +}); + +["milliseconds", "microseconds", "nanoseconds"].forEach((smallestUnit) => { + [1, 2, 4, 5, 8, 10, 20, 25, 40, 50, 100, 125, 200, 250, 500].forEach((roundingIncrement) => { + const options = {smallestUnit, roundingIncrement}; + assert( + earlier.until(later, options) instanceof Temporal.Duration, + `valid ${smallestUnit} increments divide 1000 (rounding increment = ${roundingIncrement}` + ); + }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/roundingincrement-does-not-divide.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/roundingincrement-does-not-divide.js new file mode 100644 index 000000000000..47fd0114bc44 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/roundingincrement-does-not-divide.js @@ -0,0 +1,48 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.until +description: Rounding increments that do not cleanly divide the relevant unit +features: [Temporal] +---*/ + +const earlier = new Temporal.PlainDateTime(2019, 1, 8, 8, 22, 36, 123, 456, 789); +const later = new Temporal.PlainDateTime(2021, 9, 7, 12, 39, 40, 987, 654, 321); + +const nondivisibleUnits = { + "hours": 11, + "minutes": 29, + "seconds": 29, + "milliseconds": 29, + "microseconds": 29, + "nanoseconds": 29 +}; + +Object.entries(nondivisibleUnits).forEach(([unit, increment]) => { + assert.throws( + RangeError, + () => earlier.until(later, {smallestUnit: unit, roundingIncrement: increment}), + `throws on increments that do not divide evenly into the next highest (unit = ${unit}, increment = ${increment})` + ); +}); + +const equalDivisibleUnits = { + "hours": 24, + "minutes": 60, + "seconds": 60, + "milliseconds": 1000, + "microseconds": 1000, + "nanoseconds": 1000 +}; + +Object.entries(equalDivisibleUnits).forEach(([unit, increment]) => { + assert.throws( + RangeError, + () => earlier.until(later, {smallestUnit: unit, roundingIncrement: increment}), + `throws on increments that are equal to the next highest (unit = ${unit}, rounding increment = ${increment})` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/roundingmode-ceil-basic.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/roundingmode-ceil-basic.js new file mode 100644 index 000000000000..ab7aecc7dacd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/roundingmode-ceil-basic.js @@ -0,0 +1,42 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.until +description: Checking that ceiling rounding mode rounds correctly +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const earlier = new Temporal.PlainDateTime(2019, 1, 8, 8, 22, 36, 123, 456, 789); +const later = new Temporal.PlainDateTime(2021, 9, 7, 12, 39, 40, 987, 654, 321); + +const incrementOneCeil = [ + ["years", [3], [-2]], + ["months", [0, 32], [0, -31]], + ["weeks", [0, 0, 140], [0, 0, -139]], + ["days", [0, 0, 0, 974], [0, 0, 0, -973]], + ["hours", [0, 0, 0, 973, 5], [0, 0, 0, -973, -4]], + ["minutes", [0, 0, 0, 973, 4, 18], [0, 0, 0, -973, -4, -17]], + ["seconds", [0, 0, 0, 973, 4, 17, 5], [0, 0, 0, -973, -4, -17, -4]], + ["milliseconds", [0, 0, 0, 973, 4, 17, 4, 865], [0, 0, 0, -973, -4, -17, -4, -864]], + ["microseconds", [0, 0, 0, 973, 4, 17, 4, 864, 198], [0, 0, 0, -973, -4, -17, -4, -864, -197]], + ["nanoseconds", [0, 0, 0, 973, 4, 17, 4, 864, 197, 532], [0, 0, 0, -973, -4, -17, -4, -864, -197, -532]] +]; +incrementOneCeil.forEach(([smallestUnit, expectedPositive, expectedNegative]) => { + const [py, pm = 0, pw = 0, pd = 0, ph = 0, pmin = 0, ps = 0, pms = 0, pµs = 0, pns = 0] = expectedPositive; + const [ny, nm = 0, nw = 0, nd = 0, nh = 0, nmin = 0, ns = 0, nms = 0, nµs = 0, nns = 0] = expectedNegative; + TemporalHelpers.assertDuration( + earlier.until(later, { smallestUnit, roundingMode: "ceil" }), + py, pm, pw, pd, ph, pmin, ps, pms, pµs, pns, + `rounds up to ${smallestUnit} (roundingMode = ceil, positive case)` + ); + TemporalHelpers.assertDuration( + later.until(earlier, {smallestUnit, roundingMode: "ceil"}), + ny, nm, nw, nd, nh, nmin, ns, nms, nµs, nns, + `rounds up to ${smallestUnit} (rounding mode = ceil, negative case)` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/roundingmode-floor-basic.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/roundingmode-floor-basic.js new file mode 100644 index 000000000000..6464a6000c18 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/roundingmode-floor-basic.js @@ -0,0 +1,42 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.until +description: Checking that floor rounding mode rounds correctly +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const earlier = new Temporal.PlainDateTime(2019, 1, 8, 8, 22, 36, 123, 456, 789); +const later = new Temporal.PlainDateTime(2021, 9, 7, 12, 39, 40, 987, 654, 321); + +const incrementOneFloor = [ + ["years", [2], [-3]], + ["months", [0, 31], [0, -32]], + ["weeks", [0, 0, 139], [0, 0, -140]], + ["days", [0, 0, 0, 973], [0, 0, 0, -974]], + ["hours", [0, 0, 0, 973, 4], [0, 0, 0, -973, -5]], + ["minutes", [0, 0, 0, 973, 4, 17], [0, 0, 0, -973, -4, -18]], + ["seconds", [0, 0, 0, 973, 4, 17, 4], [0, 0, 0, -973, -4, -17, -5]], + ["milliseconds", [0, 0, 0, 973, 4, 17, 4, 864], [0, 0, 0, -973, -4, -17, -4, -865]], + ["microseconds", [0, 0, 0, 973, 4, 17, 4, 864, 197], [0, 0, 0, -973, -4, -17, -4, -864, -198]], + ["nanoseconds", [0, 0, 0, 973, 4, 17, 4, 864, 197, 532], [0, 0, 0, -973, -4, -17, -4, -864, -197, -532]] +]; +incrementOneFloor.forEach(([smallestUnit, expectedPositive, expectedNegative]) => { + const [py, pm = 0, pw = 0, pd = 0, ph = 0, pmin = 0, ps = 0, pms = 0, pµs = 0, pns = 0] = expectedPositive; + const [ny, nm = 0, nw = 0, nd = 0, nh = 0, nmin = 0, ns = 0, nms = 0, nµs = 0, nns = 0] = expectedNegative; + TemporalHelpers.assertDuration( + earlier.until(later, { smallestUnit, roundingMode: "floor" }), + py, pm, pw, pd, ph, pmin, ps, pms, pµs, pns, + `rounds down to ${smallestUnit} (rounding mode = floor, positive case)` + ); + TemporalHelpers.assertDuration( + later.until(earlier, {smallestUnit, roundingMode: "floor"}), + ny, nm, nw, nd, nh, nmin, ns, nms, nµs, nns, + `rounds down to ${smallestUnit} (rounding mode = floor, negative case)` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/roundingmode-halfexpand-basic.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/roundingmode-halfexpand-basic.js new file mode 100644 index 000000000000..7715276d485d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/roundingmode-halfexpand-basic.js @@ -0,0 +1,54 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.until +description: Checking that half-expand rounding mode rounds correctly +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const earlier = new Temporal.PlainDateTime(2019, 1, 8, 8, 22, 36, 123, 456, 789); +const later = new Temporal.PlainDateTime(2021, 9, 7, 12, 39, 40, 987, 654, 321); + +function ensureUnsignedZero(x) { + return Object.is(x, -0) ? 0 : x; +} + +const incrementOneNearest = [ + ["years", [3]], + ["months", [0, 32]], + ["weeks", [0, 0, 139]], + ["days", [0, 0, 0, 973]], + ["hours", [0, 0, 0, 973, 4]], + ["minutes", [0, 0, 0, 973, 4, 17]], + ["seconds", [0, 0, 0, 973, 4, 17, 5]], + ["milliseconds", [0, 0, 0, 973, 4, 17, 4, 864]], + ["microseconds", [0, 0, 0, 973, 4, 17, 4, 864, 198]], + ["nanoseconds", [0, 0, 0, 973, 4, 17, 4, 864, 197, 532]] +]; +incrementOneNearest.forEach(([smallestUnit, expected]) => { + const [y, m = 0, w = 0, d = 0, h = 0, min = 0, s = 0, ms = 0, µs = 0, ns = 0] = expected; + TemporalHelpers.assertDuration( + earlier.until(later, {smallestUnit, roundingMode: "halfExpand"}), + y, m, w, d, h, min, s, ms, µs, ns, + `rounds to nearest ${smallestUnit} (positive case, rounding mode = halfExpand)` + ); + TemporalHelpers.assertDuration( + later.until(earlier, {smallestUnit, roundingMode: "halfExpand"}), + ensureUnsignedZero(-y), + ensureUnsignedZero(-m), + ensureUnsignedZero(-w), + ensureUnsignedZero(-d), + ensureUnsignedZero(-h), + ensureUnsignedZero(-min), + ensureUnsignedZero(-s), + ensureUnsignedZero(-ms), + ensureUnsignedZero(-µs), + ensureUnsignedZero(-ns), + `rounds to nearest ${smallestUnit} (negative case, rounding mode = halfExpand)` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/roundingmode-halfexpand-default-changes.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/roundingmode-halfexpand-default-changes.js new file mode 100644 index 000000000000..e03e4d7ce39a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/roundingmode-halfexpand-default-changes.js @@ -0,0 +1,31 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.until +description: A different default for largest unit will be used if smallest unit is larger than "days" +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const earlier = new Temporal.PlainDateTime(2019, 1, 8, 8, 22, 36, 123, 456, 789); +const later = new Temporal.PlainDateTime(2021, 9, 7, 12, 39, 40, 987, 654, 321); + +TemporalHelpers.assertDuration( + earlier.until(later, {smallestUnit: "years", roundingMode: "halfExpand"}), + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "assumes a different default for largestUnit if smallestUnit is larger than days (largest unit = years)" +); +TemporalHelpers.assertDuration( + earlier.until(later, {smallestUnit: "months", roundingMode: "halfExpand"}), + 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, + "assumes a different default for largestUnit if smallestUnit is larger than days (largest unit = months)" +); +TemporalHelpers.assertDuration( + earlier.until(later, {smallestUnit: "weeks", roundingMode: "halfExpand"}), + 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, + "assumes a different default for largestUnit if smallestUnit is larger than days (largest unit = weeks)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/roundingmode-trunc-basic.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/roundingmode-trunc-basic.js new file mode 100644 index 000000000000..5609e4d4d840 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/roundingmode-trunc-basic.js @@ -0,0 +1,54 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.until +description: A variety of tests for truncation (trunc) round mode +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const earlier = new Temporal.PlainDateTime(2019, 1, 8, 8, 22, 36, 123, 456, 789); +const later = new Temporal.PlainDateTime(2021, 9, 7, 12, 39, 40, 987, 654, 321); + +function ensureUnsignedZero(x) { + return Object.is(x, -0) ? 0 : x; +} + +const incrementOneTrunc = [ + ["years", [2]], + ["months", [0, 31]], + ["weeks", [0, 0, 139]], + ["days", [0, 0, 0, 973]], + ["hours", [0, 0, 0, 973, 4]], + ["minutes", [0, 0, 0, 973, 4, 17]], + ["seconds", [0, 0, 0, 973, 4, 17, 4]], + ["milliseconds", [0, 0, 0, 973, 4, 17, 4, 864]], + ["microseconds", [0, 0, 0, 973, 4, 17, 4, 864, 197]], + ["nanoseconds", [0, 0, 0, 973, 4, 17, 4, 864, 197, 532]] +]; +incrementOneTrunc.forEach(([smallestUnit, expected]) => { + const [y, m = 0, w = 0, d = 0, h = 0, min = 0, s = 0, ms = 0, µs = 0, ns = 0] = expected; + TemporalHelpers.assertDuration( + earlier.until(later, {smallestUnit, roundingMode: "trunc"}), + y, m, w, d, h, min, s, ms, µs, ns, + `truncates to ${smallestUnit} (rounding mode = trunc, positive case)` + ); + TemporalHelpers.assertDuration( + later.until(earlier, {smallestUnit, roundingMode: "trunc"}), + ensureUnsignedZero(-y), + ensureUnsignedZero(-m), + ensureUnsignedZero(-w), + ensureUnsignedZero(-d), + ensureUnsignedZero(-h), + ensureUnsignedZero(-min), + ensureUnsignedZero(-s), + ensureUnsignedZero(-ms), + ensureUnsignedZero(-µs), + ensureUnsignedZero(-ns), + `truncates to ${smallestUnit} (rounding mode = trunc, negative case)` + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/roundingmode-trunc-is-default.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/roundingmode-trunc-is-default.js new file mode 100644 index 000000000000..4a53827f0f2a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/roundingmode-trunc-is-default.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.until +description: Show that truncation is the default rounding mode +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const earlier = new Temporal.PlainDateTime(2019, 1, 8, 8, 22, 36, 123, 456, 789); +const later = new Temporal.PlainDateTime(2021, 9, 7, 12, 39, 40, 987, 654, 321); + +TemporalHelpers.assertDuration( + earlier.until(later, {smallestUnit: "minutes"}), + 0, 0, 0, 973, 4, 17,0, 0, 0, 0, + "trunc is the default (round up)" +); + +TemporalHelpers.assertDuration( + earlier.until(later, {smallestUnit: "seconds"}), + 0, 0, 0, 973, 4, 17, 4, 0, 0, 0, + "trunc is the default (round down)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/smallestunit-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/smallestunit-invalid-string.js index adf6f19a570c..eb622b0bb170 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/smallestunit-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/smallestunit-invalid-string.js @@ -10,9 +10,22 @@ features: [Temporal] const earlier = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 0, 0, 0); const later = new Temporal.PlainDateTime(2000, 5, 3, 13, 35, 57, 987, 654, 321); -const values = ["era", "eraYear", "other string"]; -for (const smallestUnit of values) { - assert.throws(RangeError, () => earlier.until(later, { smallestUnit })); +const badValues = [ + "era", + "eraYear", + "millisecond\0", + "mill\u0131second", + "SECOND", + "eras", + "eraYears", + "milliseconds\0", + "mill\u0131seconds", + "SECONDS", + "other string", +]; +for (const smallestUnit of badValues) { + assert.throws(RangeError, () => earlier.until(later, { smallestUnit }), + `"${smallestUnit}" is not a valid value for smallest unit`); } reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/subseconds.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/subseconds.js index b655b10c7f7e..d6b5998172a3 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/subseconds.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/subseconds.js @@ -4,34 +4,28 @@ /*--- esid: sec-temporal.plaindatetime.prototype.until -description: Largest unit is respected +description: Returned granularity may be finer than seconds includes: [temporalHelpers.js] features: [Temporal] ---*/ const feb20 = new Temporal.PlainDateTime(2020, 2, 1, 0, 0); - -const later = feb20.add({ - days: 1, - milliseconds: 250, - microseconds: 250, - nanoseconds: 250 -}); +const feb21 = new Temporal.PlainDateTime(2020, 2, 2, 0, 0, 0, 250, 250, 250); TemporalHelpers.assertDuration( - feb20.until(later, { largestUnit: "milliseconds" }), + feb20.until(feb21, { largestUnit: "milliseconds" }), 0, 0, 0, 0, 0, 0, 0, 86400250, 250, 250, "can return subseconds (millisecond precision)" ); TemporalHelpers.assertDuration( - feb20.until(later, { largestUnit: "microseconds" }), + feb20.until(feb21, { largestUnit: "microseconds" }), 0, 0, 0, 0, 0, 0, 0, 0, 86400250250, 250, "can return subseconds (microsecond precision)" ); TemporalHelpers.assertDuration( - feb20.until(later, { largestUnit: "nanoseconds" }), + feb20.until(feb21, { largestUnit: "nanoseconds" }), 0, 0, 0, 0, 0, 0, 0, 0, 0, 86400250250250, "can return subseconds (nanosecond precision)" ); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/units-changed.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/units-changed.js index 503836577e5c..01f270b1ec55 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/units-changed.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/units-changed.js @@ -32,13 +32,13 @@ TemporalHelpers.assertDuration( TemporalHelpers.assertDuration( feb20.until(feb21, { largestUnit: "hours" }), - 0, 0, 0, 0, 8784, 0, 0,0, 0, 0, + 0, 0, 0, 0, 8784, 0, 0, 0, 0, 0, "can return lower or higher units (hours)" ); TemporalHelpers.assertDuration( feb20.until(feb21, { largestUnit: "minutes" }), - 0, 0, 0, 0, 0, 527040, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 527040, 0, 0, 0, 0, "can return lower or higher units (minutes)" ); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/weeks-months-mutually-exclusive.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/weeks-months-mutually-exclusive.js index 7e27778ad79e..ee058a667ca3 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/weeks-months-mutually-exclusive.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/weeks-months-mutually-exclusive.js @@ -15,13 +15,13 @@ const laterDateTime = dt.add({ days: 42, hours: 3 }); TemporalHelpers.assertDuration( dt.until(laterDateTime, { largestUnit: "weeks" }), 0, 0, 6, 0, 3, 0, 0, 0, 0, 0, - "weeks and months mutually exclusive (1)" + "weeks and months mutually exclusive (prefer weeks)" ); TemporalHelpers.assertDuration( dt.until(laterDateTime, { largestUnit: "months" }), 0, 1, 0, 12, 3, 0, 0, 0, 0, 0, - "weeks and months mutually exclusive (2)" + "weeks and months mutually exclusive (prefer months)" ); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/year-zero.js index 84b18c94d79f..db629b52ecfa 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/until/year-zero.js @@ -9,14 +9,16 @@ features: [Temporal, arrow-function] ---*/ const invalidStrings = [ + "-000000-12-07", "-000000-12-07T03:24:30", - "-000000-12-07T03:24:30+01:00[UTC]" + "-000000-12-07T03:24:30+01:00", + "-000000-12-07T03:24:30+00:00[UTC]", ]; const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); invalidStrings.forEach((arg) => { assert.throws( RangeError, - () => { instance.until(arg); }, + () => instance.until(arg), "reject minus zero as extended year" ); }); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/with/argument-not-object.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/with/argument-not-object.js new file mode 100644 index 000000000000..8533e449f3c6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/with/argument-not-object.js @@ -0,0 +1,25 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.with +description: Non-object arguments throw. +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); +const args = [ + undefined, + null, + true, + "2020-01-12T10:20:30", + Symbol(), + 2020, + 2020n, +]; +for (const argument of args) { + assert.throws(TypeError, () => instance.with(argument), `Does not support ${typeof argument}`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/with/calendar-options.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/with/calendar-options.js new file mode 100644 index 000000000000..80537a2836b5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/with/calendar-options.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.with +description: The options argument is passed through to Calendar#dateFromFields as-is. +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const options = {}; +let calledDateFromFields = 0; +class Calendar extends Temporal.Calendar { + constructor() { + super("iso8601"); + } + dateFromFields(fields, optionsArg) { + ++calledDateFromFields; + assert.sameValue(optionsArg, options, "should pass options object through"); + return super.dateFromFields(fields, optionsArg); + } +}; +const calendar = new Calendar(); +const plaindatetime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, calendar); +const result = plaindatetime.with({ year: 2005 }, options); +TemporalHelpers.assertPlainDateTime(result, 2005, 5, "M05", 2, 12, 34, 56, 987, 654, 321); +assert.sameValue(calledDateFromFields, 1, "should have called overridden dateFromFields once"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/with/calendar-temporal-object-throws.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/with/calendar-temporal-object-throws.js new file mode 100644 index 000000000000..eddca2b8171a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/with/calendar-temporal-object-throws.js @@ -0,0 +1,36 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Throws if a Temporal object with a calendar is supplied +esid: sec-temporal.plaindatetime.prototype.with +features: [Temporal] +---*/ + +const datetime = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789); + +const values = [ + Temporal.PlainDate.from("2022-04-12"), + Temporal.PlainDateTime.from("2022-04-12T15:19:45"), + Temporal.PlainMonthDay.from("04-12"), + Temporal.PlainTime.from("15:19:45"), + Temporal.PlainYearMonth.from("2022-04"), + Temporal.ZonedDateTime.from("2022-04-12T15:19:45[UTC]"), +]; + +for (const value of values) { + Object.defineProperty(value, "calendar", { + get() { throw new Test262Error("should not get calendar property") } + }); + Object.defineProperty(value, "timeZone", { + get() { throw new Test262Error("should not get timeZone property") } + }); + assert.throws( + TypeError, + () => datetime.with(value), + "throws with temporal object" + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/with/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/with/options-wrong-type.js new file mode 100644 index 000000000000..6c4734a17357 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/with/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.with +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.PlainDateTime(2000, 5, 2); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.with({ day: 5 }, value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/with/order-of-operations.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/with/order-of-operations.js index 9246fbafc935..d296a81f0f07 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/with/order-of-operations.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/with/order-of-operations.js @@ -43,6 +43,12 @@ const expected = [ "get year", "get year.valueOf", "call year.valueOf", + "get options.overflow", + "get options.overflow.toString", + "call options.overflow.toString", + "get options.overflow", + "get options.overflow.toString", + "call options.overflow.toString", ]; const actual = []; const fields = { @@ -71,7 +77,13 @@ const argument = new Proxy(fields, { return key in target; }, }); -const result = instance.with(argument); +const options = { + get overflow() { + actual.push("get options.overflow"); + return TemporalHelpers.toPrimitiveObserver(actual, "constrain", "options.overflow"); + } +}; +const result = instance.with(argument, options); TemporalHelpers.assertPlainDateTime(result, 1, 1, "M01", 1, 1, 1, 1, 1, 1, 1); assert.sameValue(result.calendar.id, "iso8601", "calendar result"); assert.compareArray(actual, expected, "order of operations"); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withCalendar/argument-string.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withCalendar/argument-string.js new file mode 100644 index 000000000000..baaa841c06b4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withCalendar/argument-string.js @@ -0,0 +1,40 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.withcalendar +description: String argument, if it names a recognizable calendar, gets cast +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const calendar = { + toString() { return "something special"; } +}; +const dt = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789, calendar); +const result = dt.withCalendar("iso8601"); + +TemporalHelpers.assertPlainDateTime( + result, + 1976, 11, "M11", 18, 15, 23, 30, 123, 456, 789, + "'iso8601' is a recognizable calendar" +); + +const resultCalendar = result.calendar; + +assert.sameValue( + resultCalendar instanceof Temporal.Calendar, + true, + "underlying calendar is no longer a plain object" +); + +assert.sameValue(resultCalendar.toString(), "iso8601", "underlying calendar has changed"); + +assert.throws( + RangeError, + () => dt.withCalendar("this will fail"), + "unknown calendar throws" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withCalendar/basic.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withCalendar/basic.js new file mode 100644 index 000000000000..104211610c45 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withCalendar/basic.js @@ -0,0 +1,25 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.withcalendar +description: Non-throwing non-edge case +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const dt = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789); +const calendar = new Temporal.Calendar("iso8601"); + +const result = dt.withCalendar(calendar); + +TemporalHelpers.assertPlainDateTime( + result, + 1976, 11, "M11", 18, 15, 23, 30, 123, 456, 789, + "works" +); + +assert.sameValue(result.calendar, calendar, "underlying calendar is unchanged"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-number.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-number.js new file mode 100644 index 000000000000..2b80095d7569 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-number.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.withcalendar +description: A number is converted to a string, then to Temporal.Calendar +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789, { id: "replace-me" }); + +const arg = 19761118; + +const result = instance.withCalendar(arg); +assert.sameValue(result.calendar.id, "iso8601", "19761118 is a valid ISO string for Calendar"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.withCalendar(arg), + `Number ${arg} does not convert to a valid ISO string for Calendar` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-string-leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-string-leap-second.js new file mode 100644 index 000000000000..bc8d06317a22 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-string-leap-second.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.withcalendar +description: Leap second is a valid ISO string for Calendar +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789, { id: "replace-me" }); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.withCalendar(arg); +assert.sameValue( + result1.calendar.id, + "iso8601", + "leap second is a valid ISO string for Calendar" +); + +arg = { calendar: "2016-12-31T23:59:60" }; +const result2 = instance.withCalendar(arg); +assert.sameValue( + result2.calendar.id, + "iso8601", + "leap second is a valid ISO string for Calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-temporal-object.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-temporal-object.js index 536ff0ccee26..1869f32a6247 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-temporal-object.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-temporal-object.js @@ -18,7 +18,7 @@ features: [Temporal] TemporalHelpers.checkToTemporalCalendarFastPath((temporalObject, calendar) => { const plainDateTime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); const result = plainDateTime.withCalendar(temporalObject); - assert.sameValue(result.calendar, calendar, 'Temporal object coerced to calendar'); + assert.sameValue(result.calendar, calendar, "Temporal object coerced to calendar"); }); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-wrong-type.js new file mode 100644 index 000000000000..5a349b3f07b6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-wrong-type.js @@ -0,0 +1,35 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.withcalendar +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for Calendar +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 30, 123, 456, 789, { id: "replace-me" }); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.withCalendar(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.withCalendar(arg), `${description} is not a valid object and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-number.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-number.js new file mode 100644 index 000000000000..128f71bc2cae --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-number.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.withplaindate +description: A number is converted to a string, then to Temporal.PlainDate +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); + +const arg = 19761118; + +const result = instance.withPlainDate(arg); +TemporalHelpers.assertPlainDateTime(result, 1976, 11, "M11", 18, 12, 34, 56, 987, 654, 321, "19761118 is a valid ISO string for PlainDate"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.withPlainDate(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-object-insuffcient-data.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-object-insufficient-data.js similarity index 100% rename from js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-object-insuffcient-data.js rename to js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-object-insufficient-data.js diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-noniso.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-noniso.js new file mode 100644 index 000000000000..31ee2b3cfb65 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-noniso.js @@ -0,0 +1,40 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.withplaindate +description: PlainDate calendar is preserved with ISO PDT +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const cal = { + id: 'thisisnotiso', + era() { return undefined; }, + eraYear() { return undefined; }, + toString() { return "this is a string"; }, + year() { return 2008; }, + month() { return 9; }, + monthCode() { return "M09"; }, + day() { return 6; } +}; +const pdt = new Temporal.PlainDateTime(1995, 12, 7, 3, 24, 30, 0, 0, 0); +assert.sameValue(pdt.calendar.toString(), "iso8601", "PlainDateTime with ISO calendar"); +const pd = new Temporal.PlainDate(2010, 11, 12, cal); +const shifted = pdt.withPlainDate(pd); + +TemporalHelpers.assertPlainDateTime( + shifted, + 2008, 9, "M09", 6, 3, 24, 30, 0, 0, 0, + "calendar is changed if receiver has ISO calendar (1)" + // Testing of era and eraYear should only be coded under intl402 +); + +assert.sameValue( + shifted.calendar, + cal, + "calendar is changed if receiver has ISO calendar (2)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-same-id.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-same-id.js new file mode 100644 index 000000000000..7325810e7ff4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-same-id.js @@ -0,0 +1,42 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.withplaindate +description: PlainDate calendar is preserved when both calendars have the same id +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const cal1 = { + toString() { return "this is a string"; }, +}; +const cal2 = { + id: 'thisisnotiso', + era() { return undefined; }, + eraYear() { return undefined; }, + toString() { return "this is a string"; }, + year() { return 2008; }, + month() { return 9; }, + monthCode() { return "M09"; }, + day() { return 6; } +}; +const pdt = new Temporal.PlainDateTime(1995, 12, 7, 3, 24, 30, 0, 0, 0, cal1); +const pd = new Temporal.PlainDate(2010, 11, 12, cal2); +const shifted = pdt.withPlainDate(pd); + +TemporalHelpers.assertPlainDateTime( + shifted, + 2008, 9, "M09", 6, 3, 24, 30, 0, 0, 0, + "calendar is changed with same id (1)" + // Testing of era and eraYear should only be coded under intl402 +); + +assert.sameValue( + shifted.calendar, + cal2, + "calendar is changed with same id (2)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-same-object.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-same-object.js new file mode 100644 index 000000000000..ac93a19ebf3f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-same-object.js @@ -0,0 +1,44 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.withplaindate +description: PlainDate calendar is preserved when both calendars are the same object +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +let calls = 0; +const cal = { + id: 'thisisnotiso', + era() { return undefined; }, + eraYear() { return undefined; }, + toString() { + ++calls; + return "this is a string"; + }, + year() { return 2008; }, + month() { return 9; }, + monthCode() { return "M09"; }, + day() { return 6; } +}; +const pdt = new Temporal.PlainDateTime(1995, 12, 7, 3, 24, 30, 0, 0, 0, cal); +const pd = new Temporal.PlainDate(2010, 11, 12, cal); +const shifted = pdt.withPlainDate(pd); + +TemporalHelpers.assertPlainDateTime( + shifted, + 2008, 9, "M09", 6, 3, 24, 30, 0, 0, 0, + "calendar is unchanged with same calendars (1)" + // Testing of era and eraYear should only be coded under intl402 +); + +assert.sameValue( + shifted.calendar, + cal, + "calendar is unchanged with same calendars (2)" +); +assert.sameValue(calls, 0, "should not have called cal.toString()"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar.js new file mode 100644 index 000000000000..5c28b4f9efe1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar.js @@ -0,0 +1,40 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.withplaindate +description: Original PDT calendar is preserved with ISO PlainDate +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const cal = { + id: 'thisisnotiso', + era() { return undefined; }, + eraYear() { return undefined; }, + toString() { return "this is a string"; }, + year() { return 2008; }, + month() { return 9; }, + monthCode() { return "M09"; }, + day() { return 6; } +}; +const pdt = new Temporal.PlainDateTime(1995, 12, 7, 3, 24, 30, 0, 0, 0, cal); +const pd = new Temporal.PlainDate(2010, 11, 12); +assert.sameValue(pd.calendar.toString(), "iso8601", "PlainDate with ISO calendar"); +const shifted = pdt.withPlainDate(pd); + +TemporalHelpers.assertPlainDateTime( + shifted, + 2008, 9, "M09", 6, 3, 24, 30, 0, 0, 0, + "calendar is unchanged if input has ISO calendar (1)" + // Testing of era and eraYear should only be coded under intl402 +); + +assert.sameValue( + shifted.calendar, + cal, + "calendar is unchanged if input has ISO calendar (2)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..fdaafa35c551 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.withplaindate +description: Leap second is a valid ISO string for a calendar in a property bag +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.withPlainDate(arg); +TemporalHelpers.assertPlainDateTime( + result1, + 1976, 11, "M11", 18, 12, 34, 56, 987, 654, 321, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.withPlainDate(arg); +TemporalHelpers.assertPlainDateTime( + result2, + 1976, 11, "M11", 18, 12, 34, 56, 987, 654, 321, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..9560b0c61dc3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-propertybag-calendar-number.js @@ -0,0 +1,45 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.withplaindate +description: A number as calendar in a property bag is converted to a string, then to a calendar +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.withPlainDate(arg); +TemporalHelpers.assertPlainDateTime(result1, 1976, 11, "M11", 18, 12, 34, 56, 987, 654, 321, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.withPlainDate(arg); +TemporalHelpers.assertPlainDateTime(result2, 1976, 11, "M11", 18, 12, 34, 56, 987, 654, 321, "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + assert.throws( + RangeError, + () => instance.withPlainDate(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.withPlainDate(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..af821150f864 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.withplaindate +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.withPlainDate(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.withPlainDate(arg), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.withPlainDate(arg), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.withPlainDate(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.withPlainDate(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..e063c06fb348 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.withplaindate +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.withPlainDate(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-string-iso-calendar.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-string-iso-calendar.js index c1d8b4f70c29..5276baa85dd5 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-string-iso-calendar.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-string-iso-calendar.js @@ -4,15 +4,15 @@ /*--- esid: sec-temporal.plaindatetime.prototype.withplaindate -description: New calendar is preserved if original PDT has ISO calendar +description: Original PDT calendar is preserved with ISO string features: [Temporal] includes: [temporalHelpers.js] ---*/ const cal = { - id: 'thisisnotiso', - era() { return "the era"; }, - eraYear() { return 1909; }, + id: "thisisnotiso", + era() { return undefined; }, + eraYear() { return undefined; }, toString() { return "this is a string"; }, year() { return 2008; }, month() { return 9; }, @@ -25,9 +25,8 @@ const shifted = dt.withPlainDate("2010-11-12"); TemporalHelpers.assertPlainDateTime( shifted, 2008, 9, "M09", 6, 3, 24, 30, 0, 0, 0, - "calendar is unchanged if input has ISO calendar (1)", - "the era", - 1909 + "calendar is unchanged if input has ISO calendar (1)" + // Testing of era and eraYear should only be coded under intl402 ); assert.sameValue( diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-wrong-type.js new file mode 100644 index 000000000000..91a904ff39a1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/argument-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.withplaindate +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.withPlainDate(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.withPlainDate(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/leap-second.js new file mode 100644 index 000000000000..7bdac2c5291b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/leap-second.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.withplaindate +description: Leap second is a valid ISO string for PlainDate +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.withPlainDate(arg); +TemporalHelpers.assertPlainDateTime( + result1, + 2016, 12, "M12", 31, 12, 34, 56, 987, 654, 321, + "leap second is a valid ISO string for PlainDate" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.withPlainDate(arg); +TemporalHelpers.assertPlainDateTime( + result2, + 2016, 12, "M12", 31, 12, 34, 56, 987, 654, 321, + "second: 60 is ignored in property bag for PlainDate" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/non-compatible-calendars-throw.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/non-compatible-calendars-throw.js index 8ec7e1477df6..b29b5c83486e 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/non-compatible-calendars-throw.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/non-compatible-calendars-throw.js @@ -9,14 +9,14 @@ features: [Temporal] ---*/ const cal = { - id: 'foo', + id: "foo", toString() { return "this is a string"; }, }; const dt = new Temporal.PlainDateTime(1995, 12, 7, 3, 24, 30, 0, 0, 0, cal); const anotherCal = { - id: 'bar', + id: "bar", toString() { return "this is another string"; }, }; diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/year-zero.js index b3f967db678e..4bc2b6e2eb01 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainDate/year-zero.js @@ -8,13 +8,19 @@ description: Negative zero, as an extended year, is rejected features: [Temporal, arrow-function] ---*/ -const arg = "-000000-10-31"; +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); - -assert.throws( +invalidStrings.forEach((arg) => { + assert.throws( RangeError, - () => { instance.withPlainDate(arg); }, + () => instance.withPlainDate(arg), "reject minus zero as extended year" -); + ); +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainTime/argument-number.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainTime/argument-number.js new file mode 100644 index 000000000000..a22a6ef3aeb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainTime/argument-number.js @@ -0,0 +1,34 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.withplaintime +description: A number is converted to a string, then to Temporal.PlainTime +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDateTime(2000, 5, 2); + +const arg = 123456.987654321; + +const result = instance.withPlainTime(arg); +TemporalHelpers.assertPlainDateTime(result, 2000, 5, "M05", 2, 12, 34, 56, 987, 654, 321, "123456.987654321 is a valid ISO string for PlainTime"); + +const numbers = [ + 1, + -123456.987654321, + 1234567, + 123456.9876543219, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.withPlainTime(arg), + `Number ${arg} does not convert to a valid ISO string for PlainTime` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainTime/argument-string-time-designator-required-for-disambiguation.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainTime/argument-string-time-designator-required-for-disambiguation.js index e5b6dbad793e..653cff362f2e 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainTime/argument-string-time-designator-required-for-disambiguation.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainTime/argument-string-time-designator-required-for-disambiguation.js @@ -33,7 +33,7 @@ ambiguousStrings.forEach((string) => { assert.throws( RangeError, () => instance.withPlainTime(arg), - 'space is not accepted as a substitute for T prefix' + "space is not accepted as a substitute for T prefix" ); }); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainTime/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainTime/argument-wrong-type.js new file mode 100644 index 000000000000..57cf7bd0be6f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainTime/argument-wrong-type.js @@ -0,0 +1,38 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.withplaintime +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainTime +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.withPlainTime(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainTime, "Temporal.PlainTime, object"], + [Temporal.PlainTime.prototype, "Temporal.PlainTime.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.withPlainTime(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainTime/leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainTime/leap-second.js new file mode 100644 index 000000000000..27f3f8214bf1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainTime/leap-second.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.withplaintime +description: Leap second is a valid ISO string for PlainTime +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.withPlainTime(arg); +TemporalHelpers.assertPlainDateTime( + result1, + 2000, 5, "M05", 2, 23, 59, 59, 0, 0, 0, + "leap second is a valid ISO string for PlainTime" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.withPlainTime(arg); +TemporalHelpers.assertPlainDateTime( + result2, + 2000, 5, "M05", 2, 23, 59, 59, 0, 0, 0, + "second: 60 is ignored in property bag for PlainTime" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainTime/plaintime-propertybag-no-time-units.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainTime/plaintime-propertybag-no-time-units.js index 8ef6e565de82..d5fb6d357d91 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainTime/plaintime-propertybag-no-time-units.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainTime/plaintime-propertybag-no-time-units.js @@ -12,7 +12,7 @@ features: [Temporal] const instance = new Temporal.PlainDateTime(2000, 1, 1, 12, 30, 45, 123, 456, 789); const props = {}; -assert.throws(TypeError, () => instance.withPlainTime(props), "TypeError if at least one property is not present"); +assert.throws(TypeError, () => instance.withPlainTime(props), "TypeError if no properties are present"); props.minute = 30; const result = instance.withPlainTime(props); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainTime/year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainTime/year-zero.js index 15f82475e1df..afcb81e7ab4f 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainTime/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/prototype/withPlainTime/year-zero.js @@ -9,8 +9,9 @@ features: [Temporal, arrow-function] ---*/ const invalidStrings = [ - '-000000-12-07T03:24:30', - '-000000-12-07T03:24:30+01:00[UTC]' + "-000000-12-07T03:24:30", + "-000000-12-07T03:24:30+01:00", + "-000000-12-07T03:24:30+00:00[UTC]", ]; const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); invalidStrings.forEach((arg) => { diff --git a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/shell.js b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainDateTime/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainDateTime/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/calendar-number.js b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/calendar-number.js new file mode 100644 index 000000000000..76a1ee90fc1c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/calendar-number.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday +description: A number is converted to a string, then to Temporal.Calendar +features: [Temporal] +---*/ + +const arg = 19761118; + +const result = new Temporal.PlainMonthDay(12, 15, arg, 1972); +assert.sameValue(result.calendar.id, "iso8601", "19761118 is a valid ISO string for Calendar"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => new Temporal.PlainMonthDay(12, 15, arg, 1972), + `Number ${arg} does not convert to a valid ISO string for Calendar` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/calendar-wrong-type.js new file mode 100644 index 000000000000..4373ae5018a5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/calendar-wrong-type.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for Calendar +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => new Temporal.PlainMonthDay(12, 15, arg, 1972), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => new Temporal.PlainMonthDay(12, 15, arg, 1972), `${description} is not a valid object and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/from/argument-number.js b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/from/argument-number.js new file mode 100644 index 000000000000..7b75e17f70ac --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/from/argument-number.js @@ -0,0 +1,31 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday.from +description: A number is converted to a string, then to Temporal.PlainMonthDay +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const arg = 1118; + +const result = Temporal.PlainMonthDay.from(arg); +TemporalHelpers.assertPlainMonthDay(result, "M11", 18, "1118 is a valid ISO string for PlainMonthDay"); + +const numbers = [ + 1, + -1118, + 12345, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => Temporal.PlainMonthDay.from(arg), + `Number ${arg} does not convert to a valid ISO string for PlainMonthDay` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/from/argument-plainmonthday.js b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/from/argument-plainmonthday.js new file mode 100644 index 000000000000..0e55a080c963 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/from/argument-plainmonthday.js @@ -0,0 +1,28 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday.from +description: A PlainMonthDay object is copied, not returned directly +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const orig = new Temporal.PlainMonthDay(5, 2, undefined, 2000); +const result = Temporal.PlainMonthDay.from(orig); + +TemporalHelpers.assertPlainMonthDay( + result, + "M05", 2, + "PlainMonthDay is copied", + /* isoYear = */ 2000 +); + +assert.notSameValue( + result, + orig, + "When a PlainMonthDay is given, the returned value is not the original PlainMonthDay" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..ea40edc8073c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday.from +description: Leap second is a valid ISO string for a calendar in a property bag +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = "2016-12-31T23:59:60"; + +let arg = { monthCode: "M11", day: 18, calendar }; +const result1 = Temporal.PlainMonthDay.from(arg); +TemporalHelpers.assertPlainMonthDay( + result1, + "M11", 18, + "leap second is a valid ISO string for calendar" +); + +arg = { monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = Temporal.PlainMonthDay.from(arg); +TemporalHelpers.assertPlainMonthDay( + result2, + "M11", 18, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..8b478d1e18cc --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-number.js @@ -0,0 +1,43 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday.from +description: A number as calendar in a property bag is converted to a string, then to a calendar +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = 19970327; + +let arg = { monthCode: "M11", day: 18, calendar }; +const result1 = Temporal.PlainMonthDay.from(arg); +TemporalHelpers.assertPlainMonthDay(result1, "M11", 18, "19970327 is a valid ISO string for calendar"); + +arg = { monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = Temporal.PlainMonthDay.from(arg); +TemporalHelpers.assertPlainMonthDay(result2, "M11", 18, "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { monthCode: "M11", day: 18, calendar }; + assert.throws( + RangeError, + () => Temporal.PlainMonthDay.from(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { monthCode: "M11", day: 18, calendar: { calendar } }; + assert.throws( + RangeError, + () => Temporal.PlainMonthDay.from(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..19578693a9ff --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,47 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday.from +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => Temporal.PlainMonthDay.from(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => Temporal.PlainMonthDay.from(arg), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => Temporal.PlainMonthDay.from(arg), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => Temporal.PlainMonthDay.from(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => Temporal.PlainMonthDay.from(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..f527c960ca90 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/from/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday.from +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; + +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => Temporal.PlainMonthDay.from(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/from/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/from/argument-wrong-type.js new file mode 100644 index 000000000000..8d79118dffe6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/from/argument-wrong-type.js @@ -0,0 +1,37 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday.from +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainMonthDay +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => Temporal.PlainMonthDay.from(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainMonthDay, "Temporal.PlainMonthDay, object"], + [Temporal.PlainMonthDay.prototype, "Temporal.PlainMonthDay.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => Temporal.PlainMonthDay.from(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/from/leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/from/leap-second.js new file mode 100644 index 000000000000..7cba2b9fb7a8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/from/leap-second.js @@ -0,0 +1,44 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday.from +description: Leap second is a valid ISO string for PlainMonthDay +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +let arg = "2016-12-31T23:59:60"; + +const result1 = Temporal.PlainMonthDay.from(arg); +TemporalHelpers.assertPlainMonthDay( + result1, + "M12", 31, + "leap second is a valid ISO string for PlainMonthDay" +); + +const result2 = Temporal.PlainMonthDay.from(arg, { overflow: "reject" }); +TemporalHelpers.assertPlainMonthDay( + result2, + "M12", 31, + "leap second is a valid ISO string for PlainMonthDay" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; + +const result3 = Temporal.PlainMonthDay.from(arg); +TemporalHelpers.assertPlainMonthDay( + result3, + "M12", 31, + "second: 60 is ignored in property bag for PlainMonthDay" +); + +const result4 = Temporal.PlainMonthDay.from(arg, { overflow: "reject" }); +TemporalHelpers.assertPlainMonthDay( + result4, + "M12", 31, + "second: 60 is ignored in property bag for PlainMonthDay even with overflow: reject" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/from/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/from/options-wrong-type.js new file mode 100644 index 000000000000..2c20bfb7c5e6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/from/options-wrong-type.js @@ -0,0 +1,25 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday.from +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +for (const value of badOptions) { + assert.throws(TypeError, () => Temporal.PlainMonthDay.from({ monthCode: "M12", day: 15 }, value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/from/year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/from/year-zero.js index 5419f8351efb..b81504fedb0d 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/from/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/from/year-zero.js @@ -9,15 +9,16 @@ features: [Temporal, arrow-function] ---*/ const invalidStrings = [ - "-000000-08", - "-000000-08-24", - "-000000-08-24T15:43:27", - "-000000-08-24T15:43:27+01:00[UTC]" + "-000000-08-24", + "-000000-08-24T15:43:27", + "-000000-08-24T15:43:27+01:00", + "-000000-08-24T15:43:27+00:00[UTC]", ]; + invalidStrings.forEach((arg) => { assert.throws( RangeError, - () => { Temporal.PlainMonthDay.from(arg); }, + () => Temporal.PlainMonthDay.from(arg), "reject minus zero as extended year" ); }); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-number.js b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-number.js new file mode 100644 index 000000000000..ca26659b19fe --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-number.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday.prototype.equals +description: A number is converted to a string, then to Temporal.PlainMonthDay +features: [Temporal] +---*/ + +const instance = new Temporal.PlainMonthDay(11, 18); + +const arg = 1118; + +const result = instance.equals(arg); +assert.sameValue(result, true, "1118 is a valid ISO string for PlainMonthDay"); + +const numbers = [ + 1, + -1118, + 12345, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.equals(arg), + `Number ${arg} does not convert to a valid ISO string for PlainMonthDay` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..de38b7d5e5f3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,31 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday.prototype.equals +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const instance = new Temporal.PlainMonthDay(11, 18); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { monthCode: "M11", day: 18, calendar }; +const result1 = instance.equals(arg); +assert.sameValue( + result1, + true, + "leap second is a valid ISO string for calendar" +); + +arg = { monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.equals(arg); +assert.sameValue( + result2, + true, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..bc660f6e16be --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-number.js @@ -0,0 +1,44 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday.prototype.equals +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const instance = new Temporal.PlainMonthDay(11, 18); + +const calendar = 19970327; + +let arg = { monthCode: "M11", day: 18, calendar }; +const result1 = instance.equals(arg); +assert.sameValue(result1, true, "19970327 is a valid ISO string for calendar"); + +arg = { monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.equals(arg); +assert.sameValue(result2, true, "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { monthCode: "M11", day: 18, calendar }; + assert.throws( + RangeError, + () => instance.equals(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { monthCode: "M11", day: 18, calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.equals(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..b52e0ff9b27c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday.prototype.equals +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.PlainMonthDay(5, 2); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.equals(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.equals(arg), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.equals(arg), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.equals(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.equals(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..0502fb30c7e5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday.prototype.equals +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.PlainMonthDay(5, 2); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.equals(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-wrong-type.js index 303f66117cfe..266be177519d 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-wrong-type.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/prototype/equals/argument-wrong-type.js @@ -1,23 +1,39 @@ // |reftest| skip -- Temporal is not supported -// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// Copyright (C) 2022 Igalia, S.L. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. /*--- esid: sec-temporal.plainmonthday.prototype.equals -description: Appropriate error thrown when argument cannot be converted to a valid string -features: [Symbol, Temporal] +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainMonthDay +features: [BigInt, Symbol, Temporal] ---*/ -const instance = Temporal.PlainMonthDay.from({ month: 5, day: 2 }); +const instance = new Temporal.PlainMonthDay(5, 2); -assert.throws(RangeError, () => instance.equals(undefined), "undefined"); -assert.throws(RangeError, () => instance.equals(null), "null"); -assert.throws(RangeError, () => instance.equals(true), "true"); -assert.throws(RangeError, () => instance.equals(""), "empty string"); -assert.throws(TypeError, () => instance.equals(Symbol()), "symbol"); -assert.throws(RangeError, () => instance.equals(1), "1"); -assert.throws(TypeError, () => instance.equals({}), "plain object"); -assert.throws(TypeError, () => instance.equals(Temporal.PlainMonthDay), "Temporal.PlainMonthDay"); -assert.throws(TypeError, () => instance.equals(Temporal.PlainMonthDay.prototype), "Temporal.PlainMonthDay.prototype"); +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.equals(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainMonthDay, "Temporal.PlainMonthDay, object"], + [Temporal.PlainMonthDay.prototype, "Temporal.PlainMonthDay.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.equals(arg), `${description} is not a valid property bag and does not convert to a string`); +} reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/prototype/equals/leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/prototype/equals/leap-second.js new file mode 100644 index 000000000000..c8ea2228c0b9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/prototype/equals/leap-second.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday.prototype.equals +description: Leap second is a valid ISO string for PlainMonthDay +features: [Temporal] +---*/ + +const instance = new Temporal.PlainMonthDay(12, 31); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.equals(arg); +assert.sameValue( + result1, + true, + "leap second is a valid ISO string for PlainMonthDay" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.equals(arg); +assert.sameValue( + result2, + true, + "second: 60 is ignored in property bag for PlainMonthDay" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/prototype/equals/year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/prototype/equals/year-zero.js index 26e1eb8de7c4..e3bb2db4e477 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/prototype/equals/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/prototype/equals/year-zero.js @@ -9,10 +9,10 @@ features: [Temporal, arrow-function] ---*/ const invalidStrings = [ - "-000000-08", - "-000000-08-24", - "-000000-08-24T15:43:27", - "-000000-08-24T15:43:27+01:00[UTC]" + "-000000-08-24", + "-000000-08-24T15:43:27", + "-000000-08-24T15:43:27+01:00", + "-000000-08-24T15:43:27+00:00[UTC]", ]; const instance = new Temporal.PlainMonthDay(5, 2); invalidStrings.forEach((arg) => { diff --git a/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/prototype/toString/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/prototype/toString/options-wrong-type.js new file mode 100644 index 000000000000..94ca29202d52 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/prototype/toString/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday.prototype.tostring +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.PlainMonthDay(5, 2); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.toString(value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/prototype/with/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/prototype/with/options-wrong-type.js new file mode 100644 index 000000000000..0f7585271113 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/prototype/with/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday.prototype.with +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.PlainMonthDay(5, 2); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.with({ day: 5 }, value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/shell.js b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainMonthDay/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/compare/argument-number.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/compare/argument-number.js new file mode 100644 index 000000000000..0cf5db1ea02c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/compare/argument-number.js @@ -0,0 +1,38 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.compare +description: A number is converted to a string, then to Temporal.PlainTime +features: [Temporal] +---*/ + +const arg = 123456.987654321; + +const result1 = Temporal.PlainTime.compare(arg, new Temporal.PlainTime(12, 34, 56, 987, 654, 321)); +assert.sameValue(result1, 0, "123456.987654321 is a valid ISO string for PlainTime (first argument)"); +const result2 = Temporal.PlainTime.compare(new Temporal.PlainTime(12, 34, 56, 987, 654, 321), arg); +assert.sameValue(result2, 0, "123456.987654321 is a valid ISO string for PlainTime (second argument)"); + +const numbers = [ + 1, + -123456.987654321, + 1234567, + 123456.9876543219, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => Temporal.PlainTime.compare(arg, new Temporal.PlainTime(12, 34, 56, 987, 654, 321)), + `Number ${arg} does not convert to a valid ISO string for PlainTime (first argument)` + ); + assert.throws( + RangeError, + () => Temporal.PlainTime.compare(new Temporal.PlainTime(12, 34, 56, 987, 654, 321), arg), + `Number ${arg} does not convert to a valid ISO string for PlainTime (second argument)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/compare/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/compare/argument-wrong-type.js new file mode 100644 index 000000000000..016ed3972d9a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/compare/argument-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.compare +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainTime +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => Temporal.PlainTime.compare(arg, new Temporal.PlainTime(12, 34, 56, 987, 654, 321)), `${description} does not convert to a valid ISO string (first argument)`); + assert.throws(RangeError, () => Temporal.PlainTime.compare(new Temporal.PlainTime(12, 34, 56, 987, 654, 321), arg), `${description} does not convert to a valid ISO string (second argument)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainTime, "Temporal.PlainTime, object"], + [Temporal.PlainTime.prototype, "Temporal.PlainTime.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => Temporal.PlainTime.compare(arg, new Temporal.PlainTime(12, 34, 56, 987, 654, 321)), `${description} is not a valid property bag and does not convert to a string (first argument)`); + assert.throws(TypeError, () => Temporal.PlainTime.compare(new Temporal.PlainTime(12, 34, 56, 987, 654, 321), arg), `${description} is not a valid property bag and does not convert to a string (second argument)`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/compare/leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/compare/leap-second.js new file mode 100644 index 000000000000..9a7ad7be2a28 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/compare/leap-second.js @@ -0,0 +1,23 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.compare +description: Leap second is a valid ISO string for PlainTime +features: [Temporal] +---*/ + +let arg = "2016-12-31T23:59:60"; +const result1 = Temporal.PlainTime.compare(arg, new Temporal.PlainTime(23, 59, 59)); +assert.sameValue(result1, 0, "leap second is a valid ISO string for PlainTime (first argument)"); +const result2 = Temporal.PlainTime.compare(new Temporal.PlainTime(23, 59, 59), arg); +assert.sameValue(result2, 0, "leap second is a valid ISO string for PlainTime (first argument)"); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result3 = Temporal.PlainTime.compare(arg, new Temporal.PlainTime(23, 59, 59)); +assert.sameValue(result3, 0, "second: 60 is ignored in property bag for PlainTime (first argument)"); +const result4 = Temporal.PlainTime.compare(new Temporal.PlainTime(23, 59, 59), arg); +assert.sameValue(result4, 0, "second: 60 is ignored in property bag for PlainTime (second argument)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/compare/plaintime-propertybag-no-time-units.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/compare/plaintime-propertybag-no-time-units.js index 206d860ebf15..ae9cc0df658b 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/compare/plaintime-propertybag-no-time-units.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/compare/plaintime-propertybag-no-time-units.js @@ -9,7 +9,7 @@ features: [Temporal] ---*/ const props = {}; -assert.throws(TypeError, () => Temporal.PlainTime.compare(props, new Temporal.PlainTime(0, 30)), "TypeError if at least one property is not present"); +assert.throws(TypeError, () => Temporal.PlainTime.compare(props, new Temporal.PlainTime(0, 30)), "TypeError if no properties are present"); props.minute = 30; const result = Temporal.PlainTime.compare(props, new Temporal.PlainTime(0, 30)); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/compare/year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/compare/year-zero.js index 8610156170fb..bbc04351af86 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/compare/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/compare/year-zero.js @@ -9,18 +9,24 @@ features: [Temporal] ---*/ const time = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); -const bad = "-000000-12-07T03:24:30"; +const invalidStrings = [ + "-000000-12-07T03:24:30", + "-000000-12-07T03:24:30+01:00", + "-000000-12-07T03:24:30+00:00[UTC]", +]; -assert.throws( - RangeError, - () => Temporal.PlainTime.compare(bad, time), - "Cannot use minus zero as extended year (first argument)" -); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => Temporal.PlainTime.compare(arg, time), + "Cannot use minus zero as extended year (first argument)" + ); -assert.throws( - RangeError, - () => Temporal.PlainTime.compare(time, bad), - "Cannot use minus zero as extended year (second argument)" -); + assert.throws( + RangeError, + () => Temporal.PlainTime.compare(time, arg), + "Cannot use minus zero as extended year (second argument)" + ); +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/from/argument-number.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/from/argument-number.js index 58fb40657151..35fc5780b5a8 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/from/argument-number.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/from/argument-number.js @@ -4,12 +4,29 @@ /*--- esid: sec-temporal.plaintime.from -description: Number argument is converted to string -includes: [compareArray.js, temporalHelpers.js] +description: A number is converted to a string, then to Temporal.PlainTime +includes: [temporalHelpers.js] features: [Temporal] ---*/ -const result = Temporal.PlainTime.from(1523); -TemporalHelpers.assertPlainTime(result, 15, 23, 0, 0, 0, 0); +const arg = 123456.987654321; + +const result = Temporal.PlainTime.from(arg); +TemporalHelpers.assertPlainTime(result, 12, 34, 56, 987, 654, 321, "123456.987654321 is a valid ISO string for PlainTime"); + +const numbers = [ + 1, + -123456.987654321, + 1234567, + 123456.9876543219, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => Temporal.PlainTime.from(arg), + `Number ${arg} does not convert to a valid ISO string for PlainTime` + ); +} reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/from/argument-plaintime.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/from/argument-plaintime.js index 00ceb306f5be..65b4b4079262 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/from/argument-plaintime.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/from/argument-plaintime.js @@ -5,13 +5,23 @@ /*--- esid: sec-temporal.plaintime.from description: A PlainTime object is copied, not returned directly -includes: [compareArray.js, temporalHelpers.js] +includes: [temporalHelpers.js] features: [Temporal] ---*/ -const plainTime = Temporal.PlainTime.from("11:42:00"); -const result = Temporal.PlainTime.from(plainTime); -assert.notSameValue(result, plainTime); -TemporalHelpers.assertPlainTime(result, 11, 42, 0, 0, 0, 0); +const orig = new Temporal.PlainTime(11, 42, 0, 0, 0, 0); +const result = Temporal.PlainTime.from(orig); + +TemporalHelpers.assertPlainTime( + result, + 11, 42, 0, 0, 0, 0, + "PlainTime is copied" +); + +assert.notSameValue( + result, + orig, + "When a PlainTime is given, the returned value is not the original PlainTime" +); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/from/argument-string-time-designator-required-for-disambiguation.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/from/argument-string-time-designator-required-for-disambiguation.js index 8e84fb980a23..3b7602fc59cf 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/from/argument-string-time-designator-required-for-disambiguation.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/from/argument-string-time-designator-required-for-disambiguation.js @@ -31,7 +31,7 @@ ambiguousStrings.forEach((string) => { assert.throws( RangeError, () => Temporal.PlainTime.from(arg), - 'space is not accepted as a substitute for T prefix' + "space is not accepted as a substitute for T prefix" ); }); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/from/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/from/argument-wrong-type.js new file mode 100644 index 000000000000..7878ec5759be --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/from/argument-wrong-type.js @@ -0,0 +1,37 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.from +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainTime +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => Temporal.PlainTime.from(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainTime, "Temporal.PlainTime, object"], + [Temporal.PlainTime.prototype, "Temporal.PlainTime.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => Temporal.PlainTime.from(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/from/leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/from/leap-second.js new file mode 100644 index 000000000000..3155e51d5534 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/from/leap-second.js @@ -0,0 +1,43 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.from +description: Leap second is a valid ISO string for PlainTime +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +let arg = "2016-12-31T23:59:60"; + +const result1 = Temporal.PlainTime.from(arg); +TemporalHelpers.assertPlainTime( + result1, + 23, 59, 59, 0, 0, 0, + "leap second is a valid ISO string for PlainTime" +); + +const result2 = Temporal.PlainTime.from(arg, { overflow: "reject" }); +TemporalHelpers.assertPlainTime( + result2, + 23, 59, 59, 0, 0, 0, + "leap second is a valid ISO string for PlainTime" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; + +const result3 = Temporal.PlainTime.from(arg); +TemporalHelpers.assertPlainTime( + result3, + 23, 59, 59, 0, 0, 0, + "second: 60 is ignored in property bag for PlainTime" +); + +assert.throws( + RangeError, + () => Temporal.PlainTime.from(arg, { overflow: "reject" }), + "second: 60 is rejected in property bag for PlainTime with overflow: reject" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/from/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/from/options-wrong-type.js new file mode 100644 index 000000000000..c233755fb5e8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/from/options-wrong-type.js @@ -0,0 +1,25 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.from +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +for (const value of badOptions) { + assert.throws(TypeError, () => Temporal.PlainTime.from({ hour: 12, minute: 34 }, value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/from/year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/from/year-zero.js index 1bd2c09ff889..d13a40facd79 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/from/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/from/year-zero.js @@ -9,13 +9,15 @@ features: [Temporal, arrow-function] ---*/ const invalidStrings = [ - '-000000-12-07T03:24:30', - '-000000-12-07T03:24:30+01:00[UTC]' + "-000000-12-07T03:24:30", + "-000000-12-07T03:24:30+01:00", + "-000000-12-07T03:24:30+00:00[UTC]", ]; + invalidStrings.forEach((arg) => { assert.throws( RangeError, - () => { Temporal.PlainTime.from(arg); }, + () => Temporal.PlainTime.from(arg), "reject minus zero as extended year" ); }); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/equals/argument-number.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/equals/argument-number.js new file mode 100644 index 000000000000..6e4f1cb2e7ec --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/equals/argument-number.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.equals +description: A number is converted to a string, then to Temporal.PlainTime +features: [Temporal] +---*/ + +const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); + +const arg = 123456.987654321; + +const result = instance.equals(arg); +assert.sameValue(result, true, "123456.987654321 is a valid ISO string for PlainTime"); + +const numbers = [ + 1, + -123456.987654321, + 1234567, + 123456.9876543219, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.equals(arg), + `Number ${arg} does not convert to a valid ISO string for PlainTime` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/equals/argument-string-time-designator-required-for-disambiguation.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/equals/argument-string-time-designator-required-for-disambiguation.js index 332a2908dd2b..2e765696894f 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/equals/argument-string-time-designator-required-for-disambiguation.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/equals/argument-string-time-designator-required-for-disambiguation.js @@ -33,7 +33,7 @@ ambiguousStrings.forEach((string) => { assert.throws( RangeError, () => instance.equals(arg), - 'space is not accepted as a substitute for T prefix' + "space is not accepted as a substitute for T prefix" ); }); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/equals/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/equals/argument-wrong-type.js index 7d50260cadb1..488543505593 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/equals/argument-wrong-type.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/equals/argument-wrong-type.js @@ -1,23 +1,39 @@ // |reftest| skip -- Temporal is not supported -// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// Copyright (C) 2022 Igalia, S.L. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. /*--- esid: sec-temporal.plaintime.prototype.equals -description: Appropriate error thrown when argument cannot be converted to a valid string -features: [Symbol, Temporal] +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainTime +features: [BigInt, Symbol, Temporal] ---*/ -const instance = Temporal.PlainTime.from({ minute: 34, second: 56, millisecond: 987, microsecond: 654, nanosecond: 321 }); +const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); -assert.throws(RangeError, () => instance.equals(undefined), "undefined"); -assert.throws(RangeError, () => instance.equals(null), "null"); -assert.throws(RangeError, () => instance.equals(true), "true"); -assert.throws(RangeError, () => instance.equals(""), "empty string"); -assert.throws(TypeError, () => instance.equals(Symbol()), "symbol"); -assert.throws(RangeError, () => instance.equals(1), "1"); -assert.throws(TypeError, () => instance.equals({}), "plain object"); -assert.throws(TypeError, () => instance.equals(Temporal.PlainTime), "Temporal.PlainTime"); -assert.throws(TypeError, () => instance.equals(Temporal.PlainTime.prototype), "Temporal.PlainTime.prototype"); +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.equals(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainTime, "Temporal.PlainTime, object"], + [Temporal.PlainTime.prototype, "Temporal.PlainTime.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.equals(arg), `${description} is not a valid property bag and does not convert to a string`); +} reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/equals/leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/equals/leap-second.js new file mode 100644 index 000000000000..864c437dd2e2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/equals/leap-second.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.equals +description: Leap second is a valid ISO string for PlainTime +features: [Temporal] +---*/ + +const instance = new Temporal.PlainTime(23, 59, 59); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.equals(arg); +assert.sameValue( + result1, + true, + "leap second is a valid ISO string for PlainTime" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.equals(arg); +assert.sameValue( + result2, + true, + "second: 60 is ignored in property bag for PlainTime" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/equals/plaintime-propertybag-no-time-units.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/equals/plaintime-propertybag-no-time-units.js index 4b3ea1c730a5..55efac1801a8 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/equals/plaintime-propertybag-no-time-units.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/equals/plaintime-propertybag-no-time-units.js @@ -11,7 +11,7 @@ features: [Temporal] const instance = new Temporal.PlainTime(0, 30, 0, 0, 0, 0); const props = {}; -assert.throws(TypeError, () => instance.equals(props), "TypeError if at least one property is not present"); +assert.throws(TypeError, () => instance.equals(props), "TypeError if no properties are present"); props.minute = 30; const result = instance.equals(props); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/equals/year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/equals/year-zero.js index affab7b21225..c5932c004c74 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/equals/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/equals/year-zero.js @@ -9,8 +9,9 @@ features: [Temporal, arrow-function] ---*/ const invalidStrings = [ - '-000000-12-07T03:24:30', - '-000000-12-07T03:24:30+01:00[UTC]' + "-000000-12-07T03:24:30", + "-000000-12-07T03:24:30+01:00", + "-000000-12-07T03:24:30+00:00[UTC]", ]; const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); invalidStrings.forEach((arg) => { diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/round/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/round/options-wrong-type.js new file mode 100644 index 000000000000..0a76a4e438a7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/round/options-wrong-type.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.round +description: TypeError thrown when options argument is missing or a non-string primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + undefined, + null, + true, + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.PlainTime(); +assert.throws(TypeError, () => instance.round(), "TypeError on missing options argument"); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.round(value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/round/roundto-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/round/roundto-invalid-string.js new file mode 100644 index 000000000000..b83be42070aa --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/round/roundto-invalid-string.js @@ -0,0 +1,38 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.round +description: RangeError thrown when smallestUnit option not one of the allowed string values +features: [Temporal] +---*/ + +const time = new Temporal.PlainTime(12, 34, 56, 123, 987, 500); +const badValues = [ + "era", + "eraYear", + "year", + "month", + "week", + "day", + "millisecond\0", + "mill\u0131second", + "SECOND", + "eras", + "eraYears", + "years", + "months", + "weeks", + "days", + "milliseconds\0", + "mill\u0131seconds", + "SECONDS", + "other string", +]; +for (const smallestUnit of badValues) { + assert.throws(RangeError, () => time.round(smallestUnit), + `"${smallestUnit}" is not a valid value for smallest unit`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/round/smallestunit-disallowed-units.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/round/smallestunit-disallowed-units.js deleted file mode 100644 index 1329fc9a642d..000000000000 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/round/smallestunit-disallowed-units.js +++ /dev/null @@ -1,37 +0,0 @@ -// |reftest| skip -- Temporal is not supported -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.plaintime.prototype.round -description: Specifically disallowed units for the smallestUnit option -features: [Temporal, arrow-function] ----*/ - -const instance = new Temporal.PlainTime(12, 34, 56, 789, 999, 999); -const invalidUnits = [ - "era", - "eras", - "year", - "month", - "week", - "years", - "months", - "weeks", - "day", - "days", -]; -invalidUnits.forEach((smallestUnit) => { - assert.throws( - RangeError, - () => instance.round({ smallestUnit }), - `{ smallestUnit: "${smallestUnit}" } should not be allowed as an argument to round` - ); - assert.throws( - RangeError, - () => instance.round(smallestUnit), - `"${smallestUnit}" should not be allowed as an argument to round` - ); -}); - -reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/round/smallestunit-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/round/smallestunit-invalid-string.js index 0d347dc22bca..58d452b3b4ed 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/round/smallestunit-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/round/smallestunit-invalid-string.js @@ -9,9 +9,30 @@ features: [Temporal] ---*/ const time = new Temporal.PlainTime(12, 34, 56, 123, 987, 500); -const values = ["era", "year", "month", "week", "day", "years", "months", "weeks", "days", "nonsense", "other string"]; -for (const smallestUnit of values) { - assert.throws(RangeError, () => time.round({ smallestUnit })); +const badValues = [ + "era", + "eraYear", + "year", + "month", + "week", + "day", + "millisecond\0", + "mill\u0131second", + "SECOND", + "eras", + "eraYears", + "years", + "months", + "weeks", + "days", + "milliseconds\0", + "mill\u0131seconds", + "SECONDS", + "other string", +]; +for (const smallestUnit of badValues) { + assert.throws(RangeError, () => time.round({ smallestUnit }), + `"${smallestUnit}" is not a valid value for smallest unit`); } reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/since/argument-number.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/since/argument-number.js new file mode 100644 index 000000000000..3889dfea59ec --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/since/argument-number.js @@ -0,0 +1,34 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.since +description: A number is converted to a string, then to Temporal.PlainTime +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); + +const arg = 123456.987654321; + +const result = instance.since(arg); +TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "123456.987654321 is a valid ISO string for PlainTime"); + +const numbers = [ + 1, + -123456.987654321, + 1234567, + 123456.9876543219, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.since(arg), + `Number ${arg} does not convert to a valid ISO string for PlainTime` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/since/argument-string-time-designator-required-for-disambiguation.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/since/argument-string-time-designator-required-for-disambiguation.js index 307d3974f7d6..7943c9881615 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/since/argument-string-time-designator-required-for-disambiguation.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/since/argument-string-time-designator-required-for-disambiguation.js @@ -33,7 +33,7 @@ ambiguousStrings.forEach((string) => { assert.throws( RangeError, () => instance.since(arg), - 'space is not accepted as a substitute for T prefix' + "space is not accepted as a substitute for T prefix" ); }); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/since/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/since/argument-wrong-type.js new file mode 100644 index 000000000000..c842736a8c23 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/since/argument-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.since +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainTime +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.since(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainTime, "Temporal.PlainTime, object"], + [Temporal.PlainTime.prototype, "Temporal.PlainTime.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.since(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/since/largestunit-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/since/largestunit-invalid-string.js index 8bc3b4c89688..05d9bc9b4c2b 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/since/largestunit-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/since/largestunit-invalid-string.js @@ -10,9 +10,30 @@ features: [Temporal] const earlier = new Temporal.PlainTime(12, 34, 56, 0, 0, 0); const later = new Temporal.PlainTime(13, 35, 57, 987, 654, 321); -const values = ["era", "eraYear", "years", "months", "weeks", "days", "other string"]; -for (const largestUnit of values) { - assert.throws(RangeError, () => later.since(earlier, { largestUnit })); +const badValues = [ + "era", + "eraYear", + "year", + "month", + "week", + "day", + "millisecond\0", + "mill\u0131second", + "SECOND", + "eras", + "eraYears", + "years", + "months", + "weeks", + "days", + "milliseconds\0", + "mill\u0131seconds", + "SECONDS", + "other string" +]; +for (const largestUnit of badValues) { + assert.throws(RangeError, () => later.since(earlier, { largestUnit }), + `"${largestUnit}" is not a valid value for largestUnit`); } reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/since/leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/since/leap-second.js new file mode 100644 index 000000000000..0c56d70f6370 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/since/leap-second.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.since +description: Leap second is a valid ISO string for PlainTime +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainTime(23, 59, 59); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.since(arg); +TemporalHelpers.assertDuration( + result1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "leap second is a valid ISO string for PlainTime" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.since(arg); +TemporalHelpers.assertDuration( + result2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "second: 60 is ignored in property bag for PlainTime" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/since/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/since/options-wrong-type.js new file mode 100644 index 000000000000..2096b327150f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/since/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.since +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.PlainTime(); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.since(new Temporal.PlainTime(12, 34, 56), value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/since/plaintime-propertybag-no-time-units.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/since/plaintime-propertybag-no-time-units.js new file mode 100644 index 000000000000..055f77f3829a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/since/plaintime-propertybag-no-time-units.js @@ -0,0 +1,21 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.since +description: Missing time units in property bag default to 0 +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainTime(1, 0, 0, 0, 0, 1); + +const props = {}; +assert.throws(TypeError, () => instance.since(props), "TypeError if no properties are present"); + +props.minute = 30; +const result = instance.since(props); +TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 30, 0, 0, 0, 1, "missing time units default to 0"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/since/smallestunit-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/since/smallestunit-invalid-string.js index cae946d1569f..72fe195582da 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/since/smallestunit-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/since/smallestunit-invalid-string.js @@ -10,9 +10,30 @@ features: [Temporal] const earlier = new Temporal.PlainTime(12, 34, 56, 0, 0, 0); const later = new Temporal.PlainTime(13, 35, 57, 987, 654, 321); -const values = ["era", "eraYear", "years", "months", "weeks", "days", "other string"]; -for (const smallestUnit of values) { - assert.throws(RangeError, () => later.since(earlier, { smallestUnit })); +const badValues = [ + "era", + "eraYear", + "year", + "month", + "week", + "day", + "millisecond\0", + "mill\u0131second", + "SECOND", + "eras", + "eraYears", + "years", + "months", + "weeks", + "days", + "milliseconds\0", + "mill\u0131seconds", + "SECONDS", + "other string", +]; +for (const smallestUnit of badValues) { + assert.throws(RangeError, () => later.since(earlier, { smallestUnit }), + `"${smallestUnit}" is not a valid value for smallest unit`); } reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/since/year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/since/year-zero.js index d79f1cde682b..86ea5422c86d 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/since/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/since/year-zero.js @@ -9,8 +9,9 @@ features: [Temporal, arrow-function] ---*/ const invalidStrings = [ - '-000000-12-07T03:24:30', - '-000000-12-07T03:24:30+01:00[UTC]' + "-000000-12-07T03:24:30", + "-000000-12-07T03:24:30+01:00", + "-000000-12-07T03:24:30+00:00[UTC]", ]; const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); invalidStrings.forEach((arg) => { diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-number.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-number.js new file mode 100644 index 000000000000..508d95fbf009 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-number.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.toplaindatetime +description: A number is converted to a string, then to Temporal.PlainDate +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); + +const arg = 19761118; + +const result = instance.toPlainDateTime(arg); +TemporalHelpers.assertPlainDateTime(result, 1976, 11, "M11", 18, 12, 34, 56, 987, 654, 321, "19761118 is a valid ISO string for PlainDate"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.toPlainDateTime(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..491351f66a2c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.toplaindatetime +description: Leap second is a valid ISO string for a calendar in a property bag +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.toPlainDateTime(arg); +TemporalHelpers.assertPlainDateTime( + result1, + 1976, 11, "M11", 18, 12, 34, 56, 987, 654, 321, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.toPlainDateTime(arg); +TemporalHelpers.assertPlainDateTime( + result2, + 1976, 11, "M11", 18, 12, 34, 56, 987, 654, 321, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..f45fea77cc33 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-propertybag-calendar-number.js @@ -0,0 +1,45 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.toplaindatetime +description: A number as calendar in a property bag is converted to a string, then to a calendar +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.toPlainDateTime(arg); +TemporalHelpers.assertPlainDateTime(result1, 1976, 11, "M11", 18, 12, 34, 56, 987, 654, 321, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.toPlainDateTime(arg); +TemporalHelpers.assertPlainDateTime(result2, 1976, 11, "M11", 18, 12, 34, 56, 987, 654, 321, "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + assert.throws( + RangeError, + () => instance.toPlainDateTime(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.toPlainDateTime(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..b0e83ff951fa --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.toplaindatetime +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.toPlainDateTime(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.toPlainDateTime(arg), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.toPlainDateTime(arg), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.toPlainDateTime(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.toPlainDateTime(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..424b44dba78f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.toplaindatetime +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.toPlainDateTime(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-wrong-type.js new file mode 100644 index 000000000000..22cca4e14c3d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/argument-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.toplaindatetime +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.toPlainDateTime(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.toPlainDateTime(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/leap-second.js new file mode 100644 index 000000000000..23d044c61e9c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/leap-second.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.toplaindatetime +description: Leap second is a valid ISO string for PlainDate +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.toPlainDateTime(arg); +TemporalHelpers.assertPlainDateTime( + result1, + 2016, 12, "M12", 31, 12, 34, 56, 987, 654, 321, + "leap second is a valid ISO string for PlainDate" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.toPlainDateTime(arg); +TemporalHelpers.assertPlainDateTime( + result2, + 2016, 12, "M12", 31, 12, 34, 56, 987, 654, 321, + "second: 60 is ignored in property bag for PlainDate" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/limits.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/limits.js new file mode 100644 index 000000000000..423e019f9fdc --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/limits.js @@ -0,0 +1,42 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.toplaindatetime +description: Checking limits of representable PlainDateTime +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const midnight = new Temporal.PlainTime(0, 0); +const firstNs = new Temporal.PlainTime(0, 0, 0, 0, 0, 1); +const lastNs = new Temporal.PlainTime(23, 59, 59, 999, 999, 999); +const min = new Temporal.PlainDate(-271821, 4, 19); +const max = new Temporal.PlainDate(275760, 9, 13); + +assert.throws( + RangeError, + () => midnight.toPlainDateTime(min), + "Cannot go below representable limit" +); + +TemporalHelpers.assertPlainDateTime( + midnight.toPlainDateTime(max), + 275760, 9, "M09", 13, 0, 0, 0, 0, 0, 0, + "Midnight of maximum representable PlainDate" +); + +TemporalHelpers.assertPlainDateTime( + firstNs.toPlainDateTime(min), + -271821, 4, "M04", 19, 0, 0, 0, 0, 0, 1, + "Computing the minimum (earliest) representable PlainDateTime" +); + +TemporalHelpers.assertPlainDateTime( + lastNs.toPlainDateTime(max), + 275760, 9, "M09", 13, 23, 59, 59, 999, 999, 999, + "Computing the maximum (latest) representable PlainDateTime" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/year-zero.js index 953e60032744..8c26d69a57df 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/year-zero.js @@ -8,13 +8,19 @@ description: Negative zero, as an extended year, is rejected features: [Temporal, arrow-function] ---*/ -const arg = "-000000-10-31"; +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); - -assert.throws( +invalidStrings.forEach((arg) => { + assert.throws( RangeError, - () => { instance.toPlainDateTime(arg); }, + () => instance.toPlainDateTime(arg), "reject minus zero as extended year" -); + ); +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/fractionalseconddigits-auto.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/fractionalseconddigits-auto.js index 5ff6358d240e..7460bcbfc91b 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/fractionalseconddigits-auto.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/fractionalseconddigits-auto.js @@ -8,15 +8,19 @@ description: auto value for fractionalSecondDigits option features: [Temporal] ---*/ +const zeroSeconds = new Temporal.PlainTime(15, 23); +const wholeSeconds = new Temporal.PlainTime(15, 23, 30); +const subSeconds = new Temporal.PlainTime(15, 23, 30, 123, 400); + const tests = [ - ["15:23", "15:23:00"], - ["15:23:30", "15:23:30"], - ["15:23:30.1234", "15:23:30.1234"], + [zeroSeconds, "15:23:00"], + [wholeSeconds, "15:23:30"], + [subSeconds, "15:23:30.1234"], ]; -for (const [input, expected] of tests) { - const plainTime = Temporal.PlainTime.from(input); - assert.sameValue(plainTime.toString({ fractionalSecondDigits: "auto" }), expected); +for (const [time, expected] of tests) { + assert.sameValue(time.toString(), expected, "default is to emit seconds and drop trailing zeroes"); + assert.sameValue(time.toString({ fractionalSecondDigits: "auto" }), expected, "auto is the default"); } reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/fractionalseconddigits-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/fractionalseconddigits-invalid-string.js index 6d6e33846183..af1390033989 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/fractionalseconddigits-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/fractionalseconddigits-invalid-string.js @@ -11,14 +11,15 @@ info: | sec-temporal-tosecondsstringprecision step 9: 9. Let _digits_ be ? GetStringOrNumberOption(_normalizedOptions_, *"fractionalSecondDigits"*, « *"auto"* », 0, 9, *"auto"*). sec-temporal.plaintime.prototype.tostring step 4: - 4. Let _precision_ be ? ToDurationSecondsStringPrecision(_options_). + 4. Let _precision_ be ? ToSecondsStringPrecision(_options_). features: [Temporal] ---*/ const time = new Temporal.PlainTime(12, 34, 56, 987, 650, 0); -for (const fractionalSecondDigits of ["other string", "AUTO", "not-auto", "autos"]) { - assert.throws(RangeError, () => time.toString({ fractionalSecondDigits })); +for (const fractionalSecondDigits of ["other string", "AUTO", "not-auto", "autos", "auto\0"]) { + assert.throws(RangeError, () => time.toString({ fractionalSecondDigits }), + `"${fractionalSecondDigits}" is not a valid value for fractionalSecondDigits`); } reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/fractionalseconddigits-non-integer.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/fractionalseconddigits-non-integer.js index 39677ed913ac..f9ecb49c5dd4 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/fractionalseconddigits-non-integer.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/fractionalseconddigits-non-integer.js @@ -11,7 +11,7 @@ info: | sec-temporal-tosecondsstringprecision step 9: 9. Let _digits_ be ? GetStringOrNumberOption(_normalizedOptions_, *"fractionalSecondDigits"*, « *"auto"* », 0, 9, *"auto"*). sec-temporal.plaintime.prototype.tostring step 4: - 4. Let _precision_ be ? ToDurationSecondsStringPrecision(_options_). + 4. Let _precision_ be ? ToSecondsStringPrecision(_options_). features: [Temporal] ---*/ diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/fractionalseconddigits-number.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/fractionalseconddigits-number.js index 2564bedfea06..896bd321b982 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/fractionalseconddigits-number.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/fractionalseconddigits-number.js @@ -8,18 +8,29 @@ description: Number for fractionalSecondDigits option features: [Temporal] ---*/ -const t1 = Temporal.PlainTime.from("15:23"); -const t2 = Temporal.PlainTime.from("15:23:30"); -const t3 = Temporal.PlainTime.from("15:23:30.1234"); -assert.sameValue(t3.toString({ fractionalSecondDigits: 0 }), "15:23:30"); -assert.sameValue(t1.toString({ fractionalSecondDigits: 2 }), "15:23:00.00"); -assert.sameValue(t2.toString({ fractionalSecondDigits: 2 }), "15:23:30.00"); -assert.sameValue(t3.toString({ fractionalSecondDigits: 2 }), "15:23:30.12"); -assert.sameValue(t3.toString({ fractionalSecondDigits: 3 }), "15:23:30.123"); -assert.sameValue(t3.toString({ fractionalSecondDigits: 6 }), "15:23:30.123400"); -assert.sameValue(t1.toString({ fractionalSecondDigits: 7 }), "15:23:00.0000000"); -assert.sameValue(t2.toString({ fractionalSecondDigits: 7 }), "15:23:30.0000000"); -assert.sameValue(t3.toString({ fractionalSecondDigits: 7 }), "15:23:30.1234000"); -assert.sameValue(t3.toString({ fractionalSecondDigits: 9 }), "15:23:30.123400000"); +const zeroSeconds = new Temporal.PlainTime(15, 23); +const wholeSeconds = new Temporal.PlainTime(15, 23, 30); +const subSeconds = new Temporal.PlainTime(15, 23, 30, 123, 400); + +assert.sameValue(subSeconds.toString({ fractionalSecondDigits: 0 }), "15:23:30", + "truncates 4 decimal places to 0"); +assert.sameValue(zeroSeconds.toString({ fractionalSecondDigits: 2 }), "15:23:00.00", + "pads zero seconds to 2 decimal places"); +assert.sameValue(wholeSeconds.toString({ fractionalSecondDigits: 2 }), "15:23:30.00", + "pads whole seconds to 2 decimal places"); +assert.sameValue(subSeconds.toString({ fractionalSecondDigits: 2 }), "15:23:30.12", + "truncates 4 decimal places to 2"); +assert.sameValue(subSeconds.toString({ fractionalSecondDigits: 3 }), "15:23:30.123", + "truncates 4 decimal places to 3"); +assert.sameValue(subSeconds.toString({ fractionalSecondDigits: 6 }), "15:23:30.123400", + "pads 4 decimal places to 6"); +assert.sameValue(zeroSeconds.toString({ fractionalSecondDigits: 7 }), "15:23:00.0000000", + "pads zero seconds to 7 decimal places"); +assert.sameValue(wholeSeconds.toString({ fractionalSecondDigits: 7 }), "15:23:30.0000000", + "pads whole seconds to 7 decimal places"); +assert.sameValue(subSeconds.toString({ fractionalSecondDigits: 7 }), "15:23:30.1234000", + "pads 4 decimal places to 7"); +assert.sameValue(subSeconds.toString({ fractionalSecondDigits: 9 }), "15:23:30.123400000", + "pads 4 decimal places to 9"); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/fractionalseconddigits-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/fractionalseconddigits-out-of-range.js index 89d198c1a152..c58e35a3dab0 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/fractionalseconddigits-out-of-range.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/fractionalseconddigits-out-of-range.js @@ -11,15 +11,19 @@ info: | sec-temporal-tosecondsstringprecision step 9: 9. Let _digits_ be ? GetStringOrNumberOption(_normalizedOptions_, *"fractionalSecondDigits"*, « *"auto"* », 0, 9, *"auto"*). sec-temporal.plaintime.prototype.tostring step 4: - 4. Let _precision_ be ? ToDurationSecondsStringPrecision(_options_). + 4. Let _precision_ be ? ToSecondsStringPrecision(_options_). features: [Temporal] ---*/ const time = new Temporal.PlainTime(12, 34, 56, 987, 650, 0); -assert.throws(RangeError, () => time.toString({ fractionalSecondDigits: -Infinity })); -assert.throws(RangeError, () => time.toString({ fractionalSecondDigits: -1 })); -assert.throws(RangeError, () => time.toString({ fractionalSecondDigits: 10 })); -assert.throws(RangeError, () => time.toString({ fractionalSecondDigits: Infinity })); +assert.throws(RangeError, () => time.toString({ fractionalSecondDigits: -Infinity }), + "−∞ is out of range for fractionalSecondDigits"); +assert.throws(RangeError, () => time.toString({ fractionalSecondDigits: -1 }), + "−1 is out of range for fractionalSecondDigits"); +assert.throws(RangeError, () => time.toString({ fractionalSecondDigits: 10 }), + "10 is out of range for fractionalSecondDigits"); +assert.throws(RangeError, () => time.toString({ fractionalSecondDigits: Infinity }), + "∞ is out of range for fractionalSecondDigits"); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/fractionalseconddigits-undefined.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/fractionalseconddigits-undefined.js index 216d78438157..bfb662ac95a2 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/fractionalseconddigits-undefined.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/fractionalseconddigits-undefined.js @@ -9,31 +9,33 @@ info: | sec-getoption step 3: 3. If _value_ is *undefined*, return _fallback_. sec-getstringornumberoption step 2: - 2. Let _value_ be ? GetOption(_options_, _property_, *"stringOrNumber"*, *undefined*, _fallback_). + 2. Let _value_ be ? GetOption(_options_, _property_, « Number, String », *undefined*, _fallback_). sec-temporal-tosecondsstringprecision step 9: 9. Let _digits_ be ? GetStringOrNumberOption(_normalizedOptions_, *"fractionalSecondDigits"*, « *"auto"* », 0, 9, *"auto"*). sec-temporal.plaintime.prototype.tostring step 4: - 4. Let _precision_ be ? ToDurationSecondsStringPrecision(_options_). + 4. Let _precision_ be ? ToSecondsStringPrecision(_options_). features: [Temporal] ---*/ +const zeroSeconds = new Temporal.PlainTime(15, 23); +const wholeSeconds = new Temporal.PlainTime(15, 23, 30); +const subSeconds = new Temporal.PlainTime(15, 23, 30, 123, 400); + const tests = [ - ["15:23", "15:23:00"], - ["15:23:30", "15:23:30"], - ["15:23:30.1234", "15:23:30.1234"], + [zeroSeconds, "15:23:00"], + [wholeSeconds, "15:23:30"], + [subSeconds, "15:23:30.1234"], ]; -for (const [input, expected] of tests) { - const time = Temporal.PlainTime.from(input); - +for (const [time, expected] of tests) { const explicit = time.toString({ fractionalSecondDigits: undefined }); - assert.sameValue(explicit, expected, "default fractionalSecondDigits is auto"); + assert.sameValue(explicit, expected, "default fractionalSecondDigits is auto (property present but undefined)"); const implicit = time.toString({}); - assert.sameValue(implicit, expected, "default fractionalSecondDigits is auto"); + assert.sameValue(implicit, expected, "default fractionalSecondDigits is auto (property not present)"); const lambda = time.toString(() => {}); - assert.sameValue(lambda, expected, "default fractionalSecondDigits is auto"); + assert.sameValue(lambda, expected, "default fractionalSecondDigits is auto (property not present, function object)"); } reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/fractionalseconddigits-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/fractionalseconddigits-wrong-type.js index 9c3dec82eb14..4c7bffaf2e8e 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/fractionalseconddigits-wrong-type.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/fractionalseconddigits-wrong-type.js @@ -23,6 +23,28 @@ features: [Temporal] ---*/ const time = new Temporal.PlainTime(12, 34, 56, 987, 650, 0); -TemporalHelpers.checkFractionalSecondDigitsOptionWrongType(time); + +assert.throws(RangeError, () => time.toString({ fractionalSecondDigits: null }), + "null is not a number and converts to the string 'null' which is not valid for fractionalSecondDigits"); +assert.throws(RangeError, () => time.toString({ fractionalSecondDigits: true }), + "true is not a number and converts to the string 'true' which is not valid for fractionalSecondDigits"); +assert.throws(RangeError, () => time.toString({ fractionalSecondDigits: false }), + "false is not a number and converts to the string 'false' which is not valid for fractionalSecondDigits"); +assert.throws(TypeError, () => time.toString({ fractionalSecondDigits: Symbol() }), + "symbols are not numbers and cannot convert to strings"); +assert.throws(RangeError, () => time.toString({ fractionalSecondDigits: 2n }), + "bigints are not numbers and convert to strings which are not valid for fractionalSecondDigits"); +assert.throws(RangeError, () => time.toString({ fractionalSecondDigits: {} }), + "plain objects are not numbers and convert to strings which are not valid for fractionalSecondDigits"); + +const expected = [ + "get fractionalSecondDigits.toString", + "call fractionalSecondDigits.toString", +]; +const actual = []; +const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); +const result = time.toString({ fractionalSecondDigits: observer }); +assert.sameValue(result, "12:34:56.98765", "object with toString uses toString return value"); +assert.compareArray(actual, expected, "object with toString calls toString and not valueOf"); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/options-wrong-type.js new file mode 100644 index 000000000000..40343e1cc48f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.tostring +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.PlainTime(); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.toString(value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/rounding-cross-midnight.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/rounding-cross-midnight.js index 34a879298786..c1b696111896 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/rounding-cross-midnight.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/rounding-cross-midnight.js @@ -8,7 +8,7 @@ description: Rounding can cross midnight features: [Temporal] ---*/ -const plainTime = Temporal.PlainTime.from("23:59:59.999999999"); +const plainTime = new Temporal.PlainTime(23, 59, 59, 999, 999, 999); // one nanosecond before 00:00:00 for (const roundingMode of ["ceil", "halfExpand"]) { assert.sameValue(plainTime.toString({ fractionalSecondDigits: 8, roundingMode }), "00:00:00.00000000"); } diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/roundingmode-ceil.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/roundingmode-ceil.js index 70a304f979dd..533d7a23757e 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/roundingmode-ceil.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/roundingmode-ceil.js @@ -11,12 +11,30 @@ features: [Temporal] const time = new Temporal.PlainTime(12, 34, 56, 123, 987, 500); const result1 = time.toString({ smallestUnit: "microsecond", roundingMode: "ceil" }); -assert.sameValue(result1, "12:34:56.123988", "roundingMode is ceil"); +assert.sameValue(result1, "12:34:56.123988", + "roundingMode is ceil (with 6 digits from smallestUnit)"); -const result2 = time.toString({ smallestUnit: "millisecond", roundingMode: "ceil" }); -assert.sameValue(result2, "12:34:56.124", "roundingMode is ceil"); +const result2 = time.toString({ fractionalSecondDigits: 6, roundingMode: "ceil" }); +assert.sameValue(result2, "12:34:56.123988", + "roundingMode is ceil (with 6 digits from fractionalSecondDigits)"); -const result3 = time.toString({ smallestUnit: "second", roundingMode: "ceil" }); -assert.sameValue(result3, "12:34:57", "roundingMode is ceil"); +const result3 = time.toString({ smallestUnit: "millisecond", roundingMode: "ceil" }); +assert.sameValue(result3, "12:34:56.124", + "roundingMode is ceil (with 3 digits from smallestUnit)"); + +const result4 = time.toString({ fractionalSecondDigits: 3, roundingMode: "ceil" }); +assert.sameValue(result4, "12:34:56.124", + "roundingMode is ceil (with 3 digits from fractionalSecondDigits)"); + +const result5 = time.toString({ smallestUnit: "second", roundingMode: "ceil" }); +assert.sameValue(result5, "12:34:57", + "roundingMode is ceil (with 0 digits from smallestUnit)"); + +const result6 = time.toString({ fractionalSecondDigits: 0, roundingMode: "ceil" }); +assert.sameValue(result6, "12:34:57", + "roundingMode is ceil (with 0 digits from fractionalSecondDigits)"); + +const result7 = time.toString({ smallestUnit: "minute", roundingMode: "ceil" }); +assert.sameValue(result7, "12:35", "roundingMode is ceil (round to minute)"); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/roundingmode-floor.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/roundingmode-floor.js index e8f38a6c009a..d885cb9b1f88 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/roundingmode-floor.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/roundingmode-floor.js @@ -11,12 +11,30 @@ features: [Temporal] const time = new Temporal.PlainTime(12, 34, 56, 123, 987, 500); const result1 = time.toString({ smallestUnit: "microsecond", roundingMode: "floor" }); -assert.sameValue(result1, "12:34:56.123987", "roundingMode is floor"); +assert.sameValue(result1, "12:34:56.123987", + "roundingMode is floor (with 6 digits from smallestUnit)"); -const result2 = time.toString({ smallestUnit: "millisecond", roundingMode: "floor" }); -assert.sameValue(result2, "12:34:56.123", "roundingMode is floor"); +const result2 = time.toString({ fractionalSecondDigits: 6, roundingMode: "floor" }); +assert.sameValue(result2, "12:34:56.123987", + "roundingMode is floor (with 6 digits from fractionalSecondDigits)"); -const result3 = time.toString({ smallestUnit: "second", roundingMode: "floor" }); -assert.sameValue(result3, "12:34:56", "roundingMode is floor"); +const result3 = time.toString({ smallestUnit: "millisecond", roundingMode: "floor" }); +assert.sameValue(result3, "12:34:56.123", + "roundingMode is floor (with 3 digits from smallestUnit)"); + +const result4 = time.toString({ fractionalSecondDigits: 3, roundingMode: "floor" }); +assert.sameValue(result4, "12:34:56.123", + "roundingMode is floor (with 3 digits from fractionalSecondDigits)"); + +const result5 = time.toString({ smallestUnit: "second", roundingMode: "floor" }); +assert.sameValue(result5, "12:34:56", + "roundingMode is floor (with 0 digits from smallestUnit)"); + +const result6 = time.toString({ fractionalSecondDigits: 0, roundingMode: "floor" }); +assert.sameValue(result6, "12:34:56", + "roundingMode is floor (with 0 digits from fractionalSecondDigits)"); + +const result7 = time.toString({ smallestUnit: "minute", roundingMode: "floor" }); +assert.sameValue(result7, "12:34", "roundingMode is floor (round to minute)"); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/roundingmode-halfExpand.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/roundingmode-halfExpand.js index 70ad19dc10a1..72c287004f0e 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/roundingmode-halfExpand.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/roundingmode-halfExpand.js @@ -11,12 +11,30 @@ features: [Temporal] const time = new Temporal.PlainTime(12, 34, 56, 123, 987, 500); const result1 = time.toString({ smallestUnit: "microsecond", roundingMode: "halfExpand" }); -assert.sameValue(result1, "12:34:56.123988", "roundingMode is halfExpand"); +assert.sameValue(result1, "12:34:56.123988", + "roundingMode is halfExpand (with 6 digits from smallestUnit)"); -const result2 = time.toString({ smallestUnit: "millisecond", roundingMode: "halfExpand" }); -assert.sameValue(result2, "12:34:56.124", "roundingMode is halfExpand"); +const result2 = time.toString({ fractionalSecondDigits: 6, roundingMode: "halfExpand" }); +assert.sameValue(result2, "12:34:56.123988", + "roundingMode is halfExpand (with 6 digits from fractionalSecondDigits)"); -const result3 = time.toString({ smallestUnit: "second", roundingMode: "halfExpand" }); -assert.sameValue(result3, "12:34:56", "roundingMode is halfExpand"); +const result3 = time.toString({ smallestUnit: "millisecond", roundingMode: "halfExpand" }); +assert.sameValue(result3, "12:34:56.124", + "roundingMode is halfExpand (with 3 digits from smallestUnit)"); + +const result4 = time.toString({ fractionalSecondDigits: 3, roundingMode: "halfExpand" }); +assert.sameValue(result4, "12:34:56.124", + "roundingMode is halfExpand (with 3 digits from fractionalSecondDigits)"); + +const result5 = time.toString({ smallestUnit: "second", roundingMode: "halfExpand" }); +assert.sameValue(result5, "12:34:56", + "roundingMode is halfExpand (with 0 digits from smallestUnit)"); + +const result6 = time.toString({ fractionalSecondDigits: 0, roundingMode: "halfExpand" }); +assert.sameValue(result6, "12:34:56", + "roundingMode is halfExpand (with 0 digits from fractionalSecondDigits)"); + +const result7 = time.toString({ smallestUnit: "minute", roundingMode: "halfExpand" }); +assert.sameValue(result7, "12:35", "roundingMode is halfExpand (round to minute)"); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/roundingmode-trunc.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/roundingmode-trunc.js index ab2dcfcc9283..7951487e47dd 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/roundingmode-trunc.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/roundingmode-trunc.js @@ -11,12 +11,30 @@ features: [Temporal] const time = new Temporal.PlainTime(12, 34, 56, 123, 987, 500); const result1 = time.toString({ smallestUnit: "microsecond", roundingMode: "trunc" }); -assert.sameValue(result1, "12:34:56.123987", "roundingMode is trunc"); +assert.sameValue(result1, "12:34:56.123987", + "roundingMode is trunc (with 6 digits from smallestUnit)"); -const result2 = time.toString({ smallestUnit: "millisecond", roundingMode: "trunc" }); -assert.sameValue(result2, "12:34:56.123", "roundingMode is trunc"); +const result2 = time.toString({ fractionalSecondDigits: 6, roundingMode: "trunc" }); +assert.sameValue(result2, "12:34:56.123987", + "roundingMode is trunc (with 6 digits from fractionalSecondDigits)"); -const result3 = time.toString({ smallestUnit: "second", roundingMode: "trunc" }); -assert.sameValue(result3, "12:34:56", "roundingMode is trunc"); +const result3 = time.toString({ smallestUnit: "millisecond", roundingMode: "trunc" }); +assert.sameValue(result3, "12:34:56.123", + "roundingMode is trunc (with 3 digits from smallestUnit)"); + +const result4 = time.toString({ fractionalSecondDigits: 3, roundingMode: "trunc" }); +assert.sameValue(result4, "12:34:56.123", + "roundingMode is trunc (with 3 digits from fractionalSecondDigits)"); + +const result5 = time.toString({ smallestUnit: "second", roundingMode: "trunc" }); +assert.sameValue(result5, "12:34:56", + "roundingMode is trunc (with 0 digits from smallestUnit)"); + +const result6 = time.toString({ fractionalSecondDigits: 0, roundingMode: "trunc" }); +assert.sameValue(result6, "12:34:56", + "roundingMode is trunc (with 0 digits from fractionalSecondDigits)"); + +const result7 = time.toString({ smallestUnit: "minute", roundingMode: "trunc" }); +assert.sameValue(result7, "12:34", "roundingMode is trunc (round to minute)"); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/smallestunit-fractionalseconddigits.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/smallestunit-fractionalseconddigits.js index 32b4161fde2f..6f83873c8d25 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/smallestunit-fractionalseconddigits.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/smallestunit-fractionalseconddigits.js @@ -22,13 +22,12 @@ for (const [smallestUnit, expected] of tests) { smallestUnit, get fractionalSecondDigits() { throw new Test262Error("should not get fractionalSecondDigits") } }); - assert.sameValue(string, expected, smallestUnit); + assert.sameValue(string, expected, `smallestUnit: "${smallestUnit}" overrides fractionalSecondDigits`); } assert.throws(RangeError, () => time.toString({ smallestUnit: "hour", get fractionalSecondDigits() { throw new Test262Error("should not get fractionalSecondDigits") } -})); - +}), "hour is an invalid smallestUnit but still overrides fractionalSecondDigits"); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/smallestunit-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/smallestunit-invalid-string.js index 695b867608b1..70b60a9091fd 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/smallestunit-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/smallestunit-invalid-string.js @@ -9,8 +9,32 @@ features: [Temporal] ---*/ const time = new Temporal.PlainTime(12, 34, 56, 123, 987, 500); -for (const smallestUnit of ["era", "year", "month", "day", "hour", "nonsense", "other string", "m\u0131nute", "SECOND"]) { - assert.throws(RangeError, () => time.toString({ smallestUnit })); +const badValues = [ + "era", + "eraYear", + "year", + "month", + "week", + "day", + "hour", + "millisecond\0", + "mill\u0131second", + "SECOND", + "eras", + "eraYears", + "years", + "months", + "weeks", + "days", + "hours", + "milliseconds\0", + "mill\u0131seconds", + "SECONDS", + "other string", +]; +for (const smallestUnit of badValues) { + assert.throws(RangeError, () => time.toString({ smallestUnit }), + `"${smallestUnit}" is not a valid value for smallest unit`); } reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/smallestunit-valid-units.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/smallestunit-valid-units.js index e899c4e8148a..825680c0ff2d 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/smallestunit-valid-units.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toString/smallestunit-valid-units.js @@ -8,21 +8,41 @@ description: Valid units for the smallestUnit option features: [Temporal] ---*/ -const time = new Temporal.PlainTime(12, 34, 56, 789, 999, 999); -assert.sameValue(time.toString({ smallestUnit: "minute" }), "12:34"); -assert.sameValue(time.toString({ smallestUnit: "second" }), "12:34:56"); -assert.sameValue(time.toString({ smallestUnit: "millisecond" }), "12:34:56.789"); -assert.sameValue(time.toString({ smallestUnit: "microsecond" }), "12:34:56.789999"); -assert.sameValue(time.toString({ smallestUnit: "nanosecond" }), "12:34:56.789999999"); +const time = new Temporal.PlainTime(12, 34, 56, 123, 456, 789); -const time2 = new Temporal.PlainTime(12, 34); -assert.sameValue(time2.toString({ smallestUnit: "minute" }), "12:34"); -assert.sameValue(time2.toString({ smallestUnit: "second" }), "12:34:00"); -assert.sameValue(time2.toString({ smallestUnit: "millisecond" }), "12:34:00.000"); -assert.sameValue(time2.toString({ smallestUnit: "microsecond" }), "12:34:00.000000"); -assert.sameValue(time2.toString({ smallestUnit: "nanosecond" }), "12:34:00.000000000"); +function test(instance, expectations, description) { + for (const [smallestUnit, expectedResult] of expectations) { + assert.sameValue(instance.toString({ smallestUnit }), expectedResult, + `${description} with smallestUnit "${smallestUnit}"`); + } +} + +test( + time, + [ + ["minute", "12:34"], + ["second", "12:34:56"], + ["millisecond", "12:34:56.123"], + ["microsecond", "12:34:56.123456"], + ["nanosecond", "12:34:56.123456789"], + ], + "subseconds toString" +); + +test( + new Temporal.PlainTime(12, 34), + [ + ["minute", "12:34"], + ["second", "12:34:00"], + ["millisecond", "12:34:00.000"], + ["microsecond", "12:34:00.000000"], + ["nanosecond", "12:34:00.000000000"], + ], + "whole minutes toString" +); const notValid = [ + "era", "year", "month", "week", @@ -31,7 +51,8 @@ const notValid = [ ]; notValid.forEach((smallestUnit) => { - assert.throws(RangeError, () => time.toString({ smallestUnit }), smallestUnit); + assert.throws(RangeError, () => time.toString({ smallestUnit }), + `"${smallestUnit}" is not a valid unit for the smallestUnit option`); }); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-number.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-number.js new file mode 100644 index 000000000000..2c146f593748 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-number.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.tozoneddatetime +description: A number is converted to a string, then to Temporal.PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); + +const arg = 19761118; + +const result = instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }); +assert.sameValue(result.epochNanoseconds, 217_168_496_987_654_321n, "19761118 is a valid ISO string for PlainDate"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }), + `Number ${arg} does not convert to a valid ISO string for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..3f667ad4bfaa --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,31 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.tozoneddatetime +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }); +assert.sameValue( + result1.epochNanoseconds, + 217_168_496_987_654_321n, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }); +assert.sameValue( + result2.epochNanoseconds, + 217_168_496_987_654_321n, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..d37d67a2a8fd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-propertybag-calendar-number.js @@ -0,0 +1,44 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.tozoneddatetime +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }); +assert.sameValue(result1.epochNanoseconds, 217_168_496_987_654_321n, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }); +assert.sameValue(result2.epochNanoseconds, 217_168_496_987_654_321n, "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + assert.throws( + RangeError, + () => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..d917b6029fcd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.tozoneddatetime +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..30fa0c874573 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.tozoneddatetime +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-string-invalid.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-string-invalid.js index 32d184877c2f..487fe68188ee 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-string-invalid.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-string-invalid.js @@ -56,7 +56,7 @@ const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); for (const arg of invalidStrings) { assert.throws( RangeError, - () => instance.toZonedDateTime({ plainDate: arg }), + () => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }), `"${arg}" should not be a valid ISO string for a PlainDate` ); } diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-string-with-utc-designator.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-string-with-utc-designator.js index cacb2fbf2810..d49a144a5b59 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-string-with-utc-designator.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-string-with-utc-designator.js @@ -16,7 +16,7 @@ const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); invalidStrings.forEach((arg) => { assert.throws( RangeError, - () => instance.toZonedDateTime({ plainDate: arg }), + () => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }), "String with UTC designator should not be valid as a PlainDate" ); }); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-wrong-type.js new file mode 100644 index 000000000000..6daa1a4e5f56 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/argument-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.tozoneddatetime +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [undefined, "undefined"], // plainDate property is required + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/leap-second.js new file mode 100644 index 000000000000..31250ad462b7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/leap-second.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.tozoneddatetime +description: Leap second is a valid ISO string for PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }); +assert.sameValue( + result1.epochNanoseconds, + 1_483_187_696_987_654_321n, + "leap second is a valid ISO string for PlainDate" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }); +assert.sameValue( + result2.epochNanoseconds, + 1_483_187_696_987_654_321n, + "second: 60 is ignored in property bag for PlainDate" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-string-leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-string-leap-second.js new file mode 100644 index 000000000000..809a1bc07d5c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-string-leap-second.js @@ -0,0 +1,23 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.tozoneddatetime +description: Leap second is a valid ISO string for TimeZone +features: [Temporal] +---*/ + +const instance = new Temporal.PlainTime(); +let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; + +const result1 = instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone }); +assert.sameValue(result1.timeZone.id, "UTC", "leap second is a valid ISO string for TimeZone"); +const result2 = instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone: { timeZone } }); +assert.sameValue(result2.timeZone.id, "UTC", "leap second is a valid ISO string for TimeZone (nested property)"); + +timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; +assert.throws(RangeError, () => instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone }), "leap second in time zone name not valid"); +assert.throws(RangeError, () => instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone: { timeZone } }), "leap second in time zone name not valid (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-string-year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-string-year-zero.js new file mode 100644 index 000000000000..065d21083f16 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-string-year-zero.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.tozoneddatetime +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.PlainTime(); +invalidStrings.forEach((timeZone) => { + assert.throws( + RangeError, + () => instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone }), + "reject minus zero as extended year" + ); + assert.throws( + RangeError, + () => instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone: { timeZone } }), + "reject minus zero as extended year (nested property)" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-wrong-type.js new file mode 100644 index 000000000000..98f11841a2b8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/timezone-wrong-type.js @@ -0,0 +1,41 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.tozoneddatetime +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for TimeZone +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.PlainTime(); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], +]; + +for (const [timeZone, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone }), `${description} does not convert to a valid ISO string`); + assert.throws(RangeError, () => instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone: { timeZone } }), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [timeZone, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone }), `${description} is not a valid object and does not convert to a string`); + assert.throws(TypeError, () => instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone: { timeZone } }), `${description} is not a valid object and does not convert to a string (nested property)`); +} + +const timeZone = undefined; +assert.throws(RangeError, () => instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone: { timeZone } }), `undefined is always a RangeError as nested property`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/year-zero.js index 80535e1bc7a8..397cbf1d8714 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/toZonedDateTime/year-zero.js @@ -8,13 +8,19 @@ description: Negative zero, as an extended year, is rejected features: [Temporal, arrow-function] ---*/ -const arg = "-000000-10-31"; +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); - -assert.throws( +invalidStrings.forEach((arg) => { + assert.throws( RangeError, - () => { instance.toZonedDateTime({ plainDate: arg }); }, + () => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }), "reject minus zero as extended year" -); + ); +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/until/argument-number.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/until/argument-number.js new file mode 100644 index 000000000000..5d0a25c19dae --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/until/argument-number.js @@ -0,0 +1,34 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.until +description: A number is converted to a string, then to Temporal.PlainTime +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); + +const arg = 123456.987654321; + +const result = instance.until(arg); +TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "123456.987654321 is a valid ISO string for PlainTime"); + +const numbers = [ + 1, + -123456.987654321, + 1234567, + 123456.9876543219, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.until(arg), + `Number ${arg} does not convert to a valid ISO string for PlainTime` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/until/argument-string-time-designator-required-for-disambiguation.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/until/argument-string-time-designator-required-for-disambiguation.js index 50df5412fca0..cba74ea20abf 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/until/argument-string-time-designator-required-for-disambiguation.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/until/argument-string-time-designator-required-for-disambiguation.js @@ -33,7 +33,7 @@ ambiguousStrings.forEach((string) => { assert.throws( RangeError, () => instance.until(arg), - 'space is not accepted as a substitute for T prefix' + "space is not accepted as a substitute for T prefix" ); }); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/until/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/until/argument-wrong-type.js new file mode 100644 index 000000000000..c86fa664c7c7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/until/argument-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.until +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainTime +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.until(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainTime, "Temporal.PlainTime, object"], + [Temporal.PlainTime.prototype, "Temporal.PlainTime.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.until(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/until/largestunit-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/until/largestunit-invalid-string.js index d5cc7f06aeb6..cb344782d42a 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/until/largestunit-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/until/largestunit-invalid-string.js @@ -10,9 +10,30 @@ features: [Temporal] const earlier = new Temporal.PlainTime(12, 34, 56, 0, 0, 0); const later = new Temporal.PlainTime(13, 35, 57, 987, 654, 321); -const values = ["era", "eraYear", "years", "months", "weeks", "days", "other string"]; -for (const largestUnit of values) { - assert.throws(RangeError, () => earlier.until(later, { largestUnit })); +const badValues = [ + "era", + "eraYear", + "year", + "month", + "week", + "day", + "millisecond\0", + "mill\u0131second", + "SECOND", + "eras", + "eraYears", + "years", + "months", + "weeks", + "days", + "milliseconds\0", + "mill\u0131seconds", + "SECONDS", + "other string" +]; +for (const largestUnit of badValues) { + assert.throws(RangeError, () => earlier.until(later, { largestUnit }), + `"${largestUnit}" is not a valid value for largestUnit`); } reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/until/leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/until/leap-second.js new file mode 100644 index 000000000000..a6d6a8ff590e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/until/leap-second.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.until +description: Leap second is a valid ISO string for PlainTime +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainTime(23, 59, 59); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.until(arg); +TemporalHelpers.assertDuration( + result1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "leap second is a valid ISO string for PlainTime" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.until(arg); +TemporalHelpers.assertDuration( + result2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "second: 60 is ignored in property bag for PlainTime" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/until/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/until/options-wrong-type.js new file mode 100644 index 000000000000..5de14405642e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/until/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.until +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.PlainTime(); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.until(new Temporal.PlainTime(12, 34, 56), value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/until/plaintime-propertybag-no-time-units.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/until/plaintime-propertybag-no-time-units.js new file mode 100644 index 000000000000..c23221629a8f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/until/plaintime-propertybag-no-time-units.js @@ -0,0 +1,21 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.until +description: Missing time units in property bag default to 0 +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainTime(1, 0, 0, 0, 0, 1); + +const props = {}; +assert.throws(TypeError, () => instance.until(props), "TypeError if no properties are present"); + +props.minute = 30; +const result = instance.until(props); +TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, -30, 0, 0, 0, -1, "missing time units default to 0"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/until/smallestunit-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/until/smallestunit-invalid-string.js index 678c111d5426..0de577d40402 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/until/smallestunit-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/until/smallestunit-invalid-string.js @@ -10,9 +10,30 @@ features: [Temporal] const earlier = new Temporal.PlainTime(12, 34, 56, 0, 0, 0); const later = new Temporal.PlainTime(13, 35, 57, 987, 654, 321); -const values = ["era", "eraYear", "years", "months", "weeks", "days", "other string"]; -for (const smallestUnit of values) { - assert.throws(RangeError, () => earlier.until(later, { smallestUnit })); +const badValues = [ + "era", + "eraYear", + "year", + "month", + "week", + "day", + "millisecond\0", + "mill\u0131second", + "SECOND", + "eras", + "eraYears", + "years", + "months", + "weeks", + "days", + "milliseconds\0", + "mill\u0131seconds", + "SECONDS", + "other string", +]; +for (const smallestUnit of badValues) { + assert.throws(RangeError, () => earlier.until(later, { smallestUnit }), + `"${smallestUnit}" is not a valid value for smallest unit`); } reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/until/year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/until/year-zero.js index 81869181aed2..fbe1c448a028 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/until/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/until/year-zero.js @@ -9,8 +9,9 @@ features: [Temporal, arrow-function] ---*/ const invalidStrings = [ - '-000000-12-07T03:24:30', - '-000000-12-07T03:24:30+01:00[UTC]' + "-000000-12-07T03:24:30", + "-000000-12-07T03:24:30+01:00", + "-000000-12-07T03:24:30+00:00[UTC]", ]; const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321); invalidStrings.forEach((arg) => { diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/with/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/with/options-wrong-type.js new file mode 100644 index 000000000000..335f39ac87a8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/prototype/with/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaintime.prototype.with +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.PlainTime(); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.with({ minute: 45 }, value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainTime/shell.js b/js/src/tests/test262/built-ins/Temporal/PlainTime/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainTime/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainTime/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/calendar-number.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/calendar-number.js new file mode 100644 index 000000000000..0a278d06cb8a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/calendar-number.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth +description: A number is converted to a string, then to Temporal.Calendar +features: [Temporal] +---*/ + +const arg = 19761118; + +const result = new Temporal.PlainYearMonth(2000, 5, arg, 1); +assert.sameValue(result.calendar.id, "iso8601", "19761118 is a valid ISO string for Calendar"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => new Temporal.PlainYearMonth(2000, 5, arg, 1), + `Number ${arg} does not convert to a valid ISO string for Calendar` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/calendar-wrong-type.js new file mode 100644 index 000000000000..fe60b097db10 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/calendar-wrong-type.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for Calendar +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => new Temporal.PlainYearMonth(2000, 5, arg, 1), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => new Temporal.PlainYearMonth(2000, 5, arg, 1), `${description} is not a valid object and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/compare/argument-number.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/compare/argument-number.js new file mode 100644 index 000000000000..1feffce17367 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/compare/argument-number.js @@ -0,0 +1,37 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.compare +description: A number is converted to a string, then to Temporal.PlainYearMonth +features: [Temporal] +---*/ + +const arg = 201906; + +const result1 = Temporal.PlainYearMonth.compare(arg, new Temporal.PlainYearMonth(2019, 6)); +assert.sameValue(result1, 0, "201906 is a valid ISO string for PlainYearMonth (first argument)"); +const result2 = Temporal.PlainYearMonth.compare(new Temporal.PlainYearMonth(2019, 6), arg); +assert.sameValue(result2, 0, "201906 is a valid ISO string for PlainYearMonth (second argument)"); + +const numbers = [ + 1, + -201906, + 1234567, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => Temporal.PlainYearMonth.compare(arg, new Temporal.PlainYearMonth(2019, 6)), + `Number ${arg} does not convert to a valid ISO string for PlainYearMonth (first argument)` + ); + assert.throws( + RangeError, + () => Temporal.PlainYearMonth.compare(new Temporal.PlainYearMonth(2019, 6), arg), + `Number ${arg} does not convert to a valid ISO string for PlainYearMonth (first argument)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/compare/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/compare/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..a7a6b8923d06 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/compare/argument-propertybag-calendar-number.js @@ -0,0 +1,56 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.compare +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const calendar = 19970327; + +let arg = { year: 2019, monthCode: "M06", calendar }; +const result1 = Temporal.PlainYearMonth.compare(arg, new Temporal.PlainYearMonth(2019, 6)); +assert.sameValue(result1, 0, "19970327 is a valid ISO string for calendar (first argument)"); +const result2 = Temporal.PlainYearMonth.compare(new Temporal.PlainYearMonth(2019, 6), arg); +assert.sameValue(result2, 0, "19970327 is a valid ISO string for calendar (second argument)"); + +arg = { year: 2019, monthCode: "M06", calendar: { calendar } }; +const result3 = Temporal.PlainYearMonth.compare(arg, new Temporal.PlainYearMonth(2019, 6)); +assert.sameValue(result3, 0, "19970327 is a valid ISO string for calendar (nested property, first argument)"); +const result4 = Temporal.PlainYearMonth.compare(new Temporal.PlainYearMonth(2019, 6), arg); +assert.sameValue(result4, 0, "19970327 is a valid ISO string for calendar (nested property, second argument)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 2019, monthCode: "M06", calendar }; + assert.throws( + RangeError, + () => Temporal.PlainYearMonth.compare(arg, new Temporal.PlainYearMonth(2019, 6)), + `Number ${calendar} does not convert to a valid ISO string for calendar (first argument)` + ); + assert.throws( + RangeError, + () => Temporal.PlainYearMonth.compare(new Temporal.PlainYearMonth(2019, 6), arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (second argument)` + ); + arg = { year: 2019, monthCode: "M06", calendar: { calendar } }; + assert.throws( + RangeError, + () => Temporal.PlainYearMonth.compare(arg, new Temporal.PlainYearMonth(2019, 6)), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property, first argument)` + ); + assert.throws( + RangeError, + () => Temporal.PlainYearMonth.compare(new Temporal.PlainYearMonth(2019, 6), arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property, second argument)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/compare/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/compare/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..fd21315daa5f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/compare/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,52 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.compare +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => Temporal.PlainYearMonth.compare(arg, new Temporal.PlainYearMonth(2019, 6)), `${description} does not convert to a valid ISO string (first argument)`); + assert.throws(RangeError, () => Temporal.PlainYearMonth.compare(new Temporal.PlainYearMonth(2019, 6), arg), `${description} does not convert to a valid ISO string (second argument)`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => Temporal.PlainYearMonth.compare(arg, new Temporal.PlainYearMonth(2019, 6)), `${description} does not convert to a valid ISO string (nested property, first argument)`); + assert.throws(RangeError, () => Temporal.PlainYearMonth.compare(new Temporal.PlainYearMonth(2019, 6), arg), `${description} does not convert to a valid ISO string (nested property, second argument)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => Temporal.PlainYearMonth.compare(arg, new Temporal.PlainYearMonth(2019, 6)), `${description} is not a valid property bag and does not convert to a string (first argument)`); + assert.throws(TypeError, () => Temporal.PlainYearMonth.compare(new Temporal.PlainYearMonth(2019, 6), arg), `${description} is not a valid property bag and does not convert to a string (second argument)`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => Temporal.PlainYearMonth.compare(arg, new Temporal.PlainYearMonth(2019, 6)), `${description} is not a valid property bag and does not convert to a string (nested property, first argument)`); + assert.throws(TypeError, () => Temporal.PlainYearMonth.compare(new Temporal.PlainYearMonth(2019, 6), arg), `${description} is not a valid property bag and does not convert to a string (nested property, second argument)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => Temporal.PlainYearMonth.compare(arg, new Temporal.PlainYearMonth(2019, 6)), `nested undefined calendar property is always a RangeError (first argument)`); +assert.throws(RangeError, () => Temporal.PlainYearMonth.compare(new Temporal.PlainYearMonth(2019, 6), arg), `nested undefined calendar property is always a RangeError (second argument)`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/compare/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/compare/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..4d8ddccfc772 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/compare/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.compare +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; + +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => Temporal.PlainYearMonth.compare(arg, new Temporal.PlainYearMonth(2019, 6)), + "reject minus zero as extended year (first argument)" + ); + assert.throws( + RangeError, + () => Temporal.PlainYearMonth.compare(new Temporal.PlainYearMonth(2019, 6), arg), + "reject minus zero as extended year (second argument)" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/compare/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/compare/argument-wrong-type.js new file mode 100644 index 000000000000..bdf45abddb0c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/compare/argument-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.compare +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainYearMonth +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => Temporal.PlainYearMonth.compare(arg, new Temporal.PlainYearMonth(2019, 6)), `${description} does not convert to a valid ISO string (first argument)`); + assert.throws(RangeError, () => Temporal.PlainYearMonth.compare(new Temporal.PlainYearMonth(2019, 6), arg), `${description} does not convert to a valid ISO string (second argument)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainYearMonth, "Temporal.PlainYearMonth, object"], + [Temporal.PlainYearMonth.prototype, "Temporal.PlainYearMonth.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => Temporal.PlainYearMonth.compare(arg, new Temporal.PlainYearMonth(2019, 6)), `${description} is not a valid property bag and does not convert to a string (first argument)`); + assert.throws(TypeError, () => Temporal.PlainYearMonth.compare(new Temporal.PlainYearMonth(2019, 6), arg), `${description} is not a valid property bag and does not convert to a string (second argument)`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/compare/leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/compare/leap-second.js new file mode 100644 index 000000000000..60be61c84b4e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/compare/leap-second.js @@ -0,0 +1,25 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.compare +description: Leap second is a valid ISO string for PlainYearMonth +features: [Temporal] +---*/ + +let arg = "2016-12-31T23:59:60"; + +const result1 = Temporal.PlainYearMonth.compare(arg, new Temporal.PlainYearMonth(2016, 12)); +assert.sameValue(result1, 0, "leap second is a valid ISO string for PlainYearMonth (first argument)"); +const result2 = Temporal.PlainYearMonth.compare(new Temporal.PlainYearMonth(2016, 12), arg); +assert.sameValue(result2, 0, "leap second is a valid ISO string for PlainYearMonth (second argument)"); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; + +const result3 = Temporal.PlainYearMonth.compare(arg, new Temporal.PlainYearMonth(2016, 12)); +assert.sameValue(result3, 0, "second: 60 is ignored in property bag for PlainYearMonth (first argument)"); +const result4 = Temporal.PlainYearMonth.compare(new Temporal.PlainYearMonth(2016, 12), arg); +assert.sameValue(result4, 0, "second: 60 is ignored in property bag for PlainYearMonth (second argument)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/compare/year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/compare/year-zero.js index 9876c58652b6..8a2aec3fa18d 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/compare/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/compare/year-zero.js @@ -9,18 +9,26 @@ features: [Temporal] ---*/ const ok = new Temporal.PlainYearMonth(2000, 5); -const bad = "-000000-06"; +const invalidStrings = [ + "-000000-06", + "-000000-06-24", + "-000000-06-24T15:43:27", + "-000000-06-24T15:43:27+01:00", + "-000000-06-24T15:43:27+00:00[UTC]", +]; -assert.throws( - RangeError, - () => Temporal.PlainYearMonth.compare(bad, ok), - "Cannot use minus zero as extended year (first argument)" -); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => Temporal.PlainYearMonth.compare(arg, ok), + "Cannot use minus zero as extended year (first argument)" + ); -assert.throws( - RangeError, - () => Temporal.PlainYearMonth.compare(ok, bad), - "Cannot use minus zero as extended year (second argument)" -); + assert.throws( + RangeError, + () => Temporal.PlainYearMonth.compare(ok, arg), + "Cannot use minus zero as extended year (second argument)" + ); +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/from/argument-number.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/from/argument-number.js index 769f34754bc1..75a8c8c26562 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/from/argument-number.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/from/argument-number.js @@ -4,17 +4,28 @@ /*--- esid: sec-temporal.plainyearmonth.from -description: A number argument is stringified +description: A number is converted to a string, then to Temporal.PlainYearMonth includes: [temporalHelpers.js] features: [Temporal] ---*/ -const plainYearMonth = Temporal.PlainYearMonth.from(201906); -TemporalHelpers.assertPlainYearMonth(plainYearMonth, 2019, 6, "M06"); -const fields = plainYearMonth.getISOFields(); -assert.sameValue(fields.calendar.id, "iso8601"); -assert.sameValue(fields.isoDay, 1, "isoDay"); -assert.sameValue(fields.isoMonth, 6, "isoMonth"); -assert.sameValue(fields.isoYear, 2019, "isoYear"); +const arg = 201906; + +const result = Temporal.PlainYearMonth.from(arg); +TemporalHelpers.assertPlainYearMonth(result, 2019, 6, "M06", "201906 is a valid ISO string for PlainYearMonth"); + +const numbers = [ + 1, + -201906, + 1234567, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => Temporal.PlainYearMonth.from(arg), + `Number ${arg} does not convert to a valid ISO string for PlainYearMonth` + ); +} reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/from/argument-plainyearmonth.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/from/argument-plainyearmonth.js index b3ca9a967afe..c40348905446 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/from/argument-plainyearmonth.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/from/argument-plainyearmonth.js @@ -4,22 +4,25 @@ /*--- esid: sec-temporal.plainyearmonth.from -description: A PlainYearMonth argument is cloned +description: A PlainYearMonth object is copied, not returned directly includes: [temporalHelpers.js] features: [Temporal] ---*/ -const original = new Temporal.PlainYearMonth(2019, 11, undefined, 7); -const result = Temporal.PlainYearMonth.from(original); -assert.notSameValue(result, original); +const orig = new Temporal.PlainYearMonth(2000, 5, undefined, 7); +const result = Temporal.PlainYearMonth.from(orig); -for (const plainYearMonth of [original, result]) { - TemporalHelpers.assertPlainYearMonth(plainYearMonth, 2019, 11, "M11"); - const fields = plainYearMonth.getISOFields(); - assert.sameValue(fields.calendar.id, "iso8601"); - assert.sameValue(fields.isoDay, 7, "isoDay"); - assert.sameValue(fields.isoMonth, 11, "isoMonth"); - assert.sameValue(fields.isoYear, 2019, "isoYear"); -} +TemporalHelpers.assertPlainYearMonth( + result, + 2000, 5, "M05", + "PlainYearMonth is copied", + /* era = */ undefined, /* eraYear = */ undefined, /* isoDay = */ 7 +); + +assert.notSameValue( + result, + orig, + "When a PlainYearMonth is given, the returned value is not the original PlainYearMonth" +); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..d30f164b01ef --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.from +description: Leap second is a valid ISO string for a calendar in a property bag +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 2019, monthCode: "M06", calendar }; +const result1 = Temporal.PlainYearMonth.from(arg); +TemporalHelpers.assertPlainYearMonth( + result1, + 2019, 6, "M06", + "leap second is a valid ISO string for calendar" +); + +arg = { year: 2019, monthCode: "M06", calendar: { calendar } }; +const result2 = Temporal.PlainYearMonth.from(arg); +TemporalHelpers.assertPlainYearMonth( + result2, + 2019, 6, "M06", + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..1bdba2f6f501 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-number.js @@ -0,0 +1,43 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.from +description: A number as calendar in a property bag is converted to a string, then to a calendar +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = 19970327; + +let arg = { year: 2019, monthCode: "M06", calendar }; +const result1 = Temporal.PlainYearMonth.from(arg); +TemporalHelpers.assertPlainYearMonth(result1, 2019, 6, "M06", "19970327 is a valid ISO string for calendar"); + +arg = { year: 2019, monthCode: "M06", calendar: { calendar } }; +const result2 = Temporal.PlainYearMonth.from(arg); +TemporalHelpers.assertPlainYearMonth(result2, 2019, 6, "M06", "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 2019, monthCode: "M06", calendar }; + assert.throws( + RangeError, + () => Temporal.PlainYearMonth.from(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { year: 2019, monthCode: "M06", calendar: { calendar } }; + assert.throws( + RangeError, + () => Temporal.PlainYearMonth.from(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..264418a98a1c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,47 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.from +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => Temporal.PlainYearMonth.from(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => Temporal.PlainYearMonth.from(arg), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => Temporal.PlainYearMonth.from(arg), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => Temporal.PlainYearMonth.from(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => Temporal.PlainYearMonth.from(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..81baa9c96385 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/from/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.from +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; + +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => Temporal.PlainYearMonth.from(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/from/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/from/argument-wrong-type.js new file mode 100644 index 000000000000..82bd74b73e9a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/from/argument-wrong-type.js @@ -0,0 +1,37 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.from +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainYearMonth +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => Temporal.PlainYearMonth.from(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainYearMonth, "Temporal.PlainYearMonth, object"], + [Temporal.PlainYearMonth.prototype, "Temporal.PlainYearMonth.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => Temporal.PlainYearMonth.from(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/from/leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/from/leap-second.js new file mode 100644 index 000000000000..c89348c4dbac --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/from/leap-second.js @@ -0,0 +1,44 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.from +description: Leap second is a valid ISO string for PlainYearMonth +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +let arg = "2016-12-31T23:59:60"; + +const result1 = Temporal.PlainYearMonth.from(arg); +TemporalHelpers.assertPlainYearMonth( + result1, + 2016, 12, "M12", + "leap second is a valid ISO string for PlainYearMonth" +); + +const result2 = Temporal.PlainYearMonth.from(arg, { overflow: "reject" }); +TemporalHelpers.assertPlainYearMonth( + result2, + 2016, 12, "M12", + "leap second is a valid ISO string for PlainYearMonth" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; + +const result3 = Temporal.PlainYearMonth.from(arg); +TemporalHelpers.assertPlainYearMonth( + result3, + 2016, 12, "M12", + "second: 60 is ignored in property bag for PlainYearMonth" +); + +const result4 = Temporal.PlainYearMonth.from(arg, { overflow: "reject" }); +TemporalHelpers.assertPlainYearMonth( + result4, + 2016, 12, "M12", + "second: 60 is ignored in property bag for PlainYearMonth even with overflow: reject" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/from/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/from/options-wrong-type.js new file mode 100644 index 000000000000..81cc39b44863 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/from/options-wrong-type.js @@ -0,0 +1,25 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.from +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +for (const value of badOptions) { + assert.throws(TypeError, () => Temporal.PlainYearMonth.from({ year: 2021, monthCode: "M01" }, value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/from/year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/from/year-zero.js index 0340e5112b5f..8274e90adfea 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/from/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/from/year-zero.js @@ -9,15 +9,17 @@ features: [Temporal, arrow-function] ---*/ const invalidStrings = [ - '-000000-06', - '-000000-06-24', - '-000000-06-24T15:43:27', - '-000000-06-24T15:43:27+01:00[UTC]' + "-000000-06", + "-000000-06-24", + "-000000-06-24T15:43:27", + "-000000-06-24T15:43:27+01:00", + "-000000-06-24T15:43:27+00:00[UTC]", ]; + invalidStrings.forEach((arg) => { assert.throws( RangeError, - () => { Temporal.PlainYearMonth.from(arg); }, + () => Temporal.PlainYearMonth.from(arg), "reject minus zero as extended year" ); }); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/limits.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/limits.js index 38a4debbf03c..e946f11414dd 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/limits.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/limits.js @@ -14,10 +14,12 @@ assert.throws(RangeError, () => new Temporal.PlainYearMonth(275760, 10), "max"); TemporalHelpers.assertPlainYearMonth(new Temporal.PlainYearMonth(-271821, 4), -271821, 4, "M04", "min"); TemporalHelpers.assertPlainYearMonth(new Temporal.PlainYearMonth(-271821, 4, "iso8601", 18), - -271821, 4, "M04", "min with referenceISODay"); + -271821, 4, "M04", "min with referenceISODay", + /* era = */ undefined, /* eraYear = */ undefined, /* referenceISODay = */ 18); TemporalHelpers.assertPlainYearMonth(new Temporal.PlainYearMonth(275760, 9), 275760, 9, "M09", "max"); TemporalHelpers.assertPlainYearMonth(new Temporal.PlainYearMonth(275760, 9, "iso8601", 14), - 275760, 9, "M09", "max with referenceISODay"); + 275760, 9, "M09", "max with referenceISODay", + /* era = */ undefined, /* eraYear = */ undefined, /* referenceISODay = */ 14); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/add/calendar-datefromfields-called.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/add/calendar-datefromfields-called.js index 0fbbd944e937..a652bfff2268 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/add/calendar-datefromfields-called.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/add/calendar-datefromfields-called.js @@ -91,11 +91,17 @@ const month2 = Temporal.PlainYearMonth.from({ year: 2022, month: 2, calendar }); const lessThanOneMonth = new Temporal.Duration(0, 0, 0, 35); const oneMonth = new Temporal.Duration(0, 0, 0, 36); +// Reference ISO dates in the custom calendar: +// M01 = 01-01 +// M02 = 02-06 +// M03 = 03-14 + calendar.dateFromFieldsCalls = []; TemporalHelpers.assertPlainYearMonth( month2.add(lessThanOneMonth), 2022, 2, "M02", - "adding positive less than one month's worth of days yields the same month" + "adding positive less than one month's worth of days yields the same month", + /* era = */ undefined, /* eraYear = */ undefined, /* referenceISODay = */ 6 ); assert.sameValue(calendar.dateFromFieldsCalls.length, 1, "dateFromFields was called"); assert.deepEqual( @@ -109,7 +115,8 @@ calendar.dateFromFieldsCalls = []; TemporalHelpers.assertPlainYearMonth( month2.add(oneMonth), 2022, 3, "M03", - "adding positive one month's worth of days yields the following month" + "adding positive one month's worth of days yields the following month", + /* era = */ undefined, /* eraYear = */ undefined, /* referenceISODay = */ 14 ); assert.sameValue(calendar.dateFromFieldsCalls.length, 1, "dateFromFields was called"); assert.deepEqual( @@ -123,7 +130,8 @@ calendar.dateFromFieldsCalls = []; TemporalHelpers.assertPlainYearMonth( month2.add(lessThanOneMonth.negated()), 2022, 2, "M02", - "adding negative less than one month's worth of days yields the same month" + "adding negative less than one month's worth of days yields the same month", + /* era = */ undefined, /* eraYear = */ undefined, /* referenceISODay = */ 6 ); assert.sameValue(calendar.dateFromFieldsCalls.length, 1, "dateFromFields was called"); assert.deepEqual( @@ -137,7 +145,8 @@ calendar.dateFromFieldsCalls = []; TemporalHelpers.assertPlainYearMonth( month2.add(oneMonth.negated()), 2022, 1, "M01", - "adding negative one month's worth of days yields the previous month" + "adding negative one month's worth of days yields the previous month", + /* era = */ undefined, /* eraYear = */ undefined, /* referenceISODay = */ 1 ); assert.sameValue(calendar.dateFromFieldsCalls.length, 1, "dateFromFields was called"); assert.deepEqual( diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/add/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/add/options-wrong-type.js new file mode 100644 index 000000000000..29902d5ba828 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/add/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.add +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.PlainYearMonth(2019, 10); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.add({ months: 1 }, value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-number.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-number.js new file mode 100644 index 000000000000..0ede6c754bfd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-number.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.equals +description: A number is converted to a string, then to Temporal.PlainYearMonth +features: [Temporal] +---*/ + +const instance = new Temporal.PlainYearMonth(2019, 6); + +const arg = 201906; + +const result = instance.equals(arg); +assert.sameValue(result, true, "201906 is a valid ISO string for PlainYearMonth"); + +const numbers = [ + 1, + -201906, + 1234567, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.equals(arg), + `Number ${arg} does not convert to a valid ISO string for PlainYearMonth` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..d103a599a277 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,31 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.equals +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const instance = new Temporal.PlainYearMonth(2019, 6); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 2019, monthCode: "M06", calendar }; +const result1 = instance.equals(arg); +assert.sameValue( + result1, + true, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 2019, monthCode: "M06", calendar: { calendar } }; +const result2 = instance.equals(arg); +assert.sameValue( + result2, + true, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..4f563dab67f6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-number.js @@ -0,0 +1,44 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.equals +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const instance = new Temporal.PlainYearMonth(2019, 6); + +const calendar = 19970327; + +let arg = { year: 2019, monthCode: "M06", calendar }; +const result1 = instance.equals(arg); +assert.sameValue(result1, true, "19970327 is a valid ISO string for calendar"); + +arg = { year: 2019, monthCode: "M06", calendar: { calendar } }; +const result2 = instance.equals(arg); +assert.sameValue(result2, true, "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 2019, monthCode: "M06", calendar }; + assert.throws( + RangeError, + () => instance.equals(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { year: 2019, monthCode: "M06", calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.equals(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..69be41f208f3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.equals +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.PlainYearMonth(2000, 5); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.equals(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.equals(arg), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.equals(arg), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.equals(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.equals(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..7e107e660fd3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.equals +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.PlainYearMonth(2000, 5); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.equals(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-wrong-type.js index 7697a73a8080..c9f3308e7f34 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-wrong-type.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/equals/argument-wrong-type.js @@ -1,23 +1,39 @@ // |reftest| skip -- Temporal is not supported -// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// Copyright (C) 2022 Igalia, S.L. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. /*--- esid: sec-temporal.plainyearmonth.prototype.equals -description: Appropriate error thrown when argument cannot be converted to a valid string -features: [Symbol, Temporal] +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainYearMonth +features: [BigInt, Symbol, Temporal] ---*/ -const instance = Temporal.PlainYearMonth.from({ year: 2000, month: 5, day: 2 }); +const instance = new Temporal.PlainYearMonth(2000, 5); -assert.throws(RangeError, () => instance.equals(undefined), "undefined"); -assert.throws(RangeError, () => instance.equals(null), "null"); -assert.throws(RangeError, () => instance.equals(true), "true"); -assert.throws(RangeError, () => instance.equals(""), "empty string"); -assert.throws(TypeError, () => instance.equals(Symbol()), "symbol"); -assert.throws(RangeError, () => instance.equals(1), "1"); -assert.throws(TypeError, () => instance.equals({}), "plain object"); -assert.throws(TypeError, () => instance.equals(Temporal.PlainYearMonth), "Temporal.PlainYearMonth"); -assert.throws(TypeError, () => instance.equals(Temporal.PlainYearMonth.prototype), "Temporal.PlainYearMonth.prototype"); +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.equals(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainYearMonth, "Temporal.PlainYearMonth, object"], + [Temporal.PlainYearMonth.prototype, "Temporal.PlainYearMonth.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.equals(arg), `${description} is not a valid property bag and does not convert to a string`); +} reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/equals/leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/equals/leap-second.js new file mode 100644 index 000000000000..49f07f02733b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/equals/leap-second.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.equals +description: Leap second is a valid ISO string for PlainYearMonth +features: [Temporal] +---*/ + +const instance = new Temporal.PlainYearMonth(2016, 12); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.equals(arg); +assert.sameValue( + result1, + true, + "leap second is a valid ISO string for PlainYearMonth" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.equals(arg); +assert.sameValue( + result2, + true, + "second: 60 is ignored in property bag for PlainYearMonth" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/equals/year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/equals/year-zero.js index 633cac19a960..e80171c4c9f6 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/equals/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/equals/year-zero.js @@ -4,15 +4,16 @@ /*--- esid: sec-temporal.plainyearmonth.prototype.equals -description: RangeError thrown if a string with UTC designator is used as a PlainYearMonth +description: Negative zero, as an extended year, is rejected features: [Temporal, arrow-function] ---*/ const invalidStrings = [ - '-000000-06', - '-000000-06-24', - '-000000-06-24T15:43:27', - '-000000-06-24T15:43:27+01:00[UTC]' + "-000000-06", + "-000000-06-24", + "-000000-06-24T15:43:27", + "-000000-06-24T15:43:27+01:00", + "-000000-06-24T15:43:27+00:00[UTC]", ]; const instance = new Temporal.PlainYearMonth(2000, 5); invalidStrings.forEach((arg) => { diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/since/argument-number.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/since/argument-number.js new file mode 100644 index 000000000000..02c5ff64b880 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/since/argument-number.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.since +description: A number is converted to a string, then to Temporal.PlainYearMonth +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainYearMonth(2019, 6); + +const arg = 201906; + +const result = instance.since(arg); +TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "201906 is a valid ISO string for PlainYearMonth"); + +const numbers = [ + 1, + -201906, + 1234567, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.since(arg), + `Number ${arg} does not convert to a valid ISO string for PlainYearMonth` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..8463768d7829 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.since +description: Leap second is a valid ISO string for a calendar in a property bag +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainYearMonth(2019, 6); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 2019, monthCode: "M06", calendar }; +const result1 = instance.since(arg); +TemporalHelpers.assertDuration( + result1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 2019, monthCode: "M06", calendar: { calendar } }; +const result2 = instance.since(arg); +TemporalHelpers.assertDuration( + result2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..eaeb1e7b5057 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-number.js @@ -0,0 +1,45 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.since +description: A number as calendar in a property bag is converted to a string, then to a calendar +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainYearMonth(2019, 6); + +const calendar = 19970327; + +let arg = { year: 2019, monthCode: "M06", calendar }; +const result1 = instance.since(arg); +TemporalHelpers.assertDuration(result1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar"); + +arg = { year: 2019, monthCode: "M06", calendar: { calendar } }; +const result2 = instance.since(arg); +TemporalHelpers.assertDuration(result2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 2019, monthCode: "M06", calendar }; + assert.throws( + RangeError, + () => instance.since(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { year: 2019, monthCode: "M06", calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.since(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..9cbf7f9ae237 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.since +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.PlainYearMonth(2000, 5); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.since(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.since(arg), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.since(arg), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.since(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.since(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..9a62ea65eb38 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/since/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.since +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.PlainYearMonth(2000, 5); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.since(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/since/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/since/argument-wrong-type.js new file mode 100644 index 000000000000..5d857d3a8dc1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/since/argument-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.since +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainYearMonth +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.PlainYearMonth(2000, 5); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.since(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainYearMonth, "Temporal.PlainYearMonth, object"], + [Temporal.PlainYearMonth.prototype, "Temporal.PlainYearMonth.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.since(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/since/largestunit-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/since/largestunit-invalid-string.js index f98aa5e66e25..84416b340637 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/since/largestunit-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/since/largestunit-invalid-string.js @@ -10,9 +10,36 @@ features: [Temporal] const earlier = new Temporal.PlainYearMonth(2000, 5); const later = new Temporal.PlainYearMonth(2001, 6); -const values = ["era", "eraYear", "weeks", "days", "hours", "minutes", "seconds", "milliseconds", "microseconds", "nanoseconds", "other string"]; -for (const largestUnit of values) { - assert.throws(RangeError, () => later.since(earlier, { largestUnit })); +const badValues = [ + "era", + "eraYear", + "week", + "day", + "hour", + "minute", + "second", + "millisecond", + "microsecond", + "nanosecond", + "month\0", + "YEAR", + "eras", + "eraYears", + "weeks", + "days", + "hours", + "minutes", + "seconds", + "milliseconds", + "microseconds", + "nanoseconds", + "months\0", + "YEARS", + "other string" +]; +for (const largestUnit of badValues) { + assert.throws(RangeError, () => later.since(earlier, { largestUnit }), + `"${largestUnit}" is not a valid value for largestUnit`); } reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/since/leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/since/leap-second.js new file mode 100644 index 000000000000..7b8c5fa52b88 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/since/leap-second.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.since +description: Leap second is a valid ISO string for PlainYearMonth +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainYearMonth(2016, 12); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.since(arg); +TemporalHelpers.assertDuration( + result1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "leap second is a valid ISO string for PlainYearMonth" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.since(arg); +TemporalHelpers.assertDuration( + result2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "second: 60 is ignored in property bag for PlainYearMonth" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/since/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/since/options-wrong-type.js new file mode 100644 index 000000000000..6088cccc8021 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/since/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.since +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.PlainYearMonth(2019, 10); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.since(new Temporal.PlainYearMonth(1976, 11), value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/since/smallestunit-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/since/smallestunit-invalid-string.js index c49cdb86546a..132c399f22a5 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/since/smallestunit-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/since/smallestunit-invalid-string.js @@ -10,9 +10,36 @@ features: [Temporal] const earlier = new Temporal.PlainYearMonth(2000, 5); const later = new Temporal.PlainYearMonth(2001, 6); -const values = ["era", "eraYear", "weeks", "days", "hours", "minutes", "seconds", "milliseconds", "microseconds", "nanoseconds", "other string"]; -for (const smallestUnit of values) { - assert.throws(RangeError, () => later.since(earlier, { smallestUnit })); +const badValues = [ + "era", + "eraYear", + "week", + "day", + "hour", + "minute", + "second", + "millisecond", + "microsecond", + "nanosecond", + "month\0", + "YEAR", + "eras", + "eraYears", + "weeks", + "days", + "hours", + "minutes", + "seconds", + "milliseconds", + "microseconds", + "nanoseconds", + "months\0", + "YEARS", + "other string", +]; +for (const smallestUnit of badValues) { + assert.throws(RangeError, () => later.since(earlier, { smallestUnit }), + `"${smallestUnit}" is not a valid value for smallest unit`); } reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/since/year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/since/year-zero.js index 67ddd452c278..c6ac16e6f983 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/since/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/since/year-zero.js @@ -4,15 +4,16 @@ /*--- esid: sec-temporal.plainyearmonth.prototype.since -description: RangeError thrown if a string with UTC designator is used as a PlainYearMonth +description: Negative zero, as an extended year, is rejected features: [Temporal, arrow-function] ---*/ const invalidStrings = [ - '-000000-06', - '-000000-06-24', - '-000000-06-24T15:43:27', - '-000000-06-24T15:43:27+01:00[UTC]' + "-000000-06", + "-000000-06-24", + "-000000-06-24T15:43:27", + "-000000-06-24T15:43:27+01:00", + "-000000-06-24T15:43:27+00:00[UTC]", ]; const instance = new Temporal.PlainYearMonth(2000, 5); invalidStrings.forEach((arg) => { diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-datefromfields-called.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-datefromfields-called.js index 633a2c42e74a..afe9a3a2350b 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-datefromfields-called.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-datefromfields-called.js @@ -91,11 +91,17 @@ const month2 = Temporal.PlainYearMonth.from({ year: 2022, month: 2, calendar }); const lessThanOneMonth = new Temporal.Duration(0, 0, 0, 35); const oneMonth = new Temporal.Duration(0, 0, 0, 36); +// Reference ISO dates in the custom calendar: +// M01 = 01-01 +// M02 = 02-06 +// M03 = 03-14 + calendar.dateFromFieldsCalls = []; TemporalHelpers.assertPlainYearMonth( month2.subtract(lessThanOneMonth), 2022, 2, "M02", - "subtracting positive less than one month's worth of days yields the same month" + "subtracting positive less than one month's worth of days yields the same month", + /* era = */ undefined, /* eraYear = */ undefined, /* referenceISODay = */ 6 ); assert.sameValue(calendar.dateFromFieldsCalls.length, 1, "dateFromFields was called"); assert.deepEqual( @@ -109,7 +115,8 @@ calendar.dateFromFieldsCalls = []; TemporalHelpers.assertPlainYearMonth( month2.subtract(oneMonth), 2022, 1, "M01", - "subtracting positive one month's worth of days yields the previous month" + "subtracting positive one month's worth of days yields the previous month", + /* era = */ undefined, /* eraYear = */ undefined, /* referenceISODay = */ 1 ); assert.sameValue(calendar.dateFromFieldsCalls.length, 1, "dateFromFields was called"); assert.deepEqual( @@ -123,7 +130,8 @@ calendar.dateFromFieldsCalls = []; TemporalHelpers.assertPlainYearMonth( month2.subtract(lessThanOneMonth.negated()), 2022, 2, "M02", - "subtracting negative less than one month's worth of days yields the same month" + "subtracting negative less than one month's worth of days yields the same month", + /* era = */ undefined, /* eraYear = */ undefined, /* referenceISODay = */ 6 ); assert.sameValue(calendar.dateFromFieldsCalls.length, 1, "dateFromFields was called"); assert.deepEqual( @@ -137,7 +145,8 @@ calendar.dateFromFieldsCalls = []; TemporalHelpers.assertPlainYearMonth( month2.subtract(oneMonth.negated()), 2022, 3, "M03", - "subtracting negative one month's worth of days yields the following month" + "subtracting negative one month's worth of days yields the following month", + /* era = */ undefined, /* eraYear = */ undefined, /* referenceISODay = */ 14 ); assert.sameValue(calendar.dateFromFieldsCalls.length, 1, "dateFromFields was called"); assert.deepEqual( diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/subtract/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/subtract/options-wrong-type.js new file mode 100644 index 000000000000..ace9167838a3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/subtract/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.subtract +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.PlainYearMonth(2019, 10); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.subtract({ months: 1 }, value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/toString/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/toString/options-wrong-type.js new file mode 100644 index 000000000000..517ffec298ba --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/toString/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.tostring +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.PlainYearMonth(2019, 10); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.toString(value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/until/argument-number.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/until/argument-number.js new file mode 100644 index 000000000000..cf617693fee5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/until/argument-number.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.until +description: A number is converted to a string, then to Temporal.PlainYearMonth +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainYearMonth(2019, 6); + +const arg = 201906; + +const result = instance.until(arg); +TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "201906 is a valid ISO string for PlainYearMonth"); + +const numbers = [ + 1, + -201906, + 1234567, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.until(arg), + `Number ${arg} does not convert to a valid ISO string for PlainYearMonth` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..b6267de789ee --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.until +description: Leap second is a valid ISO string for a calendar in a property bag +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainYearMonth(2019, 6); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 2019, monthCode: "M06", calendar }; +const result1 = instance.until(arg); +TemporalHelpers.assertDuration( + result1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 2019, monthCode: "M06", calendar: { calendar } }; +const result2 = instance.until(arg); +TemporalHelpers.assertDuration( + result2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..1575f71ca754 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-number.js @@ -0,0 +1,45 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.until +description: A number as calendar in a property bag is converted to a string, then to a calendar +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainYearMonth(2019, 6); + +const calendar = 19970327; + +let arg = { year: 2019, monthCode: "M06", calendar }; +const result1 = instance.until(arg); +TemporalHelpers.assertDuration(result1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar"); + +arg = { year: 2019, monthCode: "M06", calendar: { calendar } }; +const result2 = instance.until(arg); +TemporalHelpers.assertDuration(result2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 2019, monthCode: "M06", calendar }; + assert.throws( + RangeError, + () => instance.until(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { year: 2019, monthCode: "M06", calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.until(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..aa17a9ac67cd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.until +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.PlainYearMonth(2000, 5); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.until(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.until(arg), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.until(arg), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.until(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.until(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..4b2615962afa --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/until/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.until +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.PlainYearMonth(2000, 5); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.until(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/until/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/until/argument-wrong-type.js new file mode 100644 index 000000000000..101d8aaaa709 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/until/argument-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.until +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainYearMonth +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.PlainYearMonth(2000, 5); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.until(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainYearMonth, "Temporal.PlainYearMonth, object"], + [Temporal.PlainYearMonth.prototype, "Temporal.PlainYearMonth.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.until(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/until/largestunit-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/until/largestunit-invalid-string.js index 52fe3210f81b..93f42bf43eb4 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/until/largestunit-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/until/largestunit-invalid-string.js @@ -10,9 +10,36 @@ features: [Temporal] const earlier = new Temporal.PlainYearMonth(2000, 5); const later = new Temporal.PlainYearMonth(2001, 6); -const values = ["era", "eraYear", "weeks", "days", "hours", "minutes", "seconds", "milliseconds", "microseconds", "nanoseconds", "other string"]; -for (const largestUnit of values) { - assert.throws(RangeError, () => earlier.until(later, { largestUnit })); +const badValues = [ + "era", + "eraYear", + "week", + "day", + "hour", + "minute", + "second", + "millisecond", + "microsecond", + "nanosecond", + "month\0", + "YEAR", + "eras", + "eraYears", + "weeks", + "days", + "hours", + "minutes", + "seconds", + "milliseconds", + "microseconds", + "nanoseconds", + "months\0", + "YEARS", + "other string" +]; +for (const largestUnit of badValues) { + assert.throws(RangeError, () => earlier.until(later, { largestUnit }), + `"${largestUnit}" is not a valid value for largestUnit`); } reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/until/leap-second.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/until/leap-second.js new file mode 100644 index 000000000000..87fbb3495487 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/until/leap-second.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.until +description: Leap second is a valid ISO string for PlainYearMonth +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.PlainYearMonth(2016, 12); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.until(arg); +TemporalHelpers.assertDuration( + result1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "leap second is a valid ISO string for PlainYearMonth" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.until(arg); +TemporalHelpers.assertDuration( + result2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "second: 60 is ignored in property bag for PlainYearMonth" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/until/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/until/options-wrong-type.js new file mode 100644 index 000000000000..6a0282896c1b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/until/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.until +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.PlainYearMonth(2019, 10); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.until(new Temporal.PlainYearMonth(1976, 11), value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/until/smallestunit-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/until/smallestunit-invalid-string.js index ac515fe2d8a6..3c6cb32e44ff 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/until/smallestunit-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/until/smallestunit-invalid-string.js @@ -10,9 +10,36 @@ features: [Temporal] const earlier = new Temporal.PlainYearMonth(2000, 5); const later = new Temporal.PlainYearMonth(2001, 6); -const values = ["era", "eraYear", "weeks", "days", "hours", "minutes", "seconds", "milliseconds", "microseconds", "nanoseconds", "other string"]; -for (const smallestUnit of values) { - assert.throws(RangeError, () => earlier.until(later, { smallestUnit })); +const badValues = [ + "era", + "eraYear", + "week", + "day", + "hour", + "minute", + "second", + "millisecond", + "microsecond", + "nanosecond", + "month\0", + "YEAR", + "eras", + "eraYears", + "weeks", + "days", + "hours", + "minutes", + "seconds", + "milliseconds", + "microseconds", + "nanoseconds", + "months\0", + "YEARS", + "other string", +]; +for (const smallestUnit of badValues) { + assert.throws(RangeError, () => earlier.until(later, { smallestUnit }), + `"${smallestUnit}" is not a valid value for smallest unit`); } reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/until/year-zero.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/until/year-zero.js index 9f5efc266f6c..87518217485d 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/until/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/until/year-zero.js @@ -4,15 +4,16 @@ /*--- esid: sec-temporal.plainyearmonth.prototype.until -description: RangeError thrown if a string with UTC designator is used as a PlainYearMonth +description: Negative zero, as an extended year, is rejected features: [Temporal, arrow-function] ---*/ const invalidStrings = [ - '-000000-06', - '-000000-06-24', - '-000000-06-24T15:43:27', - '-000000-06-24T15:43:27+01:00[UTC]' + "-000000-06", + "-000000-06-24", + "-000000-06-24T15:43:27", + "-000000-06-24T15:43:27+01:00", + "-000000-06-24T15:43:27+00:00[UTC]", ]; const instance = new Temporal.PlainYearMonth(2000, 5); invalidStrings.forEach((arg) => { diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/with/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/with/options-wrong-type.js index 99a9e500641e..beffa15cc856 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/with/options-wrong-type.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/prototype/with/options-wrong-type.js @@ -8,7 +8,7 @@ description: TypeError thrown when options argument is a primitive features: [BigInt, Symbol, Temporal] ---*/ -const values = [ +const badOptions = [ null, true, "2021-01", @@ -17,9 +17,10 @@ const values = [ 2n, ]; -const ym = Temporal.PlainYearMonth.from("2019-10"); -values.forEach((value) => { - assert.throws(TypeError, () => ym.with({ year: 2020 }, value), `TypeError on wrong argument type ${typeof value}`); -}); +const instance = new Temporal.PlainYearMonth(2019, 10); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.with({ year: 2020 }, value), + `TypeError on wrong options type ${typeof value}`); +}; reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/shell.js b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/PlainYearMonth/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/from/shell.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/TimeZone/from/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/from/timezone-string-leap-second.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/timezone-string-leap-second.js new file mode 100644 index 000000000000..d28b4c58b985 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/timezone-string-leap-second.js @@ -0,0 +1,22 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.from +description: Leap second is a valid ISO string for TimeZone +features: [Temporal] +---*/ + +let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; + +const result1 = Temporal.TimeZone.from(timeZone); +assert.sameValue(result1.id, "UTC", "leap second is a valid ISO string for TimeZone"); +const result2 = Temporal.TimeZone.from({ timeZone }); +assert.sameValue(result2.id, "UTC", "leap second is a valid ISO string for TimeZone (nested property)"); + +timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; +assert.throws(RangeError, () => Temporal.TimeZone.from(timeZone), "leap second in time zone name not valid"); +assert.throws(RangeError, () => Temporal.TimeZone.from({ timeZone }), "leap second in time zone name not valid (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/from/timezone-string-year-zero.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/timezone-string-year-zero.js new file mode 100644 index 000000000000..8f53321f36fe --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/timezone-string-year-zero.js @@ -0,0 +1,28 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.from +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+00:00[UTC]", +]; +invalidStrings.forEach((timeZone) => { + assert.throws( + RangeError, + () => Temporal.TimeZone.from(timeZone), + "reject minus zero as extended year" + ); + assert.throws( + RangeError, + () => Temporal.TimeZone.from({ timeZone }), + "reject minus zero as extended year (nested property)" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/from/timezone-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/timezone-wrong-type.js new file mode 100644 index 000000000000..63af79bd6d90 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/from/timezone-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.from +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for TimeZone +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], +]; + +for (const [timeZone, description] of rangeErrorTests) { + assert.throws(RangeError, () => Temporal.TimeZone.from(timeZone), `${description} does not convert to a valid ISO string`); + assert.throws(RangeError, () => Temporal.TimeZone.from({ timeZone }), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [timeZone, description] of typeErrorTests) { + assert.throws(TypeError, () => Temporal.TimeZone.from(timeZone), `${description} is not a valid object and does not convert to a string`); + assert.throws(TypeError, () => Temporal.TimeZone.from({ timeZone }), `${description} is not a valid object and does not convert to a string (nested property)`); +} + +const timeZone = undefined; +assert.throws(RangeError, () => Temporal.TimeZone.from({ timeZone }), `undefined is always a RangeError as nested property`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-number.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-number.js new file mode 100644 index 000000000000..aa44a1326427 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-number.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: A number is converted to a string, then to Temporal.PlainDateTime +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +let arg = 19761118; + +const result = instance.getInstantFor(arg); +assert.sameValue(result.epochNanoseconds, 217_123_200_000_000_000n, "19761118 is a valid ISO string for PlainDateTime"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.getInstantFor(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDateTime` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..1de3bedd7ad9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,31 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.getInstantFor(arg); +assert.sameValue( + result1.epochNanoseconds, + 217_123_200_000_000_000n, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.getInstantFor(arg); +assert.sameValue( + result2.epochNanoseconds, + 217_123_200_000_000_000n, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..dad8b8a66bc4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-number.js @@ -0,0 +1,44 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.getInstantFor(arg); +assert.sameValue(result1.epochNanoseconds, 217_123_200_000_000_000n, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.getInstantFor(arg); +assert.sameValue(result2.epochNanoseconds, 217_123_200_000_000_000n, "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + assert.throws( + RangeError, + () => instance.getInstantFor(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.getInstantFor(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..3455ef686cdc --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.TimeZone("UTC"); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.getInstantFor(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.getInstantFor(arg), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.getInstantFor(arg), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.getInstantFor(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.getInstantFor(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..26303205c5c4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.TimeZone("UTC"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.getInstantFor(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-wrong-type.js new file mode 100644 index 000000000000..b7b49c287618 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/argument-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDateTime +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.getInstantFor(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDateTime, "Temporal.PlainDateTime, object"], + [Temporal.PlainDateTime.prototype, "Temporal.PlainDateTime.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.getInstantFor(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/leap-second.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/leap-second.js new file mode 100644 index 000000000000..c3a777ba19c7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/leap-second.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: Leap second is a valid ISO string for PlainDateTime +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.getInstantFor(arg); +assert.sameValue( + result1.epochNanoseconds, + 1_483_228_799_000_000_000n, + "leap second is a valid ISO string for PlainDateTime" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.getInstantFor(arg); +assert.sameValue( + result2.epochNanoseconds, + 1_483_228_799_000_000_000n, + "second: 60 is ignored in property bag for PlainDateTime" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/options-wrong-type.js new file mode 100644 index 000000000000..ae333bdcd02f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getinstantfor +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.TimeZone("UTC"); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.getInstantFor(new Temporal.PlainDateTime(2019, 10, 29, 10, 46, 38), value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/shell.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/year-zero.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/year-zero.js index 67ff13902477..c915c56ae9b9 100644 --- a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getInstantFor/year-zero.js @@ -9,14 +9,16 @@ features: [Temporal, arrow-function] ---*/ const invalidStrings = [ + "-000000-12-07", "-000000-12-07T03:24:30", - "-000000-12-07T03:24:30+01:00[UTC]" + "-000000-12-07T03:24:30+01:00", + "-000000-12-07T03:24:30+00:00[UTC]", ]; const instance = new Temporal.TimeZone("UTC"); invalidStrings.forEach((arg) => { assert.throws( RangeError, - () => { instance.getInstantFor(arg); }, + () => instance.getInstantFor(arg), "reject minus zero as extended year" ); }); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/leap-second.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/leap-second.js new file mode 100644 index 000000000000..192613db05f8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/leap-second.js @@ -0,0 +1,21 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getnexttransition +description: Leap second is a valid ISO string for Instant +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const arg = "2016-12-31T23:59:60Z"; +const result = instance.getNextTransition(arg); +assert.sameValue( + result, + null, + "leap second is a valid ISO string for Instant" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/shell.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/year-zero.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/year-zero.js index 3aac1ad19bf5..3681c72a7381 100644 --- a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getNextTransition/year-zero.js @@ -5,12 +5,21 @@ /*--- esid: sec-temporal.timezone.prototype.getnexttransition description: Negative zero, as an extended year, is rejected -features: [Temporal] +features: [Temporal, arrow-function] ---*/ +const invalidStrings = [ + "-000000-03-30T00:45Z", + "-000000-03-30T01:45+01:00", + "-000000-03-30T01:45:00+00:00[UTC]", +]; const instance = new Temporal.TimeZone("UTC"); - -let str = "-000000-01-01T00:00"; -assert.throws(RangeError, () => instance.getNextTransition(str), "reject minus zero as extended year"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.getNextTransition(arg), + "reject minus zero as extended year" + ); +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/leap-second.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/leap-second.js new file mode 100644 index 000000000000..8725c00af7a5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/leap-second.js @@ -0,0 +1,21 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetnanosecondsfor +description: Leap second is a valid ISO string for Instant +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const arg = "2016-12-31T23:59:60Z"; +const result = instance.getOffsetNanosecondsFor(arg); +assert.sameValue( + result, + 0, + "leap second is a valid ISO string for Instant" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/shell.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/year-zero.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/year-zero.js index 6dcba03de879..dc940fe01f8f 100644 --- a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetNanosecondsFor/year-zero.js @@ -5,12 +5,21 @@ /*--- esid: sec-temporal.timezone.prototype.getoffsetnanosecondsfor description: Negative zero, as an extended year, is rejected -features: [Temporal] +features: [Temporal, arrow-function] ---*/ +const invalidStrings = [ + "-000000-03-30T00:45Z", + "-000000-03-30T01:45+01:00", + "-000000-03-30T01:45:00+00:00[UTC]", +]; const instance = new Temporal.TimeZone("UTC"); - -let str = "-000000-01-01T00:00"; -assert.throws(RangeError, () => instance.getOffsetNanosecondsFor(str), "reject minus zero as extended year"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.getOffsetNanosecondsFor(arg), + "reject minus zero as extended year" + ); +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/leap-second.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/leap-second.js new file mode 100644 index 000000000000..735e521d72f8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/leap-second.js @@ -0,0 +1,21 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getoffsetstringfor +description: Leap second is a valid ISO string for Instant +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const arg = "2016-12-31T23:59:60Z"; +const result = instance.getOffsetStringFor(arg); +assert.sameValue( + result, + "+00:00", + "leap second is a valid ISO string for Instant" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/shell.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/year-zero.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/year-zero.js index 74378bdbe44b..79dd07eec5bf 100644 --- a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getOffsetStringFor/year-zero.js @@ -5,12 +5,21 @@ /*--- esid: sec-temporal.timezone.prototype.getoffsetstringfor description: Negative zero, as an extended year, is rejected -features: [Temporal] +features: [Temporal, arrow-function] ---*/ +const invalidStrings = [ + "-000000-03-30T00:45Z", + "-000000-03-30T01:45+01:00", + "-000000-03-30T01:45:00+00:00[UTC]", +]; const instance = new Temporal.TimeZone("UTC"); - -let str = "-000000-01-01T00:00"; -assert.throws(RangeError, () => instance.getOffsetStringFor(str), "reject minus zero as extended year"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.getOffsetStringFor(arg), + "reject minus zero as extended year" + ); +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-object-tostring.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-object-tostring.js new file mode 100644 index 000000000000..0e03565ed9dd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-object-tostring.js @@ -0,0 +1,23 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: Object is converted to a string, then to Temporal.Instant +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const arg = {}; +assert.throws(RangeError, () => instance.getPlainDateTimeFor(arg), "[object Object] is not a valid ISO string"); + +arg.toString = function() { + return "1970-01-01T00:00Z"; +}; +const result = instance.getPlainDateTimeFor(arg); +TemporalHelpers.assertPlainDateTime(result, 1970, 1, "M01", 1, 0, 0, 0, 0, 0, 0, "result of toString is interpreted as ISO string"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-wrong-type.js new file mode 100644 index 000000000000..8cc8552b6d2b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/argument-wrong-type.js @@ -0,0 +1,40 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: > + Appropriate error thrown when argument cannot be converted to a valid string + for Instant +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], + [{}, "plain object"], + [Temporal.Instant, "Temporal.Instant, object"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.getPlainDateTimeFor(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [Temporal.Instant.prototype, "Temporal.Instant.prototype, object"], // fails brand check in toString() +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.getPlainDateTimeFor(arg), `${description} does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-number.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-number.js new file mode 100644 index 000000000000..fd265b0a1830 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-number.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: A number is converted to a string, then to Temporal.Calendar +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const arg = 19761118; + +const result = instance.getPlainDateTimeFor(new Temporal.Instant(0n), arg); +assert.sameValue(result.calendar.id, "iso8601", "19761118 is a valid ISO string for Calendar"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.getPlainDateTimeFor(new Temporal.Instant(0n), arg), + `Number ${arg} does not convert to a valid ISO string for Calendar` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-string-leap-second.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-string-leap-second.js new file mode 100644 index 000000000000..407906e0e182 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-string-leap-second.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: Leap second is a valid ISO string for Calendar +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.getPlainDateTimeFor(new Temporal.Instant(0n), arg); +assert.sameValue( + result1.calendar.id, + "iso8601", + "leap second is a valid ISO string for Calendar" +); + +arg = { calendar: "2016-12-31T23:59:60" }; +const result2 = instance.getPlainDateTimeFor(new Temporal.Instant(0n), arg); +assert.sameValue( + result2.calendar.id, + "iso8601", + "leap second is a valid ISO string for Calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-wrong-type.js new file mode 100644 index 000000000000..449a9c88a9d8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/calendar-wrong-type.js @@ -0,0 +1,35 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for Calendar +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.getPlainDateTimeFor(new Temporal.Instant(0n), arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.getPlainDateTimeFor(new Temporal.Instant(0n), arg), `${description} is not a valid object and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/instant-string-sub-minute-offset.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/instant-string-sub-minute-offset.js new file mode 100644 index 000000000000..c74ea96f9ca6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/instant-string-sub-minute-offset.js @@ -0,0 +1,18 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: Temporal.Instant string with sub-minute offset +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const str = "1970-01-01T00:19:32.37+00:19:32.37"; +const result = instance.getPlainDateTimeFor(str); +TemporalHelpers.assertPlainDateTime(result, 1970, 1, "M01", 1, 0, 0, 0, 0, 0, 0, "if present, sub-minute offset is accepted exactly"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/leap-second.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/leap-second.js new file mode 100644 index 000000000000..0f23b5b15ba6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/leap-second.js @@ -0,0 +1,22 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getplaindatetimefor +description: Leap second is a valid ISO string for Instant +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const arg = "2016-12-31T23:59:60Z"; +const result = instance.getPlainDateTimeFor(arg); +TemporalHelpers.assertPlainDateTime( + result, + 2016, 12, "M12", 31, 23, 59, 59, 0, 0, 0, + "leap second is a valid ISO string for Instant" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/limits.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/limits.js new file mode 100644 index 000000000000..11962466fba3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/limits.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.getplaindatetimefor +description: Checking limits of representable PlainDateTime +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const min = new Temporal.Instant(-8_640_000_000_000_000_000_000n); +const offsetMin = new Temporal.TimeZone("-23:59"); +const max = new Temporal.Instant(8_640_000_000_000_000_000_000n); +const offsetMax = new Temporal.TimeZone("+23:59"); + +TemporalHelpers.assertPlainDateTime( + offsetMin.getPlainDateTimeFor(min, "iso8601"), + -271821, 4, "M04", 19, 0, 1, 0, 0, 0, 0, + "converting from Instant (negative case)" +); + +TemporalHelpers.assertPlainDateTime( + offsetMax.getPlainDateTimeFor(max, "iso8601"), + 275760, 9, "M09", 13, 23, 59, 0, 0, 0, 0, + "converting from Instant (positive case)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/shell.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/year-zero.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/year-zero.js index 1057f2868e14..eeb51656992c 100644 --- a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/year-zero.js @@ -5,19 +5,19 @@ /*--- esid: sec-temporal.timezone.prototype.getplaindatetimefor description: Negative zero, as an extended year, is rejected -features: [Temporal] +features: [Temporal, arrow-function] ---*/ const invalidStrings = [ - "-000000-03-30T00:45Z", - "-000000-03-30T01:45+01:00", - "-000000-03-30T01:45:00+01:00[UTC]" + "-000000-03-30T00:45Z", + "-000000-03-30T01:45+01:00", + "-000000-03-30T01:45:00+00:00[UTC]", ]; const instance = new Temporal.TimeZone("UTC"); -invalidStrings.forEach((str) => { +invalidStrings.forEach((arg) => { assert.throws( RangeError, - () => instance.getPlainDateTimeFor(str), + () => instance.getPlainDateTimeFor(arg), "reject minus zero as extended year" ); }); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-number.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-number.js new file mode 100644 index 000000000000..127355c8ec18 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-number.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: A number is converted to a string, then to Temporal.PlainDateTime +includes: [compareArray.js] +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +let arg = 19761118; + +const result = instance.getPossibleInstantsFor(arg); +assert.compareArray(result.map(i => i.epochNanoseconds), [217_123_200_000_000_000n], "19761118 is a valid ISO string for PlainDateTime"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.getPossibleInstantsFor(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDateTime` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..c34b4d724188 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: Leap second is a valid ISO string for a calendar in a property bag +includes: [compareArray.js] +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.getPossibleInstantsFor(arg); +assert.compareArray( + result1.map(i => i.epochNanoseconds), + [217_123_200_000_000_000n], + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.getPossibleInstantsFor(arg); +assert.compareArray( + result2.map(i => i.epochNanoseconds), + [217_123_200_000_000_000n], + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..ff14e3423e8f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-number.js @@ -0,0 +1,45 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: A number as calendar in a property bag is converted to a string, then to a calendar +includes: [compareArray.js] +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.getPossibleInstantsFor(arg); +assert.compareArray(result1.map(i => i.epochNanoseconds), [217_123_200_000_000_000n], "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.getPossibleInstantsFor(arg); +assert.compareArray(result2.map(i => i.epochNanoseconds), [217_123_200_000_000_000n], "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + assert.throws( + RangeError, + () => instance.getPossibleInstantsFor(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.getPossibleInstantsFor(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..6c04c84a893b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.TimeZone("UTC"); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.getPossibleInstantsFor(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.getPossibleInstantsFor(arg), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.getPossibleInstantsFor(arg), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.getPossibleInstantsFor(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.getPossibleInstantsFor(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..a5a83193e4d7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.TimeZone("UTC"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.getPossibleInstantsFor(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-wrong-type.js new file mode 100644 index 000000000000..5fa12600a94b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDateTime +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.getPossibleInstantsFor(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDateTime, "Temporal.PlainDateTime, object"], + [Temporal.PlainDateTime.prototype, "Temporal.PlainDateTime.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.getPossibleInstantsFor(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/leap-second.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/leap-second.js new file mode 100644 index 000000000000..91ed9f0abe34 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/leap-second.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getpossibleinstantsfor +description: Leap second is a valid ISO string for PlainDateTime +includes: [compareArray.js] +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.getPossibleInstantsFor(arg); +assert.compareArray( + result1.map(i => i.epochNanoseconds), + [1_483_228_799_000_000_000n], + "leap second is a valid ISO string for PlainDateTime" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.getPossibleInstantsFor(arg); +assert.compareArray( + result2.map(i => i.epochNanoseconds), + [1_483_228_799_000_000_000n], + "second: 60 is ignored in property bag for PlainDateTime" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/shell.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/year-zero.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/year-zero.js index 656e43ed58de..6917495e0588 100644 --- a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/year-zero.js @@ -9,14 +9,16 @@ features: [Temporal, arrow-function] ---*/ const invalidStrings = [ + "-000000-12-07", "-000000-12-07T03:24:30", - "-000000-12-07T03:24:30+01:00[UTC]" + "-000000-12-07T03:24:30+01:00", + "-000000-12-07T03:24:30+00:00[UTC]", ]; const instance = new Temporal.TimeZone("UTC"); invalidStrings.forEach((arg) => { assert.throws( RangeError, - () => { instance.getPossibleInstantsFor(arg); }, + () => instance.getPossibleInstantsFor(arg), "reject minus zero as extended year" ); }); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/leap-second.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/leap-second.js new file mode 100644 index 000000000000..8dfb639ffa33 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/leap-second.js @@ -0,0 +1,21 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.getprevioustransition +description: Leap second is a valid ISO string for Instant +features: [Temporal] +---*/ + +const instance = new Temporal.TimeZone("UTC"); + +const arg = "2016-12-31T23:59:60Z"; +const result = instance.getPreviousTransition(arg); +assert.sameValue( + result, + null, + "leap second is a valid ISO string for Instant" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/shell.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/year-zero.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/year-zero.js index 90d020696037..38dc0015a237 100644 --- a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/getPreviousTransition/year-zero.js @@ -5,12 +5,21 @@ /*--- esid: sec-temporal.timezone.prototype.getprevioustransition description: Negative zero, as an extended year, is rejected -features: [Temporal] +features: [Temporal, arrow-function] ---*/ +const invalidStrings = [ + "-000000-03-30T00:45Z", + "-000000-03-30T01:45+01:00", + "-000000-03-30T01:45:00+00:00[UTC]", +]; const instance = new Temporal.TimeZone("UTC"); - -let str = "-000000-01-01T00:00"; -assert.throws(RangeError, () => instance.getPreviousTransition(str), "reject minus zero as extended year"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.getPreviousTransition(arg), + "reject minus zero as extended year" + ); +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/id/branding.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/id/branding.js new file mode 100644 index 000000000000..e0e590fb942a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/id/branding.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.timezone.prototype.id +description: Throw a TypeError if the receiver is invalid +features: [Symbol, Temporal] +---*/ + +const descriptor = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "id"); +const id = descriptor.get; + +assert.sameValue(typeof id, "function"); + +assert.throws(TypeError, () => id.call(undefined), "undefined"); +assert.throws(TypeError, () => id.call(null), "null"); +assert.throws(TypeError, () => id.call(true), "true"); +assert.throws(TypeError, () => id.call(""), "empty string"); +assert.throws(TypeError, () => id.call(Symbol()), "symbol"); +assert.throws(TypeError, () => id.call(1), "1"); +assert.throws(TypeError, () => id.call({}), "plain object"); +assert.throws(TypeError, () => id.call(Temporal.TimeZone), "Temporal.TimeZone"); +assert.throws(TypeError, () => id.call(Temporal.TimeZone.prototype), "Temporal.TimeZone.prototype"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/id/browser.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/id/browser.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/id/custom-timezone.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/id/custom-timezone.js new file mode 100644 index 000000000000..3638ff43efcd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/id/custom-timezone.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-get-temporal.timezone.prototype.id +description: Getter calls toString() and returns its value +includes: [compareArray.js, temporalHelpers.js] +features: [Temporal] +---*/ + +const actual = []; +const expected = [ + "get [Symbol.toPrimitive]", + "get toString", + "call timeZone.toString", +]; + +const timeZone = new Temporal.TimeZone("UTC"); +TemporalHelpers.observeProperty(actual, timeZone, Symbol.toPrimitive, undefined); +TemporalHelpers.observeProperty(actual, timeZone, "toString", function () { + actual.push("call timeZone.toString"); + return "time zone"; +}); + +const result = timeZone.id; +assert.compareArray(actual, expected); +assert.sameValue(result, "time zone"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/id/no-toString.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/id/no-toString.js new file mode 100644 index 000000000000..bc62affb66d0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/id/no-toString.js @@ -0,0 +1,28 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-get-temporal.timezone.prototype.id +description: TypeError thrown when toString property not present +includes: [compareArray.js] +features: [Temporal] +---*/ + +const actual = []; +const expected = [ + "get timeZone.toString", +]; + +const timeZone = new Temporal.TimeZone("UTC"); +Object.defineProperty(timeZone, "toString", { + get() { + actual.push("get timeZone.toString"); + return undefined; + }, +}); + +assert.throws(TypeError, () => timeZone.id); +assert.compareArray(actual, expected); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/id/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/id/prop-desc.js new file mode 100644 index 000000000000..95694a04707a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/id/prop-desc.js @@ -0,0 +1,17 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-get-temporal.timezone.prototype.id +description: The "id" property of Temporal.TimeZone.prototype +features: [Temporal] +---*/ + +const descriptor = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "id"); +assert.sameValue(typeof descriptor.get, "function"); +assert.sameValue(descriptor.set, undefined); +assert.sameValue(descriptor.enumerable, false); +assert.sameValue(descriptor.configurable, true); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/id/shell.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/id/shell.js new file mode 100644 index 000000000000..6b347c4c3a6c --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/id/shell.js @@ -0,0 +1,1466 @@ +// GENERATED, DO NOT EDIT +// file: temporalHelpers.js +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: | + This defines helper objects and functions for testing Temporal. +defines: [TemporalHelpers] +features: [Symbol.species, Symbol.iterator, Temporal] +---*/ + +var TemporalHelpers = { + /* + * assertDuration(duration, years, ..., nanoseconds[, description]): + * + * Shorthand for asserting that each field of a Temporal.Duration is equal to + * an expected value. + */ + assertDuration(duration, years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds, description = "") { + assert(duration instanceof Temporal.Duration, `${description} instanceof`); + assert.sameValue(duration.years, years, `${description} years result`); + assert.sameValue(duration.months, months, `${description} months result`); + assert.sameValue(duration.weeks, weeks, `${description} weeks result`); + assert.sameValue(duration.days, days, `${description} days result`); + assert.sameValue(duration.hours, hours, `${description} hours result`); + assert.sameValue(duration.minutes, minutes, `${description} minutes result`); + assert.sameValue(duration.seconds, seconds, `${description} seconds result`); + assert.sameValue(duration.milliseconds, milliseconds, `${description} milliseconds result`); + assert.sameValue(duration.microseconds, microseconds, `${description} microseconds result`); + assert.sameValue(duration.nanoseconds, nanoseconds, `${description} nanoseconds result`); + }, + + /* + * assertDurationsEqual(actual, expected[, description]): + * + * Shorthand for asserting that each field of a Temporal.Duration is equal to + * the corresponding field in another Temporal.Duration. + */ + assertDurationsEqual(actual, expected, description = "") { + assert(expected instanceof Temporal.Duration, `${description} expected value should be a Temporal.Duration`); + TemporalHelpers.assertDuration(actual, expected.years, expected.months, expected.weeks, expected.days, expected.hours, expected.minutes, expected.seconds, expected.milliseconds, expected.microseconds, expected.nanoseconds, description); + }, + + /* + * assertInstantsEqual(actual, expected[, description]): + * + * Shorthand for asserting that two Temporal.Instants are of the correct type + * and equal according to their equals() methods. + */ + assertInstantsEqual(actual, expected, description = "") { + assert(expected instanceof Temporal.Instant, `${description} expected value should be a Temporal.Instant`); + assert(actual instanceof Temporal.Instant, `${description} instanceof`); + assert(actual.equals(expected), `${description} equals method`); + }, + + /* + * assertPlainDate(date, year, ..., nanosecond[, description[, era, eraYear]]): + * + * Shorthand for asserting that each field of a Temporal.PlainDate is equal to + * an expected value. (Except the `calendar` property, since callers may want + * to assert either object equality with an object they put in there, or the + * result of date.calendar.toString().) + */ + assertPlainDate(date, year, month, monthCode, day, description = "", era = undefined, eraYear = undefined) { + assert(date instanceof Temporal.PlainDate, `${description} instanceof`); + assert.sameValue(date.era, era, `${description} era result`); + assert.sameValue(date.eraYear, eraYear, `${description} eraYear result`); + assert.sameValue(date.year, year, `${description} year result`); + assert.sameValue(date.month, month, `${description} month result`); + assert.sameValue(date.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(date.day, day, `${description} day result`); + }, + + /* + * assertPlainDateTime(datetime, year, ..., nanosecond[, description[, era, eraYear]]): + * + * Shorthand for asserting that each field of a Temporal.PlainDateTime is + * equal to an expected value. (Except the `calendar` property, since callers + * may want to assert either object equality with an object they put in there, + * or the result of datetime.calendar.toString().) + */ + assertPlainDateTime(datetime, year, month, monthCode, day, hour, minute, second, millisecond, microsecond, nanosecond, description = "", era = undefined, eraYear = undefined) { + assert(datetime instanceof Temporal.PlainDateTime, `${description} instanceof`); + assert.sameValue(datetime.era, era, `${description} era result`); + assert.sameValue(datetime.eraYear, eraYear, `${description} eraYear result`); + assert.sameValue(datetime.year, year, `${description} year result`); + assert.sameValue(datetime.month, month, `${description} month result`); + assert.sameValue(datetime.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(datetime.day, day, `${description} day result`); + assert.sameValue(datetime.hour, hour, `${description} hour result`); + assert.sameValue(datetime.minute, minute, `${description} minute result`); + assert.sameValue(datetime.second, second, `${description} second result`); + assert.sameValue(datetime.millisecond, millisecond, `${description} millisecond result`); + assert.sameValue(datetime.microsecond, microsecond, `${description} microsecond result`); + assert.sameValue(datetime.nanosecond, nanosecond, `${description} nanosecond result`); + }, + + /* + * assertPlainDateTimesEqual(actual, expected[, description]): + * + * Shorthand for asserting that two Temporal.PlainDateTimes are of the correct + * type, equal according to their equals() methods, and additionally that + * their calendars are the same value. + */ + assertPlainDateTimesEqual(actual, expected, description = "") { + assert(expected instanceof Temporal.PlainDateTime, `${description} expected value should be a Temporal.PlainDateTime`); + assert(actual instanceof Temporal.PlainDateTime, `${description} instanceof`); + assert(actual.equals(expected), `${description} equals method`); + assert.sameValue(actual.calendar, expected.calendar, `${description} calendar same value`); + }, + + /* + * assertPlainMonthDay(monthDay, monthCode, day[, description [, referenceISOYear]]): + * + * Shorthand for asserting that each field of a Temporal.PlainMonthDay is + * equal to an expected value. (Except the `calendar` property, since callers + * may want to assert either object equality with an object they put in there, + * or the result of monthDay.calendar.toString().) + */ + assertPlainMonthDay(monthDay, monthCode, day, description = "", referenceISOYear = 1972) { + assert(monthDay instanceof Temporal.PlainMonthDay, `${description} instanceof`); + assert.sameValue(monthDay.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(monthDay.day, day, `${description} day result`); + assert.sameValue(monthDay.getISOFields().isoYear, referenceISOYear, `${description} referenceISOYear result`); + }, + + /* + * assertPlainTime(time, hour, ..., nanosecond[, description]): + * + * Shorthand for asserting that each field of a Temporal.PlainTime is equal to + * an expected value. + */ + assertPlainTime(time, hour, minute, second, millisecond, microsecond, nanosecond, description = "") { + assert(time instanceof Temporal.PlainTime, `${description} instanceof`); + assert.sameValue(time.hour, hour, `${description} hour result`); + assert.sameValue(time.minute, minute, `${description} minute result`); + assert.sameValue(time.second, second, `${description} second result`); + assert.sameValue(time.millisecond, millisecond, `${description} millisecond result`); + assert.sameValue(time.microsecond, microsecond, `${description} microsecond result`); + assert.sameValue(time.nanosecond, nanosecond, `${description} nanosecond result`); + }, + + /* + * assertPlainTimesEqual(actual, expected[, description]): + * + * Shorthand for asserting that two Temporal.PlainTimes are of the correct + * type and equal according to their equals() methods. + */ + assertPlainTimesEqual(actual, expected, description = "") { + assert(expected instanceof Temporal.PlainTime, `${description} expected value should be a Temporal.PlainTime`); + assert(actual instanceof Temporal.PlainTime, `${description} instanceof`); + assert(actual.equals(expected), `${description} equals method`); + }, + + /* + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): + * + * Shorthand for asserting that each field of a Temporal.PlainYearMonth is + * equal to an expected value. (Except the `calendar` property, since callers + * may want to assert either object equality with an object they put in there, + * or the result of yearMonth.calendar.toString().) + */ + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { + assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); + assert.sameValue(yearMonth.era, era, `${description} era result`); + assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); + assert.sameValue(yearMonth.year, year, `${description} year result`); + assert.sameValue(yearMonth.month, month, `${description} month result`); + assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); + }, + + /* + * assertZonedDateTimesEqual(actual, expected[, description]): + * + * Shorthand for asserting that two Temporal.ZonedDateTimes are of the correct + * type, equal according to their equals() methods, and additionally that + * their time zones and calendars are the same value. + */ + assertZonedDateTimesEqual(actual, expected, description = "") { + assert(expected instanceof Temporal.ZonedDateTime, `${description} expected value should be a Temporal.ZonedDateTime`); + assert(actual instanceof Temporal.ZonedDateTime, `${description} instanceof`); + assert(actual.equals(expected), `${description} equals method`); + assert.sameValue(actual.timeZone, expected.timeZone, `${description} time zone same value`); + assert.sameValue(actual.calendar, expected.calendar, `${description} calendar same value`); + }, + + /* + * assertUnreachable(description): + * + * Helper for asserting that code is not executed. This is useful for + * assertions that methods of user calendars and time zones are not called. + */ + assertUnreachable(description) { + let message = "This code should not be executed"; + if (description) { + message = `${message}: ${description}`; + } + throw new Test262Error(message); + }, + + /* + * checkCalendarDateUntilLargestUnitSingular(func, expectedLargestUnitCalls): + * + * When an options object with a largestUnit property is synthesized inside + * Temporal and passed to user code such as calendar.dateUntil(), the value of + * the largestUnit property should be in the singular form, even if the input + * was given in the plural form. + * (This doesn't apply when the options object is passed through verbatim.) + * + * func(calendar, largestUnit, index) is the operation under test. It's called + * with an instance of a calendar that keeps track of which largestUnit is + * passed to dateUntil(), each key of expectedLargestUnitCalls in turn, and + * the key's numerical index in case the function needs to generate test data + * based on the index. At the end, the actual values passed to dateUntil() are + * compared with the array values of expectedLargestUnitCalls. + */ + checkCalendarDateUntilLargestUnitSingular(func, expectedLargestUnitCalls) { + const actual = []; + + class DateUntilOptionsCalendar extends Temporal.Calendar { + constructor() { + super("iso8601"); + } + + dateUntil(earlier, later, options) { + actual.push(options.largestUnit); + return super.dateUntil(earlier, later, options); + } + + toString() { + return "date-until-options"; + } + } + + const calendar = new DateUntilOptionsCalendar(); + Object.entries(expectedLargestUnitCalls).forEach(([largestUnit, expected], index) => { + func(calendar, largestUnit, index); + assert.compareArray(actual, expected, `largestUnit passed to calendar.dateUntil() for largestUnit ${largestUnit}`); + actual.splice(0, actual.length); // empty it for the next check + }); + }, + + /* + * checkPlainDateTimeConversionFastPath(func): + * + * ToTemporalDate and ToTemporalTime should both, if given a + * Temporal.PlainDateTime instance, convert to the desired type by reading the + * PlainDateTime's internal slots, rather than calling any getters. + * + * func(datetime, calendar) is the actual operation to test, that must + * internally call the abstract operation ToTemporalDate or ToTemporalTime. + * It is passed a Temporal.PlainDateTime instance, as well as the instance's + * calendar object (so that it doesn't have to call the calendar getter itself + * if it wants to make any assertions about the calendar.) + */ + checkPlainDateTimeConversionFastPath(func) { + const actual = []; + const expected = []; + + const calendar = new Temporal.Calendar("iso8601"); + const datetime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, calendar); + const prototypeDescrs = Object.getOwnPropertyDescriptors(Temporal.PlainDateTime.prototype); + ["year", "month", "monthCode", "day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond"].forEach((property) => { + Object.defineProperty(datetime, property, { + get() { + actual.push(`get ${property}`); + const value = prototypeDescrs[property].get.call(this); + return { + toString() { + actual.push(`toString ${property}`); + return value.toString(); + }, + valueOf() { + actual.push(`valueOf ${property}`); + return value; + }, + }; + }, + }); + }); + Object.defineProperty(datetime, "calendar", { + get() { + actual.push("get calendar"); + return calendar; + }, + }); + + func(datetime, calendar); + assert.compareArray(actual, expected, "property getters not called"); + }, + + /* + * Check that an options bag that accepts units written in the singular form, + * also accepts the same units written in the plural form. + * func(unit) should call the method with the appropriate options bag + * containing unit as a value. This will be called twice for each element of + * validSingularUnits, once with singular and once with plural, and the + * results of each pair should be the same (whether a Temporal object or a + * primitive value.) + */ + checkPluralUnitsAccepted(func, validSingularUnits) { + const plurals = { + year: 'years', + month: 'months', + week: 'weeks', + day: 'days', + hour: 'hours', + minute: 'minutes', + second: 'seconds', + millisecond: 'milliseconds', + microsecond: 'microseconds', + nanosecond: 'nanoseconds', + }; + + validSingularUnits.forEach((unit) => { + const singularValue = func(unit); + const pluralValue = func(plurals[unit]); + const desc = `Plural ${plurals[unit]} produces the same result as singular ${unit}`; + if (singularValue instanceof Temporal.Duration) { + TemporalHelpers.assertDurationsEqual(pluralValue, singularValue, desc); + } else if (singularValue instanceof Temporal.Instant) { + TemporalHelpers.assertInstantsEqual(pluralValue, singularValue, desc); + } else if (singularValue instanceof Temporal.PlainDateTime) { + TemporalHelpers.assertPlainDateTimesEqual(pluralValue, singularValue, desc); + } else if (singularValue instanceof Temporal.PlainTime) { + TemporalHelpers.assertPlainTimesEqual(pluralValue, singularValue, desc); + } else if (singularValue instanceof Temporal.ZonedDateTime) { + TemporalHelpers.assertZonedDateTimesEqual(pluralValue, singularValue, desc); + } else { + assert.sameValue(pluralValue, singularValue); + } + }); + }, + + /* + * checkRoundingIncrementOptionWrongType(checkFunc, assertTrueResultFunc, assertObjectResultFunc): + * + * Checks the type handling of the roundingIncrement option. + * checkFunc(roundingIncrement) is a function which takes the value of + * roundingIncrement to test, and calls the method under test with it, + * returning the result. assertTrueResultFunc(result, description) should + * assert that result is the expected result with roundingIncrement: true, and + * assertObjectResultFunc(result, description) should assert that result is + * the expected result with roundingIncrement being an object with a valueOf() + * method. + */ + checkRoundingIncrementOptionWrongType(checkFunc, assertTrueResultFunc, assertObjectResultFunc) { + // null converts to 0, which is out of range + assert.throws(RangeError, () => checkFunc(null), "null"); + // Booleans convert to either 0 or 1, and 1 is allowed + const trueResult = checkFunc(true); + assertTrueResultFunc(trueResult, "true"); + assert.throws(RangeError, () => checkFunc(false), "false"); + // Symbols and BigInts cannot convert to numbers + assert.throws(TypeError, () => checkFunc(Symbol()), "symbol"); + assert.throws(TypeError, () => checkFunc(2n), "bigint"); + + // Objects prefer their valueOf() methods when converting to a number + assert.throws(RangeError, () => checkFunc({}), "plain object"); + + const expected = [ + "get roundingIncrement.valueOf", + "call roundingIncrement.valueOf", + ]; + const actual = []; + const observer = TemporalHelpers.toPrimitiveObserver(actual, 2, "roundingIncrement"); + const objectResult = checkFunc(observer); + assertObjectResultFunc(objectResult, "object with valueOf"); + assert.compareArray(actual, expected, "order of operations"); + }, + + /* + * checkStringOptionWrongType(propertyName, value, checkFunc, assertFunc): + * + * Checks the type handling of a string option, of which there are several in + * Temporal. + * propertyName is the name of the option, and value is the value that + * assertFunc should expect it to have. + * checkFunc(value) is a function which takes the value of the option to test, + * and calls the method under test with it, returning the result. + * assertFunc(result, description) should assert that result is the expected + * result with the option value being an object with a toString() method + * which returns the given value. + */ + checkStringOptionWrongType(propertyName, value, checkFunc, assertFunc) { + // null converts to the string "null", which is an invalid string value + assert.throws(RangeError, () => checkFunc(null), "null"); + // Booleans convert to the strings "true" or "false", which are invalid + assert.throws(RangeError, () => checkFunc(true), "true"); + assert.throws(RangeError, () => checkFunc(false), "false"); + // Symbols cannot convert to strings + assert.throws(TypeError, () => checkFunc(Symbol()), "symbol"); + // Numbers convert to strings which are invalid + assert.throws(RangeError, () => checkFunc(2), "number"); + // BigInts convert to strings which are invalid + assert.throws(RangeError, () => checkFunc(2n), "bigint"); + + // Objects prefer their toString() methods when converting to a string + assert.throws(RangeError, () => checkFunc({}), "plain object"); + + const expected = [ + `get ${propertyName}.toString`, + `call ${propertyName}.toString`, + ]; + const actual = []; + const observer = TemporalHelpers.toPrimitiveObserver(actual, value, propertyName); + const result = checkFunc(observer); + assertFunc(result, "object with toString"); + assert.compareArray(actual, expected, "order of operations"); + }, + + /* + * checkSubclassingIgnored(construct, constructArgs, method, methodArgs, + * resultAssertions): + * + * Methods of Temporal classes that return a new instance of the same class, + * must not take the constructor of a subclass into account, nor the @@species + * property. This helper runs tests to ensure this. + * + * construct(...constructArgs) must yield a valid instance of the Temporal + * class. instance[method](...methodArgs) is the method call under test, which + * must also yield a valid instance of the same Temporal class, not a + * subclass. See below for the individual tests that this runs. + * resultAssertions() is a function that performs additional assertions on the + * instance returned by the method under test. + */ + checkSubclassingIgnored(...args) { + this.checkSubclassConstructorNotObject(...args); + this.checkSubclassConstructorUndefined(...args); + this.checkSubclassConstructorThrows(...args); + this.checkSubclassConstructorNotCalled(...args); + this.checkSubclassSpeciesInvalidResult(...args); + this.checkSubclassSpeciesNotAConstructor(...args); + this.checkSubclassSpeciesNull(...args); + this.checkSubclassSpeciesUndefined(...args); + this.checkSubclassSpeciesThrows(...args); + }, + + /* + * Checks that replacing the 'constructor' property of the instance with + * various primitive values does not affect the returned new instance. + */ + checkSubclassConstructorNotObject(construct, constructArgs, method, methodArgs, resultAssertions) { + function check(value, description) { + const instance = new construct(...constructArgs); + instance.constructor = value; + const result = instance[method](...methodArgs); + assert.sameValue(Object.getPrototypeOf(result), construct.prototype, description); + resultAssertions(result); + } + + check(null, "null"); + check(true, "true"); + check("test", "string"); + check(Symbol(), "Symbol"); + check(7, "number"); + check(7n, "bigint"); + }, + + /* + * Checks that replacing the 'constructor' property of the subclass with + * undefined does not affect the returned new instance. + */ + checkSubclassConstructorUndefined(construct, constructArgs, method, methodArgs, resultAssertions) { + let called = 0; + + class MySubclass extends construct { + constructor() { + ++called; + super(...constructArgs); + } + } + + const instance = new MySubclass(); + assert.sameValue(called, 1); + + MySubclass.prototype.constructor = undefined; + + const result = instance[method](...methodArgs); + assert.sameValue(called, 1); + assert.sameValue(Object.getPrototypeOf(result), construct.prototype); + resultAssertions(result); + }, + + /* + * Checks that making the 'constructor' property of the instance throw when + * called does not affect the returned new instance. + */ + checkSubclassConstructorThrows(construct, constructArgs, method, methodArgs, resultAssertions) { + function CustomError() {} + const instance = new construct(...constructArgs); + Object.defineProperty(instance, "constructor", { + get() { + throw new CustomError(); + } + }); + const result = instance[method](...methodArgs); + assert.sameValue(Object.getPrototypeOf(result), construct.prototype); + resultAssertions(result); + }, + + /* + * Checks that when subclassing, the subclass constructor is not called by + * the method under test. + */ + checkSubclassConstructorNotCalled(construct, constructArgs, method, methodArgs, resultAssertions) { + let called = 0; + + class MySubclass extends construct { + constructor() { + ++called; + super(...constructArgs); + } + } + + const instance = new MySubclass(); + assert.sameValue(called, 1); + + const result = instance[method](...methodArgs); + assert.sameValue(called, 1); + assert.sameValue(Object.getPrototypeOf(result), construct.prototype); + resultAssertions(result); + }, + + /* + * Check that the constructor's @@species property is ignored when it's a + * constructor that returns a non-object value. + */ + checkSubclassSpeciesInvalidResult(construct, constructArgs, method, methodArgs, resultAssertions) { + function check(value, description) { + const instance = new construct(...constructArgs); + instance.constructor = { + [Symbol.species]: function() { + return value; + }, + }; + const result = instance[method](...methodArgs); + assert.sameValue(Object.getPrototypeOf(result), construct.prototype, description); + resultAssertions(result); + } + + check(undefined, "undefined"); + check(null, "null"); + check(true, "true"); + check("test", "string"); + check(Symbol(), "Symbol"); + check(7, "number"); + check(7n, "bigint"); + check({}, "plain object"); + }, + + /* + * Check that the constructor's @@species property is ignored when it's not a + * constructor. + */ + checkSubclassSpeciesNotAConstructor(construct, constructArgs, method, methodArgs, resultAssertions) { + function check(value, description) { + const instance = new construct(...constructArgs); + instance.constructor = { + [Symbol.species]: value, + }; + const result = instance[method](...methodArgs); + assert.sameValue(Object.getPrototypeOf(result), construct.prototype, description); + resultAssertions(result); + } + + check(true, "true"); + check("test", "string"); + check(Symbol(), "Symbol"); + check(7, "number"); + check(7n, "bigint"); + check({}, "plain object"); + }, + + /* + * Check that the constructor's @@species property is ignored when it's null. + */ + checkSubclassSpeciesNull(construct, constructArgs, method, methodArgs, resultAssertions) { + let called = 0; + + class MySubclass extends construct { + constructor() { + ++called; + super(...constructArgs); + } + } + + const instance = new MySubclass(); + assert.sameValue(called, 1); + + MySubclass.prototype.constructor = { + [Symbol.species]: null, + }; + + const result = instance[method](...methodArgs); + assert.sameValue(called, 1); + assert.sameValue(Object.getPrototypeOf(result), construct.prototype); + resultAssertions(result); + }, + + /* + * Check that the constructor's @@species property is ignored when it's + * undefined. + */ + checkSubclassSpeciesUndefined(construct, constructArgs, method, methodArgs, resultAssertions) { + let called = 0; + + class MySubclass extends construct { + constructor() { + ++called; + super(...constructArgs); + } + } + + const instance = new MySubclass(); + assert.sameValue(called, 1); + + MySubclass.prototype.constructor = { + [Symbol.species]: undefined, + }; + + const result = instance[method](...methodArgs); + assert.sameValue(called, 1); + assert.sameValue(Object.getPrototypeOf(result), construct.prototype); + resultAssertions(result); + }, + + /* + * Check that the constructor's @@species property is ignored when it throws, + * i.e. it is not called at all. + */ + checkSubclassSpeciesThrows(construct, constructArgs, method, methodArgs, resultAssertions) { + function CustomError() {} + + const instance = new construct(...constructArgs); + instance.constructor = { + get [Symbol.species]() { + throw new CustomError(); + }, + }; + + const result = instance[method](...methodArgs); + assert.sameValue(Object.getPrototypeOf(result), construct.prototype); + }, + + /* + * checkSubclassingIgnoredStatic(construct, method, methodArgs, resultAssertions): + * + * Static methods of Temporal classes that return a new instance of the class, + * must not use the this-value as a constructor. This helper runs tests to + * ensure this. + * + * construct[method](...methodArgs) is the static method call under test, and + * must yield a valid instance of the Temporal class, not a subclass. See + * below for the individual tests that this runs. + * resultAssertions() is a function that performs additional assertions on the + * instance returned by the method under test. + */ + checkSubclassingIgnoredStatic(...args) { + this.checkStaticInvalidReceiver(...args); + this.checkStaticReceiverNotCalled(...args); + this.checkThisValueNotCalled(...args); + }, + + /* + * Check that calling the static method with a receiver that's not callable, + * still calls the intrinsic constructor. + */ + checkStaticInvalidReceiver(construct, method, methodArgs, resultAssertions) { + function check(value, description) { + const result = construct[method].apply(value, methodArgs); + assert.sameValue(Object.getPrototypeOf(result), construct.prototype); + resultAssertions(result); + } + + check(undefined, "undefined"); + check(null, "null"); + check(true, "true"); + check("test", "string"); + check(Symbol(), "symbol"); + check(7, "number"); + check(7n, "bigint"); + check({}, "Non-callable object"); + }, + + /* + * Check that calling the static method with a receiver that returns a value + * that's not callable, still calls the intrinsic constructor. + */ + checkStaticReceiverNotCalled(construct, method, methodArgs, resultAssertions) { + function check(value, description) { + const receiver = function () { + return value; + }; + const result = construct[method].apply(receiver, methodArgs); + assert.sameValue(Object.getPrototypeOf(result), construct.prototype); + resultAssertions(result); + } + + check(undefined, "undefined"); + check(null, "null"); + check(true, "true"); + check("test", "string"); + check(Symbol(), "symbol"); + check(7, "number"); + check(7n, "bigint"); + check({}, "Non-callable object"); + }, + + /* + * Check that the receiver isn't called. + */ + checkThisValueNotCalled(construct, method, methodArgs, resultAssertions) { + let called = false; + + class MySubclass extends construct { + constructor(...args) { + called = true; + super(...args); + } + } + + const result = MySubclass[method](...methodArgs); + assert.sameValue(called, false); + assert.sameValue(Object.getPrototypeOf(result), construct.prototype); + resultAssertions(result); + }, + + /* + * Check that any iterable returned from a custom time zone's + * getPossibleInstantsFor() method is exhausted. + * The custom time zone object is passed in to func(). + * expected is an array of strings representing the expected calls to the + * getPossibleInstantsFor() method. The PlainDateTimes that it is called with, + * are compared (using their toString() results) with the array. + */ + checkTimeZonePossibleInstantsIterable(func, expected) { + // A custom time zone that returns an iterable instead of an array from its + // getPossibleInstantsFor() method, and for testing purposes skips + // 00:00-01:00 UTC on January 1, 2030, and repeats 00:00-01:00 UTC+1 on + // January 3, 2030. Otherwise identical to the UTC time zone. + class TimeZonePossibleInstantsIterable extends Temporal.TimeZone { + constructor() { + super("UTC"); + this.getPossibleInstantsForCallCount = 0; + this.getPossibleInstantsForCalledWith = []; + this.getPossibleInstantsForReturns = []; + this.iteratorExhausted = []; + } + + toString() { + return "Custom/Iterable"; + } + + getOffsetNanosecondsFor(instant) { + if (Temporal.Instant.compare(instant, "2030-01-01T00:00Z") >= 0 && + Temporal.Instant.compare(instant, "2030-01-03T01:00Z") < 0) { + return 3600_000_000_000; + } else { + return 0; + } + } + + getPossibleInstantsFor(dateTime) { + this.getPossibleInstantsForCallCount++; + this.getPossibleInstantsForCalledWith.push(dateTime); + + // Fake DST transition + let retval = super.getPossibleInstantsFor(dateTime); + if (dateTime.toPlainDate().equals("2030-01-01") && dateTime.hour === 0) { + retval = []; + } else if (dateTime.toPlainDate().equals("2030-01-03") && dateTime.hour === 0) { + retval.push(retval[0].subtract({ hours: 1 })); + } else if (dateTime.year === 2030 && dateTime.month === 1 && dateTime.day >= 1 && dateTime.day <= 2) { + retval[0] = retval[0].subtract({ hours: 1 }); + } + + this.getPossibleInstantsForReturns.push(retval); + this.iteratorExhausted.push(false); + return { + callIndex: this.getPossibleInstantsForCallCount - 1, + timeZone: this, + *[Symbol.iterator]() { + yield* this.timeZone.getPossibleInstantsForReturns[this.callIndex]; + this.timeZone.iteratorExhausted[this.callIndex] = true; + }, + }; + } + } + + const timeZone = new TimeZonePossibleInstantsIterable(); + func(timeZone); + + assert.sameValue(timeZone.getPossibleInstantsForCallCount, expected.length, "getPossibleInstantsFor() method called correct number of times"); + + for (let index = 0; index < expected.length; index++) { + assert.sameValue(timeZone.getPossibleInstantsForCalledWith[index].toString(), expected[index], "getPossibleInstantsFor() called with expected PlainDateTime"); + assert(timeZone.iteratorExhausted[index], "iterated through the whole iterable"); + } + }, + + /* + * Check that any calendar-carrying Temporal object has its [[Calendar]] + * internal slot read by ToTemporalCalendar, and does not fetch the calendar + * by calling getters. + * The custom calendar object is passed in to func() so that it can do its + * own additional assertions involving the calendar if necessary. (Sometimes + * there is nothing to assert as the calendar isn't stored anywhere that can + * be asserted about.) + */ + checkToTemporalCalendarFastPath(func) { + class CalendarFastPathCheck extends Temporal.Calendar { + constructor() { + super("iso8601"); + } + + toString() { + return "fast-path-check"; + } + } + const calendar = new CalendarFastPathCheck(); + + const plainDate = new Temporal.PlainDate(2000, 5, 2, calendar); + const plainDateTime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, calendar); + const plainMonthDay = new Temporal.PlainMonthDay(5, 2, calendar); + const plainYearMonth = new Temporal.PlainYearMonth(2000, 5, calendar); + const zonedDateTime = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", calendar); + + [plainDate, plainDateTime, plainMonthDay, plainYearMonth, zonedDateTime].forEach((temporalObject) => { + const actual = []; + const expected = []; + + Object.defineProperty(temporalObject, "calendar", { + get() { + actual.push("get calendar"); + return calendar; + }, + }); + + func(temporalObject, calendar); + assert.compareArray(actual, expected, "calendar getter not called"); + }); + }, + + checkToTemporalInstantFastPath(func) { + const actual = []; + const expected = []; + + const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, "UTC"); + Object.defineProperty(datetime, 'toString', { + get() { + actual.push("get toString"); + return function (options) { + actual.push("call toString"); + return Temporal.ZonedDateTime.prototype.toString.call(this, options); + }; + }, + }); + + func(datetime); + assert.compareArray(actual, expected, "toString not called"); + }, + + checkToTemporalPlainDateTimeFastPath(func) { + const actual = []; + const expected = []; + + const calendar = new Temporal.Calendar("iso8601"); + const date = new Temporal.PlainDate(2000, 5, 2, calendar); + const prototypeDescrs = Object.getOwnPropertyDescriptors(Temporal.PlainDate.prototype); + ["year", "month", "monthCode", "day"].forEach((property) => { + Object.defineProperty(date, property, { + get() { + actual.push(`get ${property}`); + const value = prototypeDescrs[property].get.call(this); + return TemporalHelpers.toPrimitiveObserver(actual, value, property); + }, + }); + }); + ["hour", "minute", "second", "millisecond", "microsecond", "nanosecond"].forEach((property) => { + Object.defineProperty(date, property, { + get() { + actual.push(`get ${property}`); + return undefined; + }, + }); + }); + Object.defineProperty(date, "calendar", { + get() { + actual.push("get calendar"); + return calendar; + }, + }); + + func(date, calendar); + assert.compareArray(actual, expected, "property getters not called"); + }, + + /* + * A custom calendar that asserts its dateAdd() method is called with the + * options parameter having the value undefined. + */ + calendarDateAddUndefinedOptions() { + class CalendarDateAddUndefinedOptions extends Temporal.Calendar { + constructor() { + super("iso8601"); + this.dateAddCallCount = 0; + } + + toString() { + return "dateadd-undef-options"; + } + + dateAdd(date, duration, options) { + this.dateAddCallCount++; + assert.sameValue(options, undefined, "dateAdd shouldn't be called with options"); + return super.dateAdd(date, duration, options); + } + } + return new CalendarDateAddUndefinedOptions(); + }, + + /* + * A custom calendar that asserts its dateAdd() method is called with a + * PlainDate instance. Optionally, it also asserts that the PlainDate instance + * is the specific object `this.specificPlainDate`, if it is set by the + * calling code. + */ + calendarDateAddPlainDateInstance() { + class CalendarDateAddPlainDateInstance extends Temporal.Calendar { + constructor() { + super("iso8601"); + this.dateAddCallCount = 0; + this.specificPlainDate = undefined; + } + + toString() { + return "dateadd-plain-date-instance"; + } + + dateAdd(date, duration, options) { + this.dateAddCallCount++; + assert(date instanceof Temporal.PlainDate, "dateAdd() should be called with a PlainDate instance"); + if (this.dateAddCallCount === 1 && this.specificPlainDate) { + assert.sameValue(date, this.specificPlainDate, `dateAdd() should be called first with the specific PlainDate instance ${this.specificPlainDate}`); + } + return super.dateAdd(date, duration, options); + } + } + return new CalendarDateAddPlainDateInstance(); + }, + + /* + * A custom calendar that returns @returnValue from its dateUntil() method, + * recording the call in @calls. + */ + calendarDateUntilObservable(calls, returnValue) { + class CalendarDateUntilObservable extends Temporal.Calendar { + constructor() { + super("iso8601"); + } + + dateUntil() { + calls.push("call dateUntil"); + return returnValue; + } + } + + return new CalendarDateUntilObservable(); + }, + + /* + * A custom calendar that returns an iterable instead of an array from its + * fields() method, otherwise identical to the ISO calendar. + */ + calendarFieldsIterable() { + class CalendarFieldsIterable extends Temporal.Calendar { + constructor() { + super("iso8601"); + this.fieldsCallCount = 0; + this.fieldsCalledWith = []; + this.iteratorExhausted = []; + } + + toString() { + return "fields-iterable"; + } + + fields(fieldNames) { + this.fieldsCallCount++; + this.fieldsCalledWith.push(fieldNames.slice()); + this.iteratorExhausted.push(false); + return { + callIndex: this.fieldsCallCount - 1, + calendar: this, + *[Symbol.iterator]() { + yield* this.calendar.fieldsCalledWith[this.callIndex]; + this.calendar.iteratorExhausted[this.callIndex] = true; + }, + }; + } + } + return new CalendarFieldsIterable(); + }, + + /* + * A custom calendar that asserts its ...FromFields() methods are called with + * the options parameter having the value undefined. + */ + calendarFromFieldsUndefinedOptions() { + class CalendarFromFieldsUndefinedOptions extends Temporal.Calendar { + constructor() { + super("iso8601"); + this.dateFromFieldsCallCount = 0; + this.monthDayFromFieldsCallCount = 0; + this.yearMonthFromFieldsCallCount = 0; + } + + toString() { + return "from-fields-undef-options"; + } + + dateFromFields(fields, options) { + this.dateFromFieldsCallCount++; + assert.sameValue(options, undefined, "dateFromFields shouldn't be called with options"); + return super.dateFromFields(fields, options); + } + + yearMonthFromFields(fields, options) { + this.yearMonthFromFieldsCallCount++; + assert.sameValue(options, undefined, "yearMonthFromFields shouldn't be called with options"); + return super.yearMonthFromFields(fields, options); + } + + monthDayFromFields(fields, options) { + this.monthDayFromFieldsCallCount++; + assert.sameValue(options, undefined, "monthDayFromFields shouldn't be called with options"); + return super.monthDayFromFields(fields, options); + } + } + return new CalendarFromFieldsUndefinedOptions(); + }, + + /* + * A custom calendar that modifies the fields object passed in to + * dateFromFields, sabotaging its time properties. + */ + calendarMakeInfinityTime() { + class CalendarMakeInfinityTime extends Temporal.Calendar { + constructor() { + super("iso8601"); + } + + dateFromFields(fields, options) { + const retval = super.dateFromFields(fields, options); + fields.hour = Infinity; + fields.minute = Infinity; + fields.second = Infinity; + fields.millisecond = Infinity; + fields.microsecond = Infinity; + fields.nanosecond = Infinity; + return retval; + } + } + return new CalendarMakeInfinityTime(); + }, + + /* + * A custom calendar that defines getters on the fields object passed into + * dateFromFields that throw, sabotaging its time properties. + */ + calendarMakeInvalidGettersTime() { + class CalendarMakeInvalidGettersTime extends Temporal.Calendar { + constructor() { + super("iso8601"); + } + + dateFromFields(fields, options) { + const retval = super.dateFromFields(fields, options); + const throwingDescriptor = { + get() { + throw new Test262Error("reading a sabotaged time field"); + }, + }; + Object.defineProperties(fields, { + hour: throwingDescriptor, + minute: throwingDescriptor, + second: throwingDescriptor, + millisecond: throwingDescriptor, + microsecond: throwingDescriptor, + nanosecond: throwingDescriptor, + }); + return retval; + } + } + return new CalendarMakeInvalidGettersTime(); + }, + + /* + * A custom calendar whose mergeFields() method returns a proxy object with + * all of its Get and HasProperty operations observable, as well as adding a + * "shouldNotBeCopied": true property. + */ + calendarMergeFieldsGetters() { + class CalendarMergeFieldsGetters extends Temporal.Calendar { + constructor() { + super("iso8601"); + this.mergeFieldsReturnOperations = []; + } + + toString() { + return "merge-fields-getters"; + } + + dateFromFields(fields, options) { + assert.sameValue(fields.shouldNotBeCopied, undefined, "extra fields should not be copied"); + return super.dateFromFields(fields, options); + } + + yearMonthFromFields(fields, options) { + assert.sameValue(fields.shouldNotBeCopied, undefined, "extra fields should not be copied"); + return super.yearMonthFromFields(fields, options); + } + + monthDayFromFields(fields, options) { + assert.sameValue(fields.shouldNotBeCopied, undefined, "extra fields should not be copied"); + return super.monthDayFromFields(fields, options); + } + + mergeFields(fields, additionalFields) { + const retval = super.mergeFields(fields, additionalFields); + retval._calendar = this; + retval.shouldNotBeCopied = true; + return new Proxy(retval, { + get(target, key) { + target._calendar.mergeFieldsReturnOperations.push(`get ${key}`); + const result = target[key]; + if (result === undefined) { + return undefined; + } + return TemporalHelpers.toPrimitiveObserver(target._calendar.mergeFieldsReturnOperations, result, key); + }, + has(target, key) { + target._calendar.mergeFieldsReturnOperations.push(`has ${key}`); + return key in target; + }, + }); + } + } + return new CalendarMergeFieldsGetters(); + }, + + /* + * A custom calendar whose mergeFields() method returns a primitive value, + * given by @primitive, and which records the number of calls made to its + * dateFromFields(), yearMonthFromFields(), and monthDayFromFields() methods. + */ + calendarMergeFieldsReturnsPrimitive(primitive) { + class CalendarMergeFieldsPrimitive extends Temporal.Calendar { + constructor(mergeFieldsReturnValue) { + super("iso8601"); + this._mergeFieldsReturnValue = mergeFieldsReturnValue; + this.dateFromFieldsCallCount = 0; + this.monthDayFromFieldsCallCount = 0; + this.yearMonthFromFieldsCallCount = 0; + } + + toString() { + return "merge-fields-primitive"; + } + + dateFromFields(fields, options) { + this.dateFromFieldsCallCount++; + return super.dateFromFields(fields, options); + } + + yearMonthFromFields(fields, options) { + this.yearMonthFromFieldsCallCount++; + return super.yearMonthFromFields(fields, options); + } + + monthDayFromFields(fields, options) { + this.monthDayFromFieldsCallCount++; + return super.monthDayFromFields(fields, options); + } + + mergeFields() { + return this._mergeFieldsReturnValue; + } + } + return new CalendarMergeFieldsPrimitive(primitive); + }, + + /* + * observeProperty(calls, object, propertyName, value): + * + * Defines an own property @object.@propertyName with value @value, that + * will log any calls to its accessors to the array @calls. + */ + observeProperty(calls, object, propertyName, value) { + let displayName = propertyName; + if (typeof propertyName === 'symbol') { + if (Symbol.keyFor(propertyName) !== undefined) { + displayName = `[Symbol.for('${Symbol.keyFor(propertyName)}')]`; + } else if (propertyName.description.startsWith('Symbol.')) { + displayName = `[${propertyName.description}]`; + } else { + displayName = `[Symbol('${propertyName.description}')]` + } + } + Object.defineProperty(object, propertyName, { + get() { + calls.push(`get ${displayName}`); + return value; + }, + set(v) { + calls.push(`set ${displayName}`); + } + }); + }, + + /* + * A custom calendar that does not allow any of its methods to be called, for + * the purpose of asserting that a particular operation does not call into + * user code. + */ + calendarThrowEverything() { + class CalendarThrowEverything extends Temporal.Calendar { + constructor() { + super("iso8601"); + } + toString() { + TemporalHelpers.assertUnreachable("toString should not be called"); + } + dateFromFields() { + TemporalHelpers.assertUnreachable("dateFromFields should not be called"); + } + yearMonthFromFields() { + TemporalHelpers.assertUnreachable("yearMonthFromFields should not be called"); + } + monthDayFromFields() { + TemporalHelpers.assertUnreachable("monthDayFromFields should not be called"); + } + dateAdd() { + TemporalHelpers.assertUnreachable("dateAdd should not be called"); + } + dateUntil() { + TemporalHelpers.assertUnreachable("dateUntil should not be called"); + } + era() { + TemporalHelpers.assertUnreachable("era should not be called"); + } + eraYear() { + TemporalHelpers.assertUnreachable("eraYear should not be called"); + } + year() { + TemporalHelpers.assertUnreachable("year should not be called"); + } + month() { + TemporalHelpers.assertUnreachable("month should not be called"); + } + monthCode() { + TemporalHelpers.assertUnreachable("monthCode should not be called"); + } + day() { + TemporalHelpers.assertUnreachable("day should not be called"); + } + fields() { + TemporalHelpers.assertUnreachable("fields should not be called"); + } + mergeFields() { + TemporalHelpers.assertUnreachable("mergeFields should not be called"); + } + } + + return new CalendarThrowEverything(); + }, + + /* + * oneShiftTimeZone(shiftInstant, shiftNanoseconds): + * + * In the case of a spring-forward time zone offset transition (skipped time), + * and disambiguation === 'earlier', BuiltinTimeZoneGetInstantFor subtracts a + * negative number of nanoseconds from a PlainDateTime, which should balance + * with the microseconds field. + * + * This returns an instance of a custom time zone class which skips a length + * of time equal to shiftNanoseconds (a number), at the Temporal.Instant + * shiftInstant. Before shiftInstant, it's identical to UTC, and after + * shiftInstant it's a constant-offset time zone. + * + * It provides a getPossibleInstantsForCalledWith member which is an array + * with the result of calling toString() on any PlainDateTimes passed to + * getPossibleInstantsFor(). + */ + oneShiftTimeZone(shiftInstant, shiftNanoseconds) { + class OneShiftTimeZone extends Temporal.TimeZone { + constructor(shiftInstant, shiftNanoseconds) { + super("+00:00"); + this._shiftInstant = shiftInstant; + this._epoch1 = shiftInstant.epochNanoseconds; + this._epoch2 = this._epoch1 + BigInt(shiftNanoseconds); + this._shiftNanoseconds = shiftNanoseconds; + this._shift = new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, 0, this._shiftNanoseconds); + this.getPossibleInstantsForCalledWith = []; + } + + _isBeforeShift(instant) { + return instant.epochNanoseconds < this._epoch1; + } + + getOffsetNanosecondsFor(instant) { + return this._isBeforeShift(instant) ? 0 : this._shiftNanoseconds; + } + + getPossibleInstantsFor(plainDateTime) { + this.getPossibleInstantsForCalledWith.push(plainDateTime.toString()); + const [instant] = super.getPossibleInstantsFor(plainDateTime); + if (this._shiftNanoseconds > 0) { + if (this._isBeforeShift(instant)) return [instant]; + if (instant.epochNanoseconds < this._epoch2) return []; + return [instant.subtract(this._shift)]; + } + if (instant.epochNanoseconds < this._epoch2) return [instant]; + const shifted = instant.subtract(this._shift); + if (this._isBeforeShift(instant)) return [instant, shifted]; + return [shifted]; + } + + getNextTransition(instant) { + return this._isBeforeShift(instant) ? this._shiftInstant : null; + } + + getPreviousTransition(instant) { + return this._isBeforeShift(instant) ? null : this._shiftInstant; + } + + toString() { + return "Custom/One_Shift"; + } + } + return new OneShiftTimeZone(shiftInstant, shiftNanoseconds); + }, + + /* + * specificOffsetTimeZone(): + * + * This returns an instance of a custom time zone class, which returns a + * specific custom value from its getOffsetNanosecondsFrom() method. This is + * for the purpose of testing the validation of what this method returns. + * + * It also returns an empty array from getPossibleInstantsFor(), so as to + * trigger calls to getOffsetNanosecondsFor() when used from the + * BuiltinTimeZoneGetInstantFor operation. + */ + specificOffsetTimeZone(offsetValue) { + class SpecificOffsetTimeZone extends Temporal.TimeZone { + constructor(offsetValue) { + super("UTC"); + this._offsetValue = offsetValue; + } + + getOffsetNanosecondsFor() { + return this._offsetValue; + } + + getPossibleInstantsFor() { + return []; + } + } + return new SpecificOffsetTimeZone(offsetValue); + }, + + /* + * springForwardFallBackTimeZone(): + * + * This returns an instance of a custom time zone class that implements one + * single spring-forward/fall-back transition, for the purpose of testing the + * disambiguation option, without depending on system time zone data. + * + * The spring-forward occurs at epoch second 954669600 (2000-04-02T02:00 + * local) and goes from offset -08:00 to -07:00. + * + * The fall-back occurs at epoch second 972810000 (2000-10-29T02:00 local) and + * goes from offset -07:00 to -08:00. + */ + springForwardFallBackTimeZone() { + const { compare } = Temporal.PlainDateTime; + const springForwardLocal = new Temporal.PlainDateTime(2000, 4, 2, 2); + const springForwardEpoch = 954669600_000_000_000n; + const fallBackLocal = new Temporal.PlainDateTime(2000, 10, 29, 1); + const fallBackEpoch = 972810000_000_000_000n; + const winterOffset = new Temporal.TimeZone('-08:00'); + const summerOffset = new Temporal.TimeZone('-07:00'); + + class SpringForwardFallBackTimeZone extends Temporal.TimeZone { + constructor() { + super("-08:00"); + } + + getOffsetNanosecondsFor(instant) { + if (instant.epochNanoseconds < springForwardEpoch || + instant.epochNanoseconds >= fallBackEpoch) { + return winterOffset.getOffsetNanosecondsFor(instant); + } + return summerOffset.getOffsetNanosecondsFor(instant); + } + + getPossibleInstantsFor(datetime) { + if (compare(datetime, springForwardLocal) >= 0 && compare(datetime, springForwardLocal.add({ hours: 1 })) < 0) { + return []; + } + if (compare(datetime, fallBackLocal) >= 0 && compare(datetime, fallBackLocal.add({ hours: 1 })) < 0) { + return [summerOffset.getInstantFor(datetime), winterOffset.getInstantFor(datetime)]; + } + if (compare(datetime, springForwardLocal) < 0 || compare(datetime, fallBackLocal) >= 0) { + return [winterOffset.getInstantFor(datetime)]; + } + return [summerOffset.getInstantFor(datetime)]; + } + + getPreviousTransition(instant) { + if (instant.epochNanoseconds > fallBackEpoch) return new Temporal.Instant(fallBackEpoch); + if (instant.epochNanoseconds > springForwardEpoch) return new Temporal.Instant(springForwardEpoch); + return null; + } + + getNextTransition(instant) { + if (instant.epochNanoseconds < springForwardEpoch) return new Temporal.Instant(springForwardEpoch); + if (instant.epochNanoseconds < fallBackEpoch) return new Temporal.Instant(fallBackEpoch); + return null; + } + + toString() { + return "Custom/Spring_Fall"; + } + } + return new SpringForwardFallBackTimeZone(); + }, + + /* + * Returns an object that will append logs of any Gets or Calls of its valueOf + * or toString properties to the array calls. Both valueOf and toString will + * return the actual primitiveValue. propertyName is used in the log. + */ + toPrimitiveObserver(calls, primitiveValue, propertyName) { + return { + get valueOf() { + calls.push(`get ${propertyName}.valueOf`); + return function () { + calls.push(`call ${propertyName}.valueOf`); + return primitiveValue; + }; + }, + get toString() { + calls.push(`get ${propertyName}.toString`); + return function () { + calls.push(`call ${propertyName}.toString`); + if (primitiveValue === undefined) return undefined; + return primitiveValue.toString(); + }; + }, + }; + }, +}; diff --git a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toJSON/shell.js b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toJSON/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toJSON/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/TimeZone/prototype/toJSON/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/calendar-number.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/calendar-number.js new file mode 100644 index 000000000000..78bf65e0e98e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/calendar-number.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime +description: A number is converted to a string, then to Temporal.Calendar +features: [Temporal] +---*/ + +const arg = 19761118; + +const result = new Temporal.ZonedDateTime(0n, "UTC", arg); +assert.sameValue(result.calendar.id, "iso8601", "19761118 is a valid ISO string for Calendar"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => new Temporal.ZonedDateTime(0n, "UTC", arg), + `Number ${arg} does not convert to a valid ISO string for Calendar` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/calendar-wrong-type.js new file mode 100644 index 000000000000..95ad443b0bd5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/calendar-wrong-type.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for Calendar +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => new Temporal.ZonedDateTime(0n, "UTC", arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => new Temporal.ZonedDateTime(0n, "UTC", arg), `${description} is not a valid object and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..b1d19d5032c6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.compare +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const datetime = new Temporal.ZonedDateTime(217_123_200_000_000_000n, timeZone); +const calendar = "2016-12-31T23:59:60+00:00[UTC]"; + +let arg = { year: 1976, monthCode: "M11", day: 18, timeZone, calendar }; +const result1 = Temporal.ZonedDateTime.compare(arg, datetime); +assert.sameValue(result1, 0, "leap second is a valid ISO string for calendar (first argument)"); +const result2 = Temporal.ZonedDateTime.compare(datetime, arg); +assert.sameValue(result2, 0, "leap second is a valid ISO string for calendar (second argument)"); + +arg = { year: 1976, monthCode: "M11", day: 18, timeZone, calendar: { calendar } }; +const result3 = Temporal.ZonedDateTime.compare(arg, datetime); +assert.sameValue(result3, 0, "leap second is a valid ISO string for calendar (nested property, first argument)"); +const result4 = Temporal.ZonedDateTime.compare(datetime, arg); +assert.sameValue(result4, 0, "leap second is a valid ISO string for calendar (nested property, second argument)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..b6e69f71b042 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-number.js @@ -0,0 +1,59 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.compare +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const calendar = 19970327; + +const timeZone = new Temporal.TimeZone("UTC"); +const datetime = new Temporal.ZonedDateTime(0n, timeZone); + +let arg = { year: 1970, monthCode: "M01", day: 1, calendar, timeZone }; +const result1 = Temporal.ZonedDateTime.compare(arg, datetime); +assert.sameValue(result1, 0, "19970327 is a valid ISO string for calendar (first argument)"); +const result2 = Temporal.ZonedDateTime.compare(datetime, arg); +assert.sameValue(result2, 0, "19970327 is a valid ISO string for calendar (second argument)"); + +arg = { year: 1970, monthCode: "M01", day: 1, calendar: { calendar }, timeZone }; +const result3 = Temporal.ZonedDateTime.compare(arg, datetime); +assert.sameValue(result3, 0, "19970327 is a valid ISO string for calendar (nested property, first argument)"); +const result4 = Temporal.ZonedDateTime.compare(datetime, arg); +assert.sameValue(result4, 0, "19970327 is a valid ISO string for calendar (nested property, second argument)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1970, monthCode: "M01", day: 1, calendar, timeZone }; + assert.throws( + RangeError, + () => Temporal.ZonedDateTime.compare(arg, datetime), + `Number ${calendar} does not convert to a valid ISO string for calendar (first argument)` + ); + assert.throws( + RangeError, + () => Temporal.ZonedDateTime.compare(datetime, arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (second argument)` + ); + arg = { year: 1970, monthCode: "M01", day: 1, calendar: { calendar }, timeZone }; + assert.throws( + RangeError, + () => Temporal.ZonedDateTime.compare(arg, datetime), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property, first argument)` + ); + assert.throws( + RangeError, + () => Temporal.ZonedDateTime.compare(datetime, arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property, second argument)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..2001af036939 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,54 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.compare +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const datetime = new Temporal.ZonedDateTime(0n, new Temporal.TimeZone("UTC")); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => Temporal.ZonedDateTime.compare(arg, datetime), `${description} does not convert to a valid ISO string (first argument)`); + assert.throws(RangeError, () => Temporal.ZonedDateTime.compare(datetime, arg), `${description} does not convert to a valid ISO string (second argument)`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => Temporal.ZonedDateTime.compare(arg, datetime), `${description} does not convert to a valid ISO string (nested property, first argument)`); + assert.throws(RangeError, () => Temporal.ZonedDateTime.compare(datetime, arg), `${description} does not convert to a valid ISO string (nested property, second argument)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => Temporal.ZonedDateTime.compare(arg, datetime), `${description} is not a valid property bag and does not convert to a string (first argument)`); + assert.throws(TypeError, () => Temporal.ZonedDateTime.compare(datetime, arg), `${description} is not a valid property bag and does not convert to a string (second argument)`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => Temporal.ZonedDateTime.compare(arg, datetime), `${description} is not a valid property bag and does not convert to a string (nested property, first argument)`); + assert.throws(TypeError, () => Temporal.ZonedDateTime.compare(datetime, arg), `${description} is not a valid property bag and does not convert to a string (nested property, second argument)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => Temporal.ZonedDateTime.compare(arg, datetime), `nested undefined calendar property is always a RangeError (first argument)`); +assert.throws(RangeError, () => Temporal.ZonedDateTime.compare(datetime, arg), `nested undefined calendar property is always a RangeError (second argument)`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..e281ac1ec080 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.compare +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const datetime = new Temporal.ZonedDateTime(0n, new Temporal.TimeZone("UTC")); +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; + +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => Temporal.ZonedDateTime.compare(arg, datetime), + "reject minus zero as extended year (first argument)" + ); + assert.throws( + RangeError, + () => Temporal.ZonedDateTime.compare(datetime, arg), + "reject minus zero as extended year (second argument)" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/compare/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/compare/argument-wrong-type.js new file mode 100644 index 000000000000..c05d4ddffb71 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/compare/argument-wrong-type.js @@ -0,0 +1,43 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.compare +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for ZonedDateTime +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const other = new Temporal.ZonedDateTime(0n, timeZone); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => Temporal.ZonedDateTime.compare(arg, other), `${description} does not convert to a valid ISO string (first argument)`); + assert.throws(RangeError, () => Temporal.ZonedDateTime.compare(other, arg), `${description} does not convert to a valid ISO string (second argument)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.ZonedDateTime, "Temporal.ZonedDateTime, object"], + [Temporal.ZonedDateTime.prototype, "Temporal.ZonedDateTime.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => Temporal.ZonedDateTime.compare(arg, other), `${description} is not a valid property bag and does not convert to a string (first argument)`); + assert.throws(TypeError, () => Temporal.ZonedDateTime.compare(other, arg), `${description} is not a valid property bag and does not convert to a string (second argument)`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/compare/leap-second.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/compare/leap-second.js new file mode 100644 index 000000000000..73597bf29025 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/compare/leap-second.js @@ -0,0 +1,23 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.compare +description: Leap second is a valid ISO string for ZonedDateTime +features: [Temporal] +---*/ + +const datetime = new Temporal.ZonedDateTime(1_483_228_799_000_000_000n, new Temporal.TimeZone("UTC")); + +let arg = "2016-12-31T23:59:60+00:00[UTC]"; +const result1 = Temporal.ZonedDateTime.compare(arg, datetime); +assert.sameValue(result1, 0, "leap second is a valid ISO string for ZonedDateTime (first argument)"); +const result2 = Temporal.ZonedDateTime.compare(datetime, arg); +assert.sameValue(result2, 0, "leap second is a valid ISO string for ZonedDateTime (second argument)"); + +arg = "2000-05-02T12:34:56+23:59[+23:59:60]"; +assert.throws(RangeError, () => Temporal.ZonedDateTime.compare(arg, datetime), "leap second in time zone name not valid (first argument)"); +assert.throws(RangeError, () => Temporal.ZonedDateTime.compare(datetime, arg), "leap second in time zone name not valid (second argument)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/compare/timezone-string-leap-second.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/compare/timezone-string-leap-second.js new file mode 100644 index 000000000000..8044019f5e42 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/compare/timezone-string-leap-second.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.compare +description: Leap second is a valid ISO string for TimeZone +features: [Temporal] +---*/ + +const instance = new Temporal.ZonedDateTime(1588377600_000_000_000n, "UTC"); + +let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; + +const result1 = Temporal.ZonedDateTime.compare({ year: 2020, month: 5, day: 2, timeZone }, instance); +assert.sameValue(result1, 0, "leap second is a valid ISO string for TimeZone (first argument)"); +const result2 = Temporal.ZonedDateTime.compare(instance, { year: 2020, month: 5, day: 2, timeZone }); +assert.sameValue(result2, 0, "leap second is a valid ISO string for TimeZone (second argument)"); +const result3 = Temporal.ZonedDateTime.compare({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }, instance); +assert.sameValue(result3, 0, "leap second is a valid ISO string for TimeZone (nested property, first argument)"); +const result4 = Temporal.ZonedDateTime.compare(instance, { year: 2020, month: 5, day: 2, timeZone: { timeZone } }); +assert.sameValue(result4, 0, "leap second is a valid ISO string for TimeZone (nested property, second argument)"); + +timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; +assert.throws(RangeError, () => Temporal.ZonedDateTime.compare({ year: 2020, month: 5, day: 2, timeZone }, instance), "leap second in time zone name not valid (first argument)"); +assert.throws(RangeError, () => Temporal.ZonedDateTime.compare(instance, { year: 2020, month: 5, day: 2, timeZone }), "leap second in time zone name not valid (second argument)"); +assert.throws(RangeError, () => Temporal.ZonedDateTime.compare({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }, instance), "leap second in time zone name not valid (nested property, first argument)"); +assert.throws(RangeError, () => Temporal.ZonedDateTime.compare(instance, { year: 2020, month: 5, day: 2, timeZone: { timeZone } }), "leap second in time zone name not valid (nested property, second argument)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/compare/timezone-string-year-zero.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/compare/timezone-string-year-zero.js new file mode 100644 index 000000000000..c2e93eb4458d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/compare/timezone-string-year-zero.js @@ -0,0 +1,40 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.compare +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const datetime = new Temporal.ZonedDateTime(0n, new Temporal.TimeZone("UTC")); +const invalidStrings = [ + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+00:00[UTC]", +]; +invalidStrings.forEach((timeZone) => { + assert.throws( + RangeError, + () => Temporal.ZonedDateTime.compare({ year: 2020, month: 5, day: 2, timeZone }, datetime), + "reject minus zero as extended year (first argument)" + ); + assert.throws( + RangeError, + () => Temporal.ZonedDateTime.compare(datetime, { year: 2020, month: 5, day: 2, timeZone }), + "reject minus zero as extended year (second argument)" + ); + + assert.throws( + RangeError, + () => Temporal.ZonedDateTime.compare({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }, datetime), + "reject minus zero as extended year (nested property, first argument)" + ); + assert.throws( + RangeError, + () => Temporal.ZonedDateTime.compare(datetime, { year: 2020, month: 5, day: 2, timeZone: { timeZone } }), + "reject minus zero as extended year (nested property, second argument)" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/compare/timezone-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/compare/timezone-wrong-type.js new file mode 100644 index 000000000000..11d62ba90421 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/compare/timezone-wrong-type.js @@ -0,0 +1,46 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.compare +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for TimeZone +features: [BigInt, Symbol, Temporal] +---*/ + +const datetime = new Temporal.ZonedDateTime(0n, new Temporal.TimeZone("UTC")); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], +]; + +for (const [timeZone, description] of rangeErrorTests) { + assert.throws(RangeError, () => Temporal.ZonedDateTime.compare({ year: 2020, month: 5, day: 2, timeZone }, datetime), `${description} does not convert to a valid ISO string (first argument)`); + assert.throws(RangeError, () => Temporal.ZonedDateTime.compare(datetime, { year: 2020, month: 5, day: 2, timeZone }), `${description} does not convert to a valid ISO string (second argument)`); + assert.throws(RangeError, () => Temporal.ZonedDateTime.compare({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }, datetime), `${description} does not convert to a valid ISO string (nested property, first argument)`); + assert.throws(RangeError, () => Temporal.ZonedDateTime.compare(datetime, { year: 2020, month: 5, day: 2, timeZone: { timeZone } }), `${description} does not convert to a valid ISO string (nested property, second argument)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [timeZone, description] of typeErrorTests) { + assert.throws(TypeError, () => Temporal.ZonedDateTime.compare({ year: 2020, month: 5, day: 2, timeZone }, datetime), `${description} is not a valid object and does not convert to a string (first argument)`); + assert.throws(TypeError, () => Temporal.ZonedDateTime.compare(datetime, { year: 2020, month: 5, day: 2, timeZone }), `${description} is not a valid object and does not convert to a string (second argument)`); + assert.throws(TypeError, () => Temporal.ZonedDateTime.compare({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }, datetime), `${description} is not a valid object and does not convert to a string (nested property, first argument)`); + assert.throws(TypeError, () => Temporal.ZonedDateTime.compare(datetime, { year: 2020, month: 5, day: 2, timeZone: { timeZone } }), `${description} is not a valid object and does not convert to a string (nested property, second argument)`); +} + +const timeZone = undefined; +assert.throws(RangeError, () => Temporal.ZonedDateTime.compare({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }, datetime), `undefined is always a RangeError as nested property (first argument)`); +assert.throws(RangeError, () => Temporal.ZonedDateTime.compare(datetime, { year: 2020, month: 5, day: 2, timeZone: { timeZone } }), `undefined is always a RangeError as nested property (second argument)`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/compare/year-zero.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/compare/year-zero.js index 756f6d02dcbb..63a4601d7760 100644 --- a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/compare/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/compare/year-zero.js @@ -9,15 +9,21 @@ features: [Temporal] ---*/ const instance = new Temporal.ZonedDateTime(0n, "UTC"); -const bad = "-000000-08-19T17:30Z"; +const invalidStrings = [ + "-0000000-01-01T00:02Z[UTC]", + "-0000000-01-01T00:02+00:00[UTC]", + "-0000000-01-01T00:02:00.000000000+00:00[UTC]", +]; -assert.throws(RangeError, - () => Temporal.ZonedDateTime.compare(bad, instance), - "cannot use negative zero as extended year (first argument)" -); -assert.throws(RangeError, - () => Temporal.ZonedDateTime.compare(instance, bad), - "cannot use negative zero as extended year (second argument)" -); +invalidStrings.forEach((arg) => { + assert.throws(RangeError, + () => Temporal.ZonedDateTime.compare(arg, instance), + "cannot use negative zero as extended year (first argument)" + ); + assert.throws(RangeError, + () => Temporal.ZonedDateTime.compare(instance, arg), + "cannot use negative zero as extended year (second argument)" + ); +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..67b8dd3f39d5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.from +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const calendar = "2016-12-31T23:59:60+00:00[UTC]"; + +let arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; +const result1 = Temporal.ZonedDateTime.from(arg); +assert.sameValue( + result1.calendar.id, + "iso8601", + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar: { calendar } }; +const result2 = Temporal.ZonedDateTime.from(arg); +assert.sameValue( + result2.calendar.id, + "iso8601", + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..ba225e40c961 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-number.js @@ -0,0 +1,43 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.from +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const calendar = 19970327; + +const timeZone = new Temporal.TimeZone("UTC"); +let arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; +const result1 = Temporal.ZonedDateTime.from(arg); +assert.sameValue(result1.calendar.id, "iso8601", "19970327 is a valid ISO string for calendar"); + +arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar: { calendar } }; +const result2 = Temporal.ZonedDateTime.from(arg); +assert.sameValue(result2.calendar.id, "iso8601", "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; + assert.throws( + RangeError, + () => Temporal.ZonedDateTime.from(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar: { calendar } }; + assert.throws( + RangeError, + () => Temporal.ZonedDateTime.from(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..c0513706c72b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,47 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.from +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => Temporal.ZonedDateTime.from(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => Temporal.ZonedDateTime.from(arg), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => Temporal.ZonedDateTime.from(arg), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => Temporal.ZonedDateTime.from(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => Temporal.ZonedDateTime.from(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..06f618abd884 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.from +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; + +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => Temporal.ZonedDateTime.from(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/from/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/from/argument-wrong-type.js new file mode 100644 index 000000000000..82bf7eadedb0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/from/argument-wrong-type.js @@ -0,0 +1,38 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.from +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for ZonedDateTime +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => Temporal.ZonedDateTime.from(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.ZonedDateTime, "Temporal.ZonedDateTime, object"], + [Temporal.ZonedDateTime.prototype, "Temporal.ZonedDateTime.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => Temporal.ZonedDateTime.from(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/from/argument-zoneddatetime.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/from/argument-zoneddatetime.js new file mode 100644 index 000000000000..cd5f3f8f0934 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/from/argument-zoneddatetime.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.from +description: A ZonedDateTime object is copied, not returned directly +features: [Temporal] +---*/ + +const orig = new Temporal.ZonedDateTime(946684800_000_000_010n, new Temporal.TimeZone("UTC")); +const result = Temporal.ZonedDateTime.from(orig); + +assert.sameValue(result.epochNanoseconds, 946684800_000_000_010n, "ZonedDateTime is copied"); +assert.sameValue(result.timeZone, orig.timeZone, "time zone is the same"); +assert.sameValue(result.calendar, orig.calendar, "calendar is the same"); + +assert.notSameValue( + result, + orig, + "When a ZonedDateTime is given, the returned value is not the original ZonedDateTime" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/from/leap-second.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/from/leap-second.js new file mode 100644 index 000000000000..d35da7e29abe --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/from/leap-second.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.from +description: Leap second is a valid ISO string for ZonedDateTime +features: [Temporal] +---*/ + +let arg = "2016-12-31T23:59:60+00:00[UTC]"; +const result = Temporal.ZonedDateTime.from(arg); +assert.sameValue( + result.epochNanoseconds, + 1_483_228_799_000_000_000n, + "leap second is a valid ISO string for ZonedDateTime" +); + +arg = "2000-05-02T12:34:56+23:59[+23:59:60]"; +assert.throws( + RangeError, + () => Temporal.ZonedDateTime.from(arg), + "leap second in time zone name not valid" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/from/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/from/options-wrong-type.js new file mode 100644 index 000000000000..df44f9614849 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/from/options-wrong-type.js @@ -0,0 +1,25 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.from +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +for (const value of badOptions) { + assert.throws(TypeError, () => Temporal.ZonedDateTime.from({ year: 1976, month: 11, day: 18, timeZone: "UTC" }, value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/from/timezone-string-leap-second.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/from/timezone-string-leap-second.js new file mode 100644 index 000000000000..227efaf40d76 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/from/timezone-string-leap-second.js @@ -0,0 +1,22 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.from +description: Leap second is a valid ISO string for TimeZone +features: [Temporal] +---*/ + +let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; + +const result1 = Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone }); +assert.sameValue(result1.timeZone.id, "UTC", "leap second is a valid ISO string for TimeZone"); +const result2 = Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone: { timeZone } }); +assert.sameValue(result2.timeZone.id, "UTC", "leap second is a valid ISO string for TimeZone (nested property)"); + +timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; +assert.throws(RangeError, () => Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone }), "leap second in time zone name not valid"); +assert.throws(RangeError, () => Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone: { timeZone } }), "leap second in time zone name not valid (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/from/timezone-string-year-zero.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/from/timezone-string-year-zero.js new file mode 100644 index 000000000000..bfa2daf55793 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/from/timezone-string-year-zero.js @@ -0,0 +1,28 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.from +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+00:00[UTC]", +]; +invalidStrings.forEach((timeZone) => { + assert.throws( + RangeError, + () => Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone }), + "reject minus zero as extended year" + ); + assert.throws( + RangeError, + () => Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone: { timeZone } }), + "reject minus zero as extended year (nested property)" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/from/timezone-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/from/timezone-wrong-type.js new file mode 100644 index 000000000000..dabbac8391ce --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/from/timezone-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.from +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for TimeZone +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], +]; + +for (const [timeZone, description] of rangeErrorTests) { + assert.throws(RangeError, () => Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone }), `${description} does not convert to a valid ISO string`); + assert.throws(RangeError, () => Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone: { timeZone } }), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [timeZone, description] of typeErrorTests) { + assert.throws(TypeError, () => Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone }), `${description} is not a valid object and does not convert to a string`); + assert.throws(TypeError, () => Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone: { timeZone } }), `${description} is not a valid object and does not convert to a string (nested property)`); +} + +const timeZone = undefined; +assert.throws(RangeError, () => Temporal.ZonedDateTime.from({ year: 2000, month: 5, day: 2, timeZone: { timeZone } }), `undefined is always a RangeError as nested property`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/from/year-zero.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/from/year-zero.js index f58cc1c20cf4..5512ce864bc7 100644 --- a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/from/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/from/year-zero.js @@ -5,11 +5,21 @@ /*--- esid: sec-temporal.zoneddatetime.from description: Negative zero, as an extended year, is rejected -features: [Temporal] +features: [Temporal, arrow-function] ---*/ -const str = "-0000000-01-01T00:02:00.000000000+00:00[UTC]"; +const invalidStrings = [ + "-0000000-01-01T00:02Z[UTC]", + "-0000000-01-01T00:02+00:00[UTC]", + "-0000000-01-01T00:02:00.000000000+00:00[UTC]", +]; -assert.throws(RangeError, () => { Temporal.ZonedDateTime.from(str); }, "reject minus zero as extended year"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => Temporal.ZonedDateTime.from(arg), + "reject minus zero as extended year" + ); +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/add/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/add/options-wrong-type.js new file mode 100644 index 000000000000..72b66b703913 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/add/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.add +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.ZonedDateTime(0n, "UTC"); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.add({ years: 1 }, value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..7347d5747833 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.equals +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.ZonedDateTime(0n, timeZone); + +const calendar = "2016-12-31T23:59:60+00:00[UTC]"; + +let arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; +const result1 = instance.equals(arg); +assert.sameValue( + result1, + true, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar: { calendar } }; +const result2 = instance.equals(arg); +assert.sameValue( + result2, + true, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..6d77a6c0c204 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-number.js @@ -0,0 +1,45 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.equals +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.ZonedDateTime(0n, timeZone); + +const calendar = 19970327; + +let arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; +const result1 = instance.equals(arg); +assert.sameValue(result1, true, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar: { calendar } }; +const result2 = instance.equals(arg); +assert.sameValue(result2, true, "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; + assert.throws( + RangeError, + () => instance.equals(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.equals(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..6c586316f2e0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.equals +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.ZonedDateTime(0n, timeZone); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.equals(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.equals(arg), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.equals(arg), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.equals(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.equals(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..a8ad8eabe740 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,28 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.equals +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.ZonedDateTime(0n, timeZone); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.equals(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-wrong-type.js new file mode 100644 index 000000000000..78ea9a4919f9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/equals/argument-wrong-type.js @@ -0,0 +1,41 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.equals +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for ZonedDateTime +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.ZonedDateTime(0n, timeZone); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.equals(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.ZonedDateTime, "Temporal.ZonedDateTime, object"], + [Temporal.ZonedDateTime.prototype, "Temporal.ZonedDateTime.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.equals(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/equals/leap-second.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/equals/leap-second.js new file mode 100644 index 000000000000..454dc11cc3f5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/equals/leap-second.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.equals +description: Leap second is a valid ISO string for ZonedDateTime +features: [Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.ZonedDateTime(1_483_228_799_000_000_000n, timeZone); + +let arg = "2016-12-31T23:59:60+00:00[UTC]"; +const result = instance.equals(arg); +assert.sameValue( + result, + true, + "leap second is a valid ISO string for ZonedDateTime" +); + +arg = "2000-05-02T12:34:56+23:59[+23:59:60]"; +assert.throws( + RangeError, + () => instance.equals(arg), + "leap second in time zone name not valid" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/equals/timezone-string-leap-second.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/equals/timezone-string-leap-second.js new file mode 100644 index 000000000000..b41ac379584f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/equals/timezone-string-leap-second.js @@ -0,0 +1,21 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.equals +description: Leap second is a valid ISO string for TimeZone +features: [Temporal] +---*/ + +const instance = new Temporal.ZonedDateTime(1588377600_000_000_000n, new Temporal.TimeZone("UTC")); +let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; + +assert(instance.equals({ year: 2020, month: 5, day: 2, timeZone }), "leap second is a valid ISO string for TimeZone"); +assert(instance.equals({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }), "leap second is a valid ISO String for TimeZone (nested property)"); + +timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; +assert.throws(RangeError, () => instance.equals({ year: 2020, month: 5, day: 2, timeZone }), "leap second in time zone name not valid"); +assert.throws(RangeError, () => instance.equals({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }), "leap second in time zone name not valid (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/equals/timezone-string-year-zero.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/equals/timezone-string-year-zero.js new file mode 100644 index 000000000000..c87c7e2cea48 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/equals/timezone-string-year-zero.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.equals +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.ZonedDateTime(0n, new Temporal.TimeZone("UTC")); +invalidStrings.forEach((timeZone) => { + assert.throws( + RangeError, + () => instance.equals({ year: 2020, month: 5, day: 2, timeZone }), + "reject minus zero as extended year" + ); + assert.throws( + RangeError, + () => instance.equals({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }), + "reject minus zero as extended year (nested property)" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/equals/timezone-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/equals/timezone-wrong-type.js new file mode 100644 index 000000000000..9e5d654c6741 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/equals/timezone-wrong-type.js @@ -0,0 +1,41 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.equals +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for TimeZone +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.ZonedDateTime(0n, new Temporal.TimeZone("UTC")); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], +]; + +for (const [timeZone, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.equals({ year: 2020, month: 5, day: 2, timeZone }), `${description} does not convert to a valid ISO string`); + assert.throws(RangeError, () => instance.equals({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [timeZone, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.equals({ year: 2020, month: 5, day: 2, timeZone }), `${description} is not a valid object and does not convert to a string`); + assert.throws(TypeError, () => instance.equals({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }), `${description} is not a valid object and does not convert to a string (nested property)`); +} + +const timeZone = undefined; +assert.throws(RangeError, () => instance.equals({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }), `undefined is always a RangeError as nested property`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/equals/year-zero.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/equals/year-zero.js index ce266576a9ec..ff6d64d23c08 100644 --- a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/equals/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/equals/year-zero.js @@ -5,13 +5,22 @@ /*--- esid: sec-temporal.zoneddatetime.prototype.equals description: Negative zero, as an extended year, is rejected -features: [Temporal] +features: [Temporal, arrow-function] ---*/ +const invalidStrings = [ + "-0000000-01-01T00:02Z[UTC]", + "-0000000-01-01T00:02+00:00[UTC]", + "-0000000-01-01T00:02:00.000000000+00:00[UTC]", +]; const timeZone = new Temporal.TimeZone("UTC"); const instance = new Temporal.ZonedDateTime(0n, timeZone); -const str = "-0000000-01-01T00:02:00.000000000+00:00[UTC]"; - -assert.throws(RangeError, () => { instance.equals(str); }, "reject minus zero as extended year"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.equals(arg), + "reject minus zero as extended year" + ); +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/round/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/round/options-wrong-type.js new file mode 100644 index 000000000000..ac793733e1dd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/round/options-wrong-type.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.round +description: TypeError thrown when options argument is missing or a non-string primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + undefined, + null, + true, + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.ZonedDateTime(0n, "UTC"); +assert.throws(TypeError, () => instance.round(), "TypeError on missing options argument"); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.round(value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/round/rounding-direction.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/round/rounding-direction.js new file mode 100644 index 000000000000..a76653c7801b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/round/rounding-direction.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.round +description: Rounding down is towards the Big Bang, not the epoch or 1 BCE +features: [Temporal] +---*/ + +const instance = new Temporal.ZonedDateTime(-65_261_246_399_500_000_000n, "UTC"); // -000099-12-15T12:00:00.5Z +assert.sameValue( + instance.round({ smallestUnit: "second", roundingMode: "floor" }).epochNanoseconds, + -65_261_246_400_000_000_000n, // -000099-12-15T12:00:00Z + "Rounding down is towards the Big Bang, not the epoch or 1 BCE (roundingMode floor)" +); +assert.sameValue( + instance.round({ smallestUnit: "second", roundingMode: "trunc" }).epochNanoseconds, + -65_261_246_400_000_000_000n, // -000099-12-15T12:00:00Z + "Rounding down is towards the Big Bang, not the epoch or 1 BCE (roundingMode trunc)" +); +assert.sameValue( + instance.round({ smallestUnit: "second", roundingMode: "ceil" }).epochNanoseconds, + -65_261_246_399_000_000_000n, // -000099-12-15T12:00:01Z + "Rounding up is away from the Big Bang, not the epoch or 1 BCE (roundingMode ceil)" +); +assert.sameValue( + instance.round({ smallestUnit: "second", roundingMode: "halfExpand" }).epochNanoseconds, + -65_261_246_399_000_000_000n, // -000099-12-15T12:00:01Z + "Rounding up is away from the Big Bang, not the epoch or 1 BCE (roundingMode halfExpand)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/round/roundto-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/round/roundto-invalid-string.js new file mode 100644 index 000000000000..aea8885e46dc --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/round/roundto-invalid-string.js @@ -0,0 +1,36 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.round +description: RangeError thrown when smallestUnit option not one of the allowed string values +features: [Temporal] +---*/ + +const datetime = new Temporal.ZonedDateTime(1_000_000_000_123_987_500n, "UTC"); +const badValues = [ + "era", + "eraYear", + "year", + "month", + "week", + "millisecond\0", + "mill\u0131second", + "SECOND", + "eras", + "eraYears", + "years", + "months", + "weeks", + "milliseconds\0", + "mill\u0131seconds", + "SECONDS", + "other string", +]; +for (const smallestUnit of badValues) { + assert.throws(RangeError, () => datetime.round(smallestUnit), + `"${smallestUnit}" is not a valid value for smallest unit`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/round/smallestunit-disallowed-units.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/round/smallestunit-disallowed-units.js deleted file mode 100644 index e394beb73e05..000000000000 --- a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/round/smallestunit-disallowed-units.js +++ /dev/null @@ -1,35 +0,0 @@ -// |reftest| skip -- Temporal is not supported -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.zoneddatetime.prototype.round -description: Specifically disallowed units for the smallestUnit option -features: [Temporal, arrow-function] ----*/ - -const instance = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, "UTC"); -const invalidUnits = [ - "era", - "eras", - "year", - "month", - "week", - "years", - "months", - "weeks", -]; -invalidUnits.forEach((smallestUnit) => { - assert.throws( - RangeError, - () => instance.round({ smallestUnit }), - `{ smallestUnit: "${smallestUnit}" } should not be allowed as an argument to round` - ); - assert.throws( - RangeError, - () => instance.round(smallestUnit), - `"${smallestUnit}" should not be allowed as an argument to round` - ); -}); - -reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/round/smallestunit-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/round/smallestunit-invalid-string.js index 70768323ebcb..653bba22f55e 100644 --- a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/round/smallestunit-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/round/smallestunit-invalid-string.js @@ -9,6 +9,28 @@ features: [Temporal] ---*/ const datetime = new Temporal.ZonedDateTime(1_000_000_000_123_987_500n, "UTC"); -assert.throws(RangeError, () => datetime.round({ smallestUnit: "other string" })); +const badValues = [ + "era", + "eraYear", + "year", + "month", + "week", + "millisecond\0", + "mill\u0131second", + "SECOND", + "eras", + "eraYears", + "years", + "months", + "weeks", + "milliseconds\0", + "mill\u0131seconds", + "SECONDS", + "other string", +]; +for (const smallestUnit of badValues) { + assert.throws(RangeError, () => datetime.round({ smallestUnit }), + `"${smallestUnit}" is not a valid value for smallest unit`); +} reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..6c3af1a89870 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.since +description: Leap second is a valid ISO string for a calendar in a property bag +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.ZonedDateTime(0n, timeZone); + +const calendar = "2016-12-31T23:59:60+00:00[UTC]"; + +let arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; +const result1 = instance.since(arg); +TemporalHelpers.assertDuration( + result1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar: { calendar } }; +const result2 = instance.since(arg); +TemporalHelpers.assertDuration( + result2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..3111f819cc8e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-number.js @@ -0,0 +1,46 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.since +description: A number as calendar in a property bag is converted to a string, then to a calendar +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.ZonedDateTime(0n, timeZone); + +const calendar = 19970327; + +let arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; +const result1 = instance.since(arg); +TemporalHelpers.assertDuration(result1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar: { calendar } }; +const result2 = instance.since(arg); +TemporalHelpers.assertDuration(result2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; + assert.throws( + RangeError, + () => instance.since(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.since(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..2fd44222b112 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.since +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.ZonedDateTime(0n, timeZone); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.since(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.since(arg), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.since(arg), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.since(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.since(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..3699e301ee37 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,28 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.since +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.ZonedDateTime(0n, timeZone); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.since(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/argument-wrong-type.js new file mode 100644 index 000000000000..64ff354371ea --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/argument-wrong-type.js @@ -0,0 +1,41 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.since +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for ZonedDateTime +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.ZonedDateTime(0n, timeZone); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.since(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.ZonedDateTime, "Temporal.ZonedDateTime, object"], + [Temporal.ZonedDateTime.prototype, "Temporal.ZonedDateTime.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.since(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/largestunit-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/largestunit-invalid-string.js index 2c91b22a9e75..2060a4456174 100644 --- a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/largestunit-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/largestunit-invalid-string.js @@ -10,9 +10,22 @@ features: [Temporal] const earlier = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); const later = new Temporal.ZonedDateTime(1_000_090_061_987_654_321n, "UTC"); -const values = ["era", "eraYear", "other string"]; -for (const largestUnit of values) { - assert.throws(RangeError, () => later.since(earlier, { largestUnit })); +const badValues = [ + "era", + "eraYear", + "millisecond\0", + "mill\u0131second", + "SECOND", + "eras", + "eraYears", + "milliseconds\0", + "mill\u0131seconds", + "SECONDS", + "other string" +]; +for (const largestUnit of badValues) { + assert.throws(RangeError, () => later.since(earlier, { largestUnit }), + `"${largestUnit}" is not a valid value for largestUnit`); } reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/leap-second.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/leap-second.js new file mode 100644 index 000000000000..4c7a20b28f6a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/leap-second.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.since +description: Leap second is a valid ISO string for ZonedDateTime +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.ZonedDateTime(1_483_228_799_000_000_000n, timeZone); + +let arg = "2016-12-31T23:59:60+00:00[UTC]"; +const result = instance.since(arg); +TemporalHelpers.assertDuration( + result, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "leap second is a valid ISO string for ZonedDateTime" +); + +arg = "2000-05-02T12:34:56+23:59[+23:59:60]"; +assert.throws( + RangeError, + () => instance.since(arg), + "leap second in time zone name not valid" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/options-wrong-type.js new file mode 100644 index 000000000000..3fffc8ab3b51 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.since +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.ZonedDateTime(0n, "UTC"); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.since(new Temporal.ZonedDateTime(3600_000_000_000n, "UTC"), value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/smallestunit-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/smallestunit-invalid-string.js index c4e1324bc45b..b5f4a9dd99d3 100644 --- a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/smallestunit-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/smallestunit-invalid-string.js @@ -10,9 +10,22 @@ features: [Temporal] const earlier = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); const later = new Temporal.ZonedDateTime(1_000_090_061_987_654_321n, "UTC"); -const values = ["era", "eraYear", "other string"]; -for (const smallestUnit of values) { - assert.throws(RangeError, () => later.since(earlier, { smallestUnit })); +const badValues = [ + "era", + "eraYear", + "millisecond\0", + "mill\u0131second", + "SECOND", + "eras", + "eraYears", + "milliseconds\0", + "mill\u0131seconds", + "SECONDS", + "other string", +]; +for (const smallestUnit of badValues) { + assert.throws(RangeError, () => later.since(earlier, { smallestUnit }), + `"${smallestUnit}" is not a valid value for smallest unit`); } reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/timezone-string-leap-second.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/timezone-string-leap-second.js new file mode 100644 index 000000000000..2686b17818cc --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/timezone-string-leap-second.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.since +description: Leap second is a valid ISO string for TimeZone +features: [Temporal] +---*/ + +const expectedTimeZone = "UTC"; +const instance = new Temporal.ZonedDateTime(0n, expectedTimeZone); +let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; + +// These operations should produce expectedTimeZone, so the following operations +// should not throw due to the time zones being different on the receiver and +// the argument. + +instance.since({ year: 2020, month: 5, day: 2, timeZone }); +instance.since({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }); + +timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; +assert.throws(RangeError, () => instance.since({ year: 2020, month: 5, day: 2, timeZone }), "leap second in time zone name not valid"); +assert.throws(RangeError, () => instance.since({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }), "leap second in time zone name not valid (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/timezone-string-year-zero.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/timezone-string-year-zero.js new file mode 100644 index 000000000000..2bd77f5c9f01 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/timezone-string-year-zero.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.since +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.ZonedDateTime(0n, new Temporal.TimeZone("UTC")); +invalidStrings.forEach((timeZone) => { + assert.throws( + RangeError, + () => instance.since({ year: 2020, month: 5, day: 2, timeZone }), + "reject minus zero as extended year" + ); + assert.throws( + RangeError, + () => instance.since({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }), + "reject minus zero as extended year (nested property)" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/timezone-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/timezone-wrong-type.js new file mode 100644 index 000000000000..b38bcaf2e043 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/timezone-wrong-type.js @@ -0,0 +1,41 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.since +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for TimeZone +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.ZonedDateTime(0n, new Temporal.TimeZone("UTC")); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], +]; + +for (const [timeZone, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.since({ year: 2020, month: 5, day: 2, timeZone }), `${description} does not convert to a valid ISO string`); + assert.throws(RangeError, () => instance.since({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [timeZone, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.since({ year: 2020, month: 5, day: 2, timeZone }), `${description} is not a valid object and does not convert to a string`); + assert.throws(TypeError, () => instance.since({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }), `${description} is not a valid object and does not convert to a string (nested property)`); +} + +const timeZone = undefined; +assert.throws(RangeError, () => instance.since({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }), `undefined is always a RangeError as nested property`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/year-zero.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/year-zero.js index e1f97a10bc3a..e6962e2ec6c9 100644 --- a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/since/year-zero.js @@ -5,13 +5,22 @@ /*--- esid: sec-temporal.zoneddatetime.prototype.since description: Negative zero, as an extended year, is rejected -features: [Temporal] +features: [Temporal, arrow-function] ---*/ +const invalidStrings = [ + "-0000000-01-01T00:02Z[UTC]", + "-0000000-01-01T00:02+00:00[UTC]", + "-0000000-01-01T00:02:00.000000000+00:00[UTC]", +]; const timeZone = new Temporal.TimeZone("UTC"); const instance = new Temporal.ZonedDateTime(0n, timeZone); -const str = "-0000000-01-01T00:02:00.000000000+00:00[UTC]"; - -assert.throws(RangeError, () => { instance.since(str); }, "reject minus zero as extended year"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.since(arg), + "reject minus zero as extended year" + ); +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/subtract/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/subtract/options-wrong-type.js new file mode 100644 index 000000000000..75e62037298b --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/subtract/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.subtract +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.ZonedDateTime(0n, "UTC"); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.subtract({ years: 1 }, value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/fractionalseconddigits-auto.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/fractionalseconddigits-auto.js new file mode 100644 index 000000000000..7da6f1d5368f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/fractionalseconddigits-auto.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.tostring +description: auto value for fractionalSecondDigits option +features: [BigInt, Temporal] +---*/ + +const zeroSeconds = new Temporal.ZonedDateTime(0n, "UTC"); +const wholeSeconds = new Temporal.ZonedDateTime(30_000_000_000n, "UTC"); +const subSeconds = new Temporal.ZonedDateTime(30_123_400_000n, "UTC"); + +const tests = [ + [zeroSeconds, "1970-01-01T00:00:00+00:00[UTC]"], + [wholeSeconds, "1970-01-01T00:00:30+00:00[UTC]"], + [subSeconds, "1970-01-01T00:00:30.1234+00:00[UTC]"], +]; + +for (const [datetime, expected] of tests) { + assert.sameValue(datetime.toString(), expected, "default is to emit seconds and drop trailing zeroes"); + assert.sameValue(datetime.toString({ fractionalSecondDigits: "auto" }), expected, "auto is the default"); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/fractionalseconddigits-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/fractionalseconddigits-invalid-string.js index d9f0b319ea2d..2ef0ca7612bc 100644 --- a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/fractionalseconddigits-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/fractionalseconddigits-invalid-string.js @@ -10,13 +10,16 @@ info: | 4. If _stringValues_ is not *undefined* and _stringValues_ does not contain an element equal to _value_, throw a *RangeError* exception. sec-temporal-tosecondsstringprecision step 9: 9. Let _digits_ be ? GetStringOrNumberOption(_normalizedOptions_, *"fractionalSecondDigits"*, « *"auto"* », 0, 9, *"auto"*). - sec-temporal.instant.prototype.tostring step 4: - 4. Let _precision_ be ? ToDurationSecondsStringPrecision(_options_). + sec-temporal.zoneddatetime.prototype.tostring step 4: + 4. Let _precision_ be ? ToSecondsStringPrecision(_options_). features: [Temporal] ---*/ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_650_000n, "UTC"); -assert.throws(RangeError, () => datetime.toString({ fractionalSecondDigits: "other string" })); +for (const fractionalSecondDigits of ["other string", "AUTO", "not-auto", "autos", "auto\0"]) { + assert.throws(RangeError, () => datetime.toString({ fractionalSecondDigits }), + `"${fractionalSecondDigits}" is not a valid value for fractionalSecondDigits`); +} reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/fractionalseconddigits-non-integer.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/fractionalseconddigits-non-integer.js index 4d40e23ed6e9..3b16b5f06b32 100644 --- a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/fractionalseconddigits-non-integer.js +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/fractionalseconddigits-non-integer.js @@ -11,7 +11,7 @@ info: | sec-temporal-tosecondsstringprecision step 9: 9. Let _digits_ be ? GetStringOrNumberOption(_normalizedOptions_, *"fractionalSecondDigits"*, « *"auto"* », 0, 9, *"auto"*). sec-temporal.zoneddatetime.prototype.tostring step 4: - 4. Let _precision_ be ? ToDurationSecondsStringPrecision(_options_). + 4. Let _precision_ be ? ToSecondsStringPrecision(_options_). features: [Temporal] ---*/ diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/fractionalseconddigits-number.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/fractionalseconddigits-number.js new file mode 100644 index 000000000000..62721ba676e7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/fractionalseconddigits-number.js @@ -0,0 +1,36 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.tostring +description: Number for fractionalSecondDigits option +features: [BigInt, Temporal] +---*/ + +const zeroSeconds = new Temporal.ZonedDateTime(0n, "UTC"); +const wholeSeconds = new Temporal.ZonedDateTime(30_000_000_000n, "UTC"); +const subSeconds = new Temporal.ZonedDateTime(30_123_400_000n, "UTC"); + +assert.sameValue(subSeconds.toString({ fractionalSecondDigits: 0 }), "1970-01-01T00:00:30+00:00[UTC]", + "truncates 4 decimal places to 0"); +assert.sameValue(zeroSeconds.toString({ fractionalSecondDigits: 2 }), "1970-01-01T00:00:00.00+00:00[UTC]", + "pads zero seconds to 2 decimal places"); +assert.sameValue(wholeSeconds.toString({ fractionalSecondDigits: 2 }), "1970-01-01T00:00:30.00+00:00[UTC]", + "pads whole seconds to 2 decimal places"); +assert.sameValue(subSeconds.toString({ fractionalSecondDigits: 2 }), "1970-01-01T00:00:30.12+00:00[UTC]", + "truncates 4 decimal places to 2"); +assert.sameValue(subSeconds.toString({ fractionalSecondDigits: 3 }), "1970-01-01T00:00:30.123+00:00[UTC]", + "truncates 4 decimal places to 3"); +assert.sameValue(subSeconds.toString({ fractionalSecondDigits: 6 }), "1970-01-01T00:00:30.123400+00:00[UTC]", + "pads 4 decimal places to 6"); +assert.sameValue(zeroSeconds.toString({ fractionalSecondDigits: 7 }), "1970-01-01T00:00:00.0000000+00:00[UTC]", + "pads zero seconds to 7 decimal places"); +assert.sameValue(wholeSeconds.toString({ fractionalSecondDigits: 7 }), "1970-01-01T00:00:30.0000000+00:00[UTC]", + "pads whole seconds to 7 decimal places"); +assert.sameValue(subSeconds.toString({ fractionalSecondDigits: 7 }), "1970-01-01T00:00:30.1234000+00:00[UTC]", + "pads 4 decimal places to 7"); +assert.sameValue(subSeconds.toString({ fractionalSecondDigits: 9 }), "1970-01-01T00:00:30.123400000+00:00[UTC]", + "pads 4 decimal places to 9"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/fractionalseconddigits-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/fractionalseconddigits-out-of-range.js index 72e8cf6b69ed..b6251bf08866 100644 --- a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/fractionalseconddigits-out-of-range.js +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/fractionalseconddigits-out-of-range.js @@ -11,13 +11,19 @@ info: | sec-temporal-tosecondsstringprecision step 9: 9. Let _digits_ be ? GetStringOrNumberOption(_normalizedOptions_, *"fractionalSecondDigits"*, « *"auto"* », 0, 9, *"auto"*). sec-temporal.zoneddatetime.prototype.tostring step 4: - 4. Let _precision_ be ? ToDurationSecondsStringPrecision(_options_). + 4. Let _precision_ be ? ToSecondsStringPrecision(_options_). features: [Temporal] ---*/ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_650_000n, "UTC"); -assert.throws(RangeError, () => datetime.toString({ fractionalSecondDigits: -1 })); -assert.throws(RangeError, () => datetime.toString({ fractionalSecondDigits: 10 })); +assert.throws(RangeError, () => datetime.toString({ fractionalSecondDigits: -Infinity }), + "−∞ is out of range for fractionalSecondDigits"); +assert.throws(RangeError, () => datetime.toString({ fractionalSecondDigits: -1 }), + "−1 is out of range for fractionalSecondDigits"); +assert.throws(RangeError, () => datetime.toString({ fractionalSecondDigits: 10 }), + "10 is out of range for fractionalSecondDigits"); +assert.throws(RangeError, () => datetime.toString({ fractionalSecondDigits: Infinity }), + "∞ is out of range for fractionalSecondDigits"); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/fractionalseconddigits-undefined.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/fractionalseconddigits-undefined.js index c1ea7eb7daa4..d3305e830741 100644 --- a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/fractionalseconddigits-undefined.js +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/fractionalseconddigits-undefined.js @@ -9,19 +9,33 @@ info: | sec-getoption step 3: 3. If _value_ is *undefined*, return _fallback_. sec-getstringornumberoption step 2: - 2. Let _value_ be ? GetOption(_options_, _property_, *"stringOrNumber"*, *undefined*, _fallback_). + 2. Let _value_ be ? GetOption(_options_, _property_, « Number, String », *undefined*, _fallback_). sec-temporal-tosecondsstringprecision step 9: 9. Let _digits_ be ? GetStringOrNumberOption(_normalizedOptions_, *"fractionalSecondDigits"*, « *"auto"* », 0, 9, *"auto"*). sec-temporal.zoneddatetime.prototype.tostring step 4: - 4. Let _precision_ be ? ToDurationSecondsStringPrecision(_options_). + 4. Let _precision_ be ? ToSecondsStringPrecision(_options_). features: [Temporal] ---*/ -const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_650_000n, "UTC"); +const zeroSeconds = new Temporal.ZonedDateTime(0n, "UTC"); +const wholeSeconds = new Temporal.ZonedDateTime(30_000_000_000n, "UTC"); +const subSeconds = new Temporal.ZonedDateTime(30_123_400_000n, "UTC"); -const explicit = datetime.toString({ fractionalSecondDigits: undefined }); -assert.sameValue(explicit, "2001-09-09T01:46:40.98765+00:00[UTC]", "default fractionalSecondDigits is auto"); +const tests = [ + [zeroSeconds, "1970-01-01T00:00:00+00:00[UTC]"], + [wholeSeconds, "1970-01-01T00:00:30+00:00[UTC]"], + [subSeconds, "1970-01-01T00:00:30.1234+00:00[UTC]"], +]; -// See options-undefined.js for {} +for (const [datetime, expected] of tests) { + const explicit = datetime.toString({ fractionalSecondDigits: undefined }); + assert.sameValue(explicit, expected, "default fractionalSecondDigits is auto (property present but undefined)"); + + const implicit = datetime.toString({}); + assert.sameValue(implicit, expected, "default fractionalSecondDigits is auto (property not present)"); + + const lambda = datetime.toString(() => {}); + assert.sameValue(lambda, expected, "default fractionalSecondDigits is auto (property not present, function object)"); +} reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/fractionalseconddigits-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/fractionalseconddigits-wrong-type.js index 2b82767ab51f..a534daf9b84e 100644 --- a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/fractionalseconddigits-wrong-type.js +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/fractionalseconddigits-wrong-type.js @@ -23,6 +23,28 @@ features: [Temporal] ---*/ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_650_000n, "UTC"); -TemporalHelpers.checkFractionalSecondDigitsOptionWrongType(datetime); + +assert.throws(RangeError, () => datetime.toString({ fractionalSecondDigits: null }), + "null is not a number and converts to the string 'null' which is not valid for fractionalSecondDigits"); +assert.throws(RangeError, () => datetime.toString({ fractionalSecondDigits: true }), + "true is not a number and converts to the string 'true' which is not valid for fractionalSecondDigits"); +assert.throws(RangeError, () => datetime.toString({ fractionalSecondDigits: false }), + "false is not a number and converts to the string 'false' which is not valid for fractionalSecondDigits"); +assert.throws(TypeError, () => datetime.toString({ fractionalSecondDigits: Symbol() }), + "symbols are not numbers and cannot convert to strings"); +assert.throws(RangeError, () => datetime.toString({ fractionalSecondDigits: 2n }), + "bigints are not numbers and convert to strings which are not valid for fractionalSecondDigits"); +assert.throws(RangeError, () => datetime.toString({ fractionalSecondDigits: {} }), + "plain objects are not numbers and convert to strings which are not valid for fractionalSecondDigits"); + +const expected = [ + "get fractionalSecondDigits.toString", + "call fractionalSecondDigits.toString", +]; +const actual = []; +const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); +const result = datetime.toString({ fractionalSecondDigits: observer }); +assert.sameValue(result, "2001-09-09T01:46:40.98765+00:00[UTC]", "object with toString uses toString return value"); +assert.compareArray(actual, expected, "object with toString calls toString and not valueOf"); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/options-wrong-type.js new file mode 100644 index 000000000000..9a7cbddadafd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.tostring +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.ZonedDateTime(0n, "UTC"); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.toString(value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/rounding-cross-midnight.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/rounding-cross-midnight.js new file mode 100644 index 000000000000..4a44c926163e --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/rounding-cross-midnight.js @@ -0,0 +1,16 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.tostring +description: Rounding can cross midnight +features: [Temporal] +---*/ + +const zonedDateTime = new Temporal.ZonedDateTime(946_684_799_999_999_999n, "UTC"); // one nanosecond before 2000-01-01T00:00:00 +for (const roundingMode of ["ceil", "halfExpand"]) { + assert.sameValue(zonedDateTime.toString({ fractionalSecondDigits: 8, roundingMode }), "2000-01-01T00:00:00.00000000+00:00[UTC]"); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/rounding-direction.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/rounding-direction.js new file mode 100644 index 000000000000..f46b24ac9712 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/rounding-direction.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.tostring +description: Rounding down is towards the Big Bang, not the epoch or 1 BCE +features: [Temporal] +---*/ + +const instance = new Temporal.ZonedDateTime(-65_261_246_399_500_000_000n, "UTC"); // -000099-12-15T12:00:00.5Z +assert.sameValue( + instance.toString({ smallestUnit: "second", roundingMode: "floor" }), + "-000099-12-15T12:00:00+00:00[UTC]", + "Rounding down is towards the Big Bang, not the epoch or 1 BCE" +); +assert.sameValue( + instance.toString({ smallestUnit: "second", roundingMode: "trunc" }), + "-000099-12-15T12:00:00+00:00[UTC]", + "Rounding down is towards the Big Bang, not the epoch or 1 BCE (roundingMode trunc)" +); +assert.sameValue( + instance.toString({ smallestUnit: "second", roundingMode: "ceil" }), + "-000099-12-15T12:00:01+00:00[UTC]", + "Rounding up is away from the Big Bang, not the epoch or 1 BCE (roundingMode ceil)" +); +assert.sameValue( + instance.toString({ smallestUnit: "second", roundingMode: "halfExpand" }), + "-000099-12-15T12:00:01+00:00[UTC]", + "Rounding up is away from the Big Bang, not the epoch or 1 BCE (roundingMode halfExpand)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/roundingmode-ceil.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/roundingmode-ceil.js new file mode 100644 index 000000000000..5c71b8e0196a --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/roundingmode-ceil.js @@ -0,0 +1,40 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.tostring +description: ceil value for roundingMode option +features: [Temporal] +---*/ + +const datetime = new Temporal.ZonedDateTime(1_000_000_000_123_987_500n, "UTC"); + +const result1 = datetime.toString({ smallestUnit: "microsecond", roundingMode: "ceil" }); +assert.sameValue(result1, "2001-09-09T01:46:40.123988+00:00[UTC]", + "roundingMode is ceil (with 6 digits from smallestUnit)"); + +const result2 = datetime.toString({ fractionalSecondDigits: 6, roundingMode: "ceil" }); +assert.sameValue(result2, "2001-09-09T01:46:40.123988+00:00[UTC]", + "roundingMode is ceil (with 6 digits from fractionalSecondDigits)"); + +const result3 = datetime.toString({ smallestUnit: "millisecond", roundingMode: "ceil" }); +assert.sameValue(result3, "2001-09-09T01:46:40.124+00:00[UTC]", + "roundingMode is ceil (with 3 digits from smallestUnit)"); + +const result4 = datetime.toString({ fractionalSecondDigits: 3, roundingMode: "ceil" }); +assert.sameValue(result4, "2001-09-09T01:46:40.124+00:00[UTC]", + "roundingMode is ceil (with 3 digits from fractionalSecondDigits)"); + +const result5 = datetime.toString({ smallestUnit: "second", roundingMode: "ceil" }); +assert.sameValue(result5, "2001-09-09T01:46:41+00:00[UTC]", + "roundingMode is ceil (with 0 digits from smallestUnit)"); + +const result6 = datetime.toString({ fractionalSecondDigits: 0, roundingMode: "ceil" }); +assert.sameValue(result6, "2001-09-09T01:46:41+00:00[UTC]", + "roundingMode is ceil (with 0 digits from fractionalSecondDigits)"); + +const result7 = datetime.toString({ smallestUnit: "minute", roundingMode: "ceil" }); +assert.sameValue(result7, "2001-09-09T01:47+00:00[UTC]", "roundingMode is ceil (round to minute)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/roundingmode-floor.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/roundingmode-floor.js new file mode 100644 index 000000000000..94e783df48bf --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/roundingmode-floor.js @@ -0,0 +1,40 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.tostring +description: floor value for roundingMode option +features: [Temporal] +---*/ + +const datetime = new Temporal.ZonedDateTime(1_000_000_000_123_987_500n, "UTC"); + +const result1 = datetime.toString({ smallestUnit: "microsecond", roundingMode: "floor" }); +assert.sameValue(result1, "2001-09-09T01:46:40.123987+00:00[UTC]", + "roundingMode is floor (with 6 digits from smallestUnit)"); + +const result2 = datetime.toString({ fractionalSecondDigits: 6, roundingMode: "floor" }); +assert.sameValue(result2, "2001-09-09T01:46:40.123987+00:00[UTC]", + "roundingMode is floor (with 6 digits from fractionalSecondDigits)"); + +const result3 = datetime.toString({ smallestUnit: "millisecond", roundingMode: "floor" }); +assert.sameValue(result3, "2001-09-09T01:46:40.123+00:00[UTC]", + "roundingMode is floor (with 3 digits from smallestUnit)"); + +const result4 = datetime.toString({ fractionalSecondDigits: 3, roundingMode: "floor" }); +assert.sameValue(result4, "2001-09-09T01:46:40.123+00:00[UTC]", + "roundingMode is floor (with 3 digits from fractionalSecondDigits)"); + +const result5 = datetime.toString({ smallestUnit: "second", roundingMode: "floor" }); +assert.sameValue(result5, "2001-09-09T01:46:40+00:00[UTC]", + "roundingMode is floor (with 0 digits from smallestUnit)"); + +const result6 = datetime.toString({ fractionalSecondDigits: 0, roundingMode: "floor" }); +assert.sameValue(result6, "2001-09-09T01:46:40+00:00[UTC]", + "roundingMode is floor (with 0 digits from fractionalSecondDigits)"); + +const result7 = datetime.toString({ smallestUnit: "minute", roundingMode: "floor" }); +assert.sameValue(result7, "2001-09-09T01:46+00:00[UTC]", "roundingMode is floor (round to minute)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/roundingmode-halfExpand.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/roundingmode-halfExpand.js new file mode 100644 index 000000000000..69ae68d32aaa --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/roundingmode-halfExpand.js @@ -0,0 +1,40 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.tostring +description: halfExpand value for roundingMode option +features: [Temporal] +---*/ + +const datetime = new Temporal.ZonedDateTime(1_000_000_000_123_987_500n, "UTC"); + +const result1 = datetime.toString({ smallestUnit: "microsecond", roundingMode: "halfExpand" }); +assert.sameValue(result1, "2001-09-09T01:46:40.123988+00:00[UTC]", + "roundingMode is halfExpand (with 6 digits from smallestUnit)"); + +const result2 = datetime.toString({ fractionalSecondDigits: 6, roundingMode: "halfExpand" }); +assert.sameValue(result2, "2001-09-09T01:46:40.123988+00:00[UTC]", + "roundingMode is halfExpand (with 6 digits from fractionalSecondDigits)"); + +const result3 = datetime.toString({ smallestUnit: "millisecond", roundingMode: "halfExpand" }); +assert.sameValue(result3, "2001-09-09T01:46:40.124+00:00[UTC]", + "roundingMode is halfExpand (with 3 digits from smallestUnit)"); + +const result4 = datetime.toString({ fractionalSecondDigits: 3, roundingMode: "halfExpand" }); +assert.sameValue(result4, "2001-09-09T01:46:40.124+00:00[UTC]", + "roundingMode is halfExpand (with 3 digits from fractionalSecondDigits)"); + +const result5 = datetime.toString({ smallestUnit: "second", roundingMode: "halfExpand" }); +assert.sameValue(result5, "2001-09-09T01:46:40+00:00[UTC]", + "roundingMode is halfExpand (with 0 digits from smallestUnit)"); + +const result6 = datetime.toString({ fractionalSecondDigits: 0, roundingMode: "halfExpand" }); +assert.sameValue(result6, "2001-09-09T01:46:40+00:00[UTC]", + "roundingMode is halfExpand (with 0 digits from fractionalSecondDigits)"); + +const result7 = datetime.toString({ smallestUnit: "minute", roundingMode: "halfExpand" }); +assert.sameValue(result7, "2001-09-09T01:47+00:00[UTC]", "roundingMode is halfExpand (round to minute)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/roundingmode-trunc.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/roundingmode-trunc.js new file mode 100644 index 000000000000..5abd7286a998 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/roundingmode-trunc.js @@ -0,0 +1,40 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.tostring +description: trunc value for roundingMode option +features: [Temporal] +---*/ + +const datetime = new Temporal.ZonedDateTime(1_000_000_000_123_987_500n, "UTC"); + +const result1 = datetime.toString({ smallestUnit: "microsecond", roundingMode: "trunc" }); +assert.sameValue(result1, "2001-09-09T01:46:40.123987+00:00[UTC]", + "roundingMode is trunc (with 6 digits from smallestUnit)"); + +const result2 = datetime.toString({ fractionalSecondDigits: 6, roundingMode: "trunc" }); +assert.sameValue(result2, "2001-09-09T01:46:40.123987+00:00[UTC]", + "roundingMode is trunc (with 6 digits from fractionalSecondDigits)"); + +const result3 = datetime.toString({ smallestUnit: "millisecond", roundingMode: "trunc" }); +assert.sameValue(result3, "2001-09-09T01:46:40.123+00:00[UTC]", + "roundingMode is trunc (with 3 digits from smallestUnit)"); + +const result4 = datetime.toString({ fractionalSecondDigits: 3, roundingMode: "trunc" }); +assert.sameValue(result4, "2001-09-09T01:46:40.123+00:00[UTC]", + "roundingMode is trunc (with 3 digits from fractionalSecondDigits)"); + +const result5 = datetime.toString({ smallestUnit: "second", roundingMode: "trunc" }); +assert.sameValue(result5, "2001-09-09T01:46:40+00:00[UTC]", + "roundingMode is trunc (with 0 digits from smallestUnit)"); + +const result6 = datetime.toString({ fractionalSecondDigits: 0, roundingMode: "trunc" }); +assert.sameValue(result6, "2001-09-09T01:46:40+00:00[UTC]", + "roundingMode is trunc (with 0 digits from fractionalSecondDigits)"); + +const result7 = datetime.toString({ smallestUnit: "minute", roundingMode: "trunc" }); +assert.sameValue(result7, "2001-09-09T01:46+00:00[UTC]", "roundingMode is trunc (round to minute)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/smallestunit-fractionalseconddigits.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/smallestunit-fractionalseconddigits.js new file mode 100644 index 000000000000..b82caece2b2f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/smallestunit-fractionalseconddigits.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.tostring +description: fractionalSecondDigits option is not used with smallestUnit present +features: [Temporal] +---*/ + +const datetime = new Temporal.ZonedDateTime(56_789_999_999n, "UTC"); +const tests = [ + ["minute", "1970-01-01T00:00+00:00[UTC]"], + ["second", "1970-01-01T00:00:56+00:00[UTC]"], + ["millisecond", "1970-01-01T00:00:56.789+00:00[UTC]"], + ["microsecond", "1970-01-01T00:00:56.789999+00:00[UTC]"], + ["nanosecond", "1970-01-01T00:00:56.789999999+00:00[UTC]"], +]; + +for (const [smallestUnit, expected] of tests) { + const string = datetime.toString({ + smallestUnit, + get fractionalSecondDigits() { throw new Test262Error("should not get fractionalSecondDigits") } + }); + assert.sameValue(string, expected, `smallestUnit: "${smallestUnit}" overrides fractionalSecondDigits`); +} + +assert.throws(RangeError, () => datetime.toString({ + smallestUnit: "hour", + get fractionalSecondDigits() { throw new Test262Error("should not get fractionalSecondDigits") } +}), "hour is an invalid smallestUnit but still overrides fractionalSecondDigits"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/smallestunit-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/smallestunit-invalid-string.js index 7a8d748ea137..03537a1356bd 100644 --- a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/smallestunit-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/smallestunit-invalid-string.js @@ -9,6 +9,32 @@ features: [Temporal] ---*/ const datetime = new Temporal.ZonedDateTime(1_000_000_000_123_987_500n, "UTC"); -assert.throws(RangeError, () => datetime.toString({ smallestUnit: "other string" })); +const badValues = [ + "era", + "eraYear", + "year", + "month", + "week", + "day", + "hour", + "millisecond\0", + "mill\u0131second", + "SECOND", + "eras", + "eraYears", + "years", + "months", + "weeks", + "days", + "hours", + "milliseconds\0", + "mill\u0131seconds", + "SECONDS", + "other string", +]; +for (const smallestUnit of badValues) { + assert.throws(RangeError, () => datetime.toString({ smallestUnit }), + `"${smallestUnit}" is not a valid value for smallest unit`); +} reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/smallestunit-valid-units.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/smallestunit-valid-units.js index f3a407bce3ce..f41cd35c55bb 100644 --- a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/smallestunit-valid-units.js +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/toString/smallestunit-valid-units.js @@ -10,13 +10,39 @@ features: [Temporal] const datetime = new Temporal.ZonedDateTime(1_000_000_000_123_456_789n, "UTC"); -assert.sameValue(datetime.toString({ smallestUnit: "minute" }), "2001-09-09T01:46+00:00[UTC]"); -assert.sameValue(datetime.toString({ smallestUnit: "second" }), "2001-09-09T01:46:40+00:00[UTC]"); -assert.sameValue(datetime.toString({ smallestUnit: "millisecond" }), "2001-09-09T01:46:40.123+00:00[UTC]"); -assert.sameValue(datetime.toString({ smallestUnit: "microsecond" }), "2001-09-09T01:46:40.123456+00:00[UTC]"); -assert.sameValue(datetime.toString({ smallestUnit: "nanosecond" }), "2001-09-09T01:46:40.123456789+00:00[UTC]"); +function test(instance, expectations, description) { + for (const [smallestUnit, expectedResult] of expectations) { + assert.sameValue(instance.toString({ smallestUnit }), expectedResult, + `${description} with smallestUnit "${smallestUnit}"`); + } +} + +test( + datetime, + [ + ["minute", "2001-09-09T01:46+00:00[UTC]"], + ["second", "2001-09-09T01:46:40+00:00[UTC]"], + ["millisecond", "2001-09-09T01:46:40.123+00:00[UTC]"], + ["microsecond", "2001-09-09T01:46:40.123456+00:00[UTC]"], + ["nanosecond", "2001-09-09T01:46:40.123456789+00:00[UTC]"], + ], + "subseconds toString" +); + +test( + new Temporal.ZonedDateTime(999_999_960_000_000_000n, "UTC"), + [ + ["minute", "2001-09-09T01:46+00:00[UTC]"], + ["second", "2001-09-09T01:46:00+00:00[UTC]"], + ["millisecond", "2001-09-09T01:46:00.000+00:00[UTC]"], + ["microsecond", "2001-09-09T01:46:00.000000+00:00[UTC]"], + ["nanosecond", "2001-09-09T01:46:00.000000000+00:00[UTC]"], + ], + "whole minutes toString" +); const notValid = [ + "era", "year", "month", "week", @@ -25,7 +51,8 @@ const notValid = [ ]; notValid.forEach((smallestUnit) => { - assert.throws(RangeError, () => datetime.toString({ smallestUnit }), smallestUnit); + assert.throws(RangeError, () => datetime.toString({ smallestUnit }), + `"${smallestUnit}" is not a valid unit for the smallestUnit option`); }); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..8b80d537aced --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.until +description: Leap second is a valid ISO string for a calendar in a property bag +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.ZonedDateTime(0n, timeZone); + +const calendar = "2016-12-31T23:59:60+00:00[UTC]"; + +let arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; +const result1 = instance.until(arg); +TemporalHelpers.assertDuration( + result1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar: { calendar } }; +const result2 = instance.until(arg); +TemporalHelpers.assertDuration( + result2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..29326ef052cd --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-number.js @@ -0,0 +1,46 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.until +description: A number as calendar in a property bag is converted to a string, then to a calendar +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.ZonedDateTime(0n, timeZone); + +const calendar = 19970327; + +let arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; +const result1 = instance.until(arg); +TemporalHelpers.assertDuration(result1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar: { calendar } }; +const result2 = instance.until(arg); +TemporalHelpers.assertDuration(result2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar }; + assert.throws( + RangeError, + () => instance.until(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { year: 1970, monthCode: "M01", day: 1, timeZone, calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.until(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..c3709decf8c0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.until +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.ZonedDateTime(0n, timeZone); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.until(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.until(arg), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.until(arg), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.until(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.until(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..b453e74f24ee --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,28 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.until +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.ZonedDateTime(0n, timeZone); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.until(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/argument-wrong-type.js new file mode 100644 index 000000000000..24e855e165c6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/argument-wrong-type.js @@ -0,0 +1,41 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.until +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for ZonedDateTime +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.ZonedDateTime(0n, timeZone); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.until(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.ZonedDateTime, "Temporal.ZonedDateTime, object"], + [Temporal.ZonedDateTime.prototype, "Temporal.ZonedDateTime.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.until(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/largestunit-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/largestunit-invalid-string.js index cc1f3eb0c7d0..4fd9f0b93c80 100644 --- a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/largestunit-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/largestunit-invalid-string.js @@ -10,9 +10,22 @@ features: [Temporal] const earlier = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); const later = new Temporal.ZonedDateTime(1_000_090_061_987_654_321n, "UTC"); -const values = ["era", "eraYear", "other string"]; -for (const largestUnit of values) { - assert.throws(RangeError, () => earlier.until(later, { largestUnit })); +const badValues = [ + "era", + "eraYear", + "millisecond\0", + "mill\u0131second", + "SECOND", + "eras", + "eraYears", + "milliseconds\0", + "mill\u0131seconds", + "SECONDS", + "other string" +]; +for (const largestUnit of badValues) { + assert.throws(RangeError, () => earlier.until(later, { largestUnit }), + `"${largestUnit}" is not a valid value for largestUnit`); } reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/leap-second.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/leap-second.js new file mode 100644 index 000000000000..de351a7b2c46 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/leap-second.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.until +description: Leap second is a valid ISO string for ZonedDateTime +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.ZonedDateTime(1_483_228_799_000_000_000n, timeZone); + +let arg = "2016-12-31T23:59:60+00:00[UTC]"; +const result = instance.until(arg); +TemporalHelpers.assertDuration( + result, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "leap second is a valid ISO string for ZonedDateTime" +); + +arg = "2000-05-02T12:34:56+23:59[+23:59:60]"; +assert.throws( + RangeError, + () => instance.until(arg), + "leap second in time zone name not valid" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/options-wrong-type.js new file mode 100644 index 000000000000..196f96b932b5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.until +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.ZonedDateTime(0n, "UTC"); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.until(new Temporal.ZonedDateTime(3600_000_000_000n, "UTC"), value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/smallestunit-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/smallestunit-invalid-string.js index b0c08616ef67..86f7e29129a8 100644 --- a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/smallestunit-invalid-string.js +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/smallestunit-invalid-string.js @@ -10,9 +10,22 @@ features: [Temporal] const earlier = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); const later = new Temporal.ZonedDateTime(1_000_090_061_987_654_321n, "UTC"); -const values = ["era", "eraYear", "other string"]; -for (const smallestUnit of values) { - assert.throws(RangeError, () => earlier.until(later, { smallestUnit })); +const badValues = [ + "era", + "eraYear", + "millisecond\0", + "mill\u0131second", + "SECOND", + "eras", + "eraYears", + "milliseconds\0", + "mill\u0131seconds", + "SECONDS", + "other string", +]; +for (const smallestUnit of badValues) { + assert.throws(RangeError, () => earlier.until(later, { smallestUnit }), + `"${smallestUnit}" is not a valid value for smallest unit`); } reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/timezone-string-leap-second.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/timezone-string-leap-second.js new file mode 100644 index 000000000000..0ddfd7639116 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/timezone-string-leap-second.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.until +description: Leap second is a valid ISO string for TimeZone +features: [Temporal] +---*/ + +const expectedTimeZone = "UTC"; +const instance = new Temporal.ZonedDateTime(0n, expectedTimeZone); +let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; + +// These operations should produce expectedTimeZone, so the following operations +// should not throw due to the time zones being different on the receiver and +// the argument. + +instance.until({ year: 2020, month: 5, day: 2, timeZone }); +instance.until({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }); + +timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; +assert.throws(RangeError, () => instance.until({ year: 2020, month: 5, day: 2, timeZone }), "leap second in time zone name not valid"); +assert.throws(RangeError, () => instance.until({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }), "leap second in time zone name not valid (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/timezone-string-year-zero.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/timezone-string-year-zero.js new file mode 100644 index 000000000000..d0127c083592 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/timezone-string-year-zero.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.until +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.ZonedDateTime(0n, new Temporal.TimeZone("UTC")); +invalidStrings.forEach((timeZone) => { + assert.throws( + RangeError, + () => instance.until({ year: 2020, month: 5, day: 2, timeZone }), + "reject minus zero as extended year" + ); + assert.throws( + RangeError, + () => instance.until({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }), + "reject minus zero as extended year (nested property)" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/timezone-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/timezone-wrong-type.js new file mode 100644 index 000000000000..3cd028bee9a8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/timezone-wrong-type.js @@ -0,0 +1,41 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.until +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for TimeZone +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.ZonedDateTime(0n, new Temporal.TimeZone("UTC")); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], +]; + +for (const [timeZone, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.until({ year: 2020, month: 5, day: 2, timeZone }), `${description} does not convert to a valid ISO string`); + assert.throws(RangeError, () => instance.until({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [timeZone, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.until({ year: 2020, month: 5, day: 2, timeZone }), `${description} is not a valid object and does not convert to a string`); + assert.throws(TypeError, () => instance.until({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }), `${description} is not a valid object and does not convert to a string (nested property)`); +} + +const timeZone = undefined; +assert.throws(RangeError, () => instance.until({ year: 2020, month: 5, day: 2, timeZone: { timeZone } }), `undefined is always a RangeError as nested property`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/year-zero.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/year-zero.js index a0c654f8d9ec..44756e891be1 100644 --- a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/year-zero.js @@ -5,13 +5,22 @@ /*--- esid: sec-temporal.zoneddatetime.prototype.until description: Negative zero, as an extended year, is rejected -features: [Temporal] +features: [Temporal, arrow-function] ---*/ +const invalidStrings = [ + "-0000000-01-01T00:02Z[UTC]", + "-0000000-01-01T00:02+00:00[UTC]", + "-0000000-01-01T00:02:00.000000000+00:00[UTC]", +]; const timeZone = new Temporal.TimeZone("UTC"); const instance = new Temporal.ZonedDateTime(0n, timeZone); -const str = "-0000000-01-01T00:02:00.000000000+00:00[UTC]"; - -assert.throws(RangeError, () => { instance.until(str); }, "reject minus zero as extended year"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.until(arg), + "reject minus zero as extended year" + ); +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/with/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/with/options-wrong-type.js new file mode 100644 index 000000000000..3ddb79502768 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/with/options-wrong-type.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.with +description: TypeError thrown when options argument is a primitive +features: [BigInt, Symbol, Temporal] +---*/ + +const badOptions = [ + null, + true, + "some string", + Symbol(), + 1, + 2n, +]; + +const instance = new Temporal.ZonedDateTime(0n, "UTC"); +for (const value of badOptions) { + assert.throws(TypeError, () => instance.with({ day: 5 }, value), + `TypeError on wrong options type ${typeof value}`); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-number.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-number.js new file mode 100644 index 000000000000..25e58d8f2530 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-number.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withcalendar +description: A number is converted to a string, then to Temporal.Calendar +features: [Temporal] +---*/ + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", { id: "replace-me" }); + +const arg = 19761118; + +const result = instance.withCalendar(arg); +assert.sameValue(result.calendar.id, "iso8601", "19761118 is a valid ISO string for Calendar"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.withCalendar(arg), + `Number ${arg} does not convert to a valid ISO string for Calendar` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-string-leap-second.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-string-leap-second.js new file mode 100644 index 000000000000..608f09587272 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-string-leap-second.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withcalendar +description: Leap second is a valid ISO string for Calendar +features: [Temporal] +---*/ + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", { id: "replace-me" }); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.withCalendar(arg); +assert.sameValue( + result1.calendar.id, + "iso8601", + "leap second is a valid ISO string for Calendar" +); + +arg = { calendar: "2016-12-31T23:59:60" }; +const result2 = instance.withCalendar(arg); +assert.sameValue( + result2.calendar.id, + "iso8601", + "leap second is a valid ISO string for Calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-wrong-type.js new file mode 100644 index 000000000000..cd3df30dc47f --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withCalendar/calendar-wrong-type.js @@ -0,0 +1,35 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withcalendar +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for Calendar +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", { id: "replace-me" }); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.withCalendar(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.withCalendar(arg), `${description} is not a valid object and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-number.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-number.js new file mode 100644 index 000000000000..2e828617bb03 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-number.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaindate +description: A number is converted to a string, then to Temporal.PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); + +const arg = 19761118; + +const result = instance.withPlainDate(arg); +assert.sameValue(result.epochNanoseconds, 217_129_600_000_000_000n, "19761118 is a valid ISO string for PlainDate"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.withPlainDate(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..0b0319cece09 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaindate +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, timeZone); + +const calendar = "2016-12-31T23:59:60+00:00[UTC]"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.withPlainDate(arg); +assert.sameValue( + result1.epochNanoseconds, + 217_129_600_000_000_000n, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.withPlainDate(arg); +assert.sameValue( + result2.epochNanoseconds, + 217_129_600_000_000_000n, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..b0dffacd0aee --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-propertybag-calendar-number.js @@ -0,0 +1,45 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaindate +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, timeZone); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.withPlainDate(arg); +assert.sameValue(result1.epochNanoseconds, 217_129_600_000_000_000n, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.withPlainDate(arg); +assert.sameValue(result2.epochNanoseconds, 217_129_600_000_000_000n, "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + assert.throws( + RangeError, + () => instance.withPlainDate(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.withPlainDate(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..fb56b43d9c66 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaindate +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, timeZone); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.withPlainDate(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.withPlainDate(arg), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.withPlainDate(arg), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.withPlainDate(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.withPlainDate(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..029587ee2d71 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,28 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaindate +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, timeZone); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.withPlainDate(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-wrong-type.js new file mode 100644 index 000000000000..7dfd0838b944 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/argument-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaindate +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.withPlainDate(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.withPlainDate(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/leap-second.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/leap-second.js new file mode 100644 index 000000000000..6ff58d116387 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/leap-second.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaindate +description: Leap second is a valid ISO string for PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.withPlainDate(arg); +assert.sameValue( + result1.epochNanoseconds, + 1_483_148_800_000_000_000n, + "leap second is a valid ISO string for PlainDate" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.withPlainDate(arg); +assert.sameValue( + result2.epochNanoseconds, + 1_483_148_800_000_000_000n, + "second: 60 is ignored in property bag for PlainDate" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/year-zero.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/year-zero.js index 0cc8f250a238..c3b44fa715e1 100644 --- a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainDate/year-zero.js @@ -8,13 +8,20 @@ description: Negative zero, as an extended year, is rejected features: [Temporal, arrow-function] ---*/ -const arg = "-000000-10-31"; -const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); - -assert.throws( +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.ZonedDateTime(0n, timeZone); +invalidStrings.forEach((arg) => { + assert.throws( RangeError, - () => { instance.withPlainDate(arg); }, + () => instance.withPlainDate(arg), "reject minus zero as extended year" -); + ); +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-number.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-number.js new file mode 100644 index 000000000000..64963844c4cb --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-number.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaintime +description: A number is converted to a string, then to Temporal.PlainTime +features: [Temporal] +---*/ + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); + +const arg = 123456.987654321; + +const result = instance.withPlainTime(arg); +assert.sameValue(result.epochNanoseconds, 1000038896_987_654_321n, "123456.987654321 is a valid ISO string for PlainTime"); + +const numbers = [ + 1, + -123456.987654321, + 1234567, + 123456.9876543219, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.withPlainTime(arg), + `Number ${arg} does not convert to a valid ISO string for PlainTime` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-time-designator-required-for-disambiguation.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-time-designator-required-for-disambiguation.js index 26cfd1b0cf22..d69bda40e396 100644 --- a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-time-designator-required-for-disambiguation.js +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-string-time-designator-required-for-disambiguation.js @@ -33,7 +33,7 @@ ambiguousStrings.forEach((string) => { assert.throws( RangeError, () => instance.withPlainTime(arg), - 'space is not accepted as a substitute for T prefix' + "space is not accepted as a substitute for T prefix" ); }); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-wrong-type.js new file mode 100644 index 000000000000..2de4cfbb1e06 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/argument-wrong-type.js @@ -0,0 +1,38 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaintime +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainTime +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.withPlainTime(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainTime, "Temporal.PlainTime, object"], + [Temporal.PlainTime.prototype, "Temporal.PlainTime.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.withPlainTime(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/leap-second.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/leap-second.js new file mode 100644 index 000000000000..0cf665e92431 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/leap-second.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withplaintime +description: Leap second is a valid ISO string for PlainTime +features: [Temporal] +---*/ + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.withPlainTime(arg); +assert.sameValue( + result1.epochNanoseconds, + 1000079999_000_000_000n, + "leap second is a valid ISO string for PlainTime" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.withPlainTime(arg); +assert.sameValue( + result2.epochNanoseconds, + 1000079999_000_000_000n, + "second: 60 is ignored in property bag for PlainTime" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/plaintime-propertybag-no-time-units.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/plaintime-propertybag-no-time-units.js index 4fc6257d54e9..f4a0284553df 100644 --- a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/plaintime-propertybag-no-time-units.js +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/plaintime-propertybag-no-time-units.js @@ -11,7 +11,7 @@ features: [Temporal] const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); const props = {}; -assert.throws(TypeError, () => instance.withPlainTime(props), "TypeError if at least one property is not present"); +assert.throws(TypeError, () => instance.withPlainTime(props), "TypeError if no properties are present"); props.minute = 30; const result = instance.withPlainTime(props); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/year-zero.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/year-zero.js index 6e2f10c34fa3..9a160295d30c 100644 --- a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/year-zero.js +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/year-zero.js @@ -9,10 +9,12 @@ features: [Temporal, arrow-function] ---*/ const invalidStrings = [ - '-000000-12-07T03:24:30', - '-000000-12-07T03:24:30+01:00[UTC]' + "-000000-12-07T03:24:30", + "-000000-12-07T03:24:30+01:00", + "-000000-12-07T03:24:30+00:00[UTC]", ]; -const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC"); +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.ZonedDateTime(0n, timeZone); invalidStrings.forEach((arg) => { assert.throws( RangeError, diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-string-leap-second.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-string-leap-second.js new file mode 100644 index 000000000000..76f058204e4d --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-string-leap-second.js @@ -0,0 +1,23 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withtimezone +description: Leap second is a valid ISO string for TimeZone +features: [Temporal] +---*/ + +const instance = new Temporal.ZonedDateTime(0n, "UTC"); +let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; + +const result1 = instance.withTimeZone(timeZone); +assert.sameValue(result1.timeZone.id, "UTC", "leap second is a valid ISO string for TimeZone"); +const result2 = instance.withTimeZone({ timeZone }); +assert.sameValue(result2.timeZone.id, "UTC", "leap second is a valid ISO string for TimeZone (nested property)"); + +timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; +assert.throws(RangeError, () => instance.withTimeZone(timeZone), "leap second in time zone name not valid"); +assert.throws(RangeError, () => instance.withTimeZone({ timeZone }), "leap second in time zone name not valid (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-string-year-zero.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-string-year-zero.js new file mode 100644 index 000000000000..d03ac1128313 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-string-year-zero.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withtimezone +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.ZonedDateTime(0n, new Temporal.TimeZone("UTC")); +invalidStrings.forEach((timeZone) => { + assert.throws( + RangeError, + () => instance.withTimeZone(timeZone), + "reject minus zero as extended year" + ); + assert.throws( + RangeError, + () => instance.withTimeZone({ timeZone }), + "reject minus zero as extended year (nested property)" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-wrong-type.js new file mode 100644 index 000000000000..3be95a3ef9e6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-wrong-type.js @@ -0,0 +1,41 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.withtimezone +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for TimeZone +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.ZonedDateTime(0n, new Temporal.TimeZone("UTC")); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], +]; + +for (const [timeZone, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.withTimeZone(timeZone), `${description} does not convert to a valid ISO string`); + assert.throws(RangeError, () => instance.withTimeZone({ timeZone }), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [timeZone, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.withTimeZone(timeZone), `${description} is not a valid object and does not convert to a string`); + assert.throws(TypeError, () => instance.withTimeZone({ timeZone }), `${description} is not a valid object and does not convert to a string (nested property)`); +} + +const timeZone = undefined; +assert.throws(RangeError, () => instance.withTimeZone({ timeZone }), `undefined is always a RangeError as nested property`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/shell.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/shell.js +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/timezone-string-leap-second.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/timezone-string-leap-second.js new file mode 100644 index 000000000000..c201e431af84 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/timezone-string-leap-second.js @@ -0,0 +1,22 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime +description: Leap second is a valid ISO string for TimeZone +features: [Temporal] +---*/ + +let timeZone = "2016-12-31T23:59:60+00:00[UTC]"; + +const result1 = new Temporal.ZonedDateTime(0n, timeZone); +assert.sameValue(result1.timeZone.id, "UTC", "Time zone string determined from bracket name"); +const result2 = new Temporal.ZonedDateTime(0n, { timeZone }); +assert.sameValue(result2.timeZone.id, "UTC", "Time zone string determined from bracket name (nested property)"); + +timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]"; +assert.throws(RangeError, () => new Temporal.ZonedDateTime(0n, timeZone), "leap second in time zone name not valid"); +assert.throws(RangeError, () => new Temporal.ZonedDateTime(0n, { timeZone }), "leap second in time zone name not valid (nested property)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/timezone-string-multiple-offsets.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/timezone-string-multiple-offsets.js new file mode 100644 index 000000000000..53ac30af3485 --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/timezone-string-multiple-offsets.js @@ -0,0 +1,18 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime +description: Time zone strings with UTC offset fractional part are not confused with time fractional part +features: [Temporal] +---*/ + +const timeZone = "2021-08-19T17:30:45.123456789+01:46[+01:45:30.987654321]"; + +const result1 = new Temporal.ZonedDateTime(0n, timeZone); +assert.sameValue(result1.timeZone.id, "+01:45:30.987654321", "Time zone string determined from bracket name"); +const result2 = new Temporal.ZonedDateTime(0n, { timeZone }); +assert.sameValue(result2.timeZone.id, "+01:45:30.987654321", "Time zone string determined from bracket name"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/timezone-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/timezone-wrong-type.js new file mode 100644 index 000000000000..18373f8814cb --- /dev/null +++ b/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/timezone-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or object for TimeZone +features: [BigInt, Symbol, Temporal] +---*/ + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [19761118, "number that would convert to a valid ISO string in other contexts"], + [1n, "bigint"], +]; + +for (const [timeZone, description] of rangeErrorTests) { + assert.throws(RangeError, () => new Temporal.ZonedDateTime(0n, timeZone), `${description} does not convert to a valid ISO string`); + assert.throws(RangeError, () => new Temporal.ZonedDateTime(0n, { timeZone }), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], +]; + +for (const [timeZone, description] of typeErrorTests) { + assert.throws(TypeError, () => new Temporal.ZonedDateTime(0n, timeZone), `${description} is not a valid object and does not convert to a string`); + assert.throws(TypeError, () => new Temporal.ZonedDateTime(0n, { timeZone }), `${description} is not a valid object and does not convert to a string (nested property)`); +} + +const timeZone = undefined; +assert.throws(RangeError, () => new Temporal.ZonedDateTime(0n, { timeZone }), `undefined is always a RangeError as nested property`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/TypedArray/prototype/set/BigInt/array-arg-targetbuffer-detached-on-get-src-value-throws.js b/js/src/tests/test262/built-ins/TypedArray/prototype/set/BigInt/array-arg-targetbuffer-detached-on-get-src-value-throws.js deleted file mode 100644 index 2d84700e41bd..000000000000 --- a/js/src/tests/test262/built-ins/TypedArray/prototype/set/BigInt/array-arg-targetbuffer-detached-on-get-src-value-throws.js +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (C) 2016 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-%typedarray%.prototype.set-array-offset -description: > - Throws an error if buffer is detached before setting a value -info: | - 22.2.3.23.1 %TypedArray%.prototype.set (array [ , offset ] ) - - 1. Assert: array is any ECMAScript language value other than an Object with a - [[TypedArrayName]] internal slot. If it is such an Object, the definition in - 22.2.3.23.2 applies. - ... - 21. Repeat, while targetByteIndex < limit - a. Let Pk be ! ToString(k). - b. Let kNumber be ? ToNumber(? Get(src, Pk)). - c. If IsDetachedBuffer(targetBuffer) is true, throw a TypeError exception. - d. Perform SetValueInBuffer(targetBuffer, targetByteIndex, targetType, - kNumber). - ... -includes: [testBigIntTypedArray.js, detachArrayBuffer.js] -features: [BigInt, TypedArray] ----*/ - -testWithBigIntTypedArrayConstructors(function(TA) { - var sample = new TA([1n, 2n, 3n]); - var obj = { - length: 3, - "0": 42n - }; - Object.defineProperty(obj, 1, { - get: function() { - $DETACHBUFFER(sample.buffer); - } - }); - Object.defineProperty(obj, 2, { - get: function() { - throw new Test262Error("Should not get other values"); - } - }); - - assert.throws(TypeError, function() { - sample.set(obj); - }); -}); - -reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/TypedArrayConstructors/ctors/no-species.js b/js/src/tests/test262/built-ins/TypedArrayConstructors/ctors/no-species.js index c13f6bb416df..af48263ff641 100644 --- a/js/src/tests/test262/built-ins/TypedArrayConstructors/ctors/no-species.js +++ b/js/src/tests/test262/built-ins/TypedArrayConstructors/ctors/no-species.js @@ -4,7 +4,7 @@ /*--- description: > Creating TypedArray from other TypedArrays doesn't look up Symbol.species. -features: [Symbol.species] +features: [TypedArray, ArrayBuffer, Symbol.species] ---*/ let throwOnGrossBufferConstruction = false; diff --git a/js/src/tests/test262/built-ins/parseInt/15.1.2.2-2-1.js b/js/src/tests/test262/built-ins/parseInt/15.1.2.2-2-1.js index e47c3531c400..d259cb8b93d5 100644 --- a/js/src/tests/test262/built-ins/parseInt/15.1.2.2-2-1.js +++ b/js/src/tests/test262/built-ins/parseInt/15.1.2.2-2-1.js @@ -4,7 +4,7 @@ /*--- esid: sec-parseint-string-radix description: > - pareseInt - 'S' is the empty string when inputString does not + parseInt - 'S' is the empty string when inputString does not contain any such characters ---*/ diff --git a/js/src/tests/test262/harness/shell.js b/js/src/tests/test262/harness/shell.js index 68be365f54ec..ec4142f280fd 100644 --- a/js/src/tests/test262/harness/shell.js +++ b/js/src/tests/test262/harness/shell.js @@ -1439,20 +1439,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -1526,39 +1527,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/DurationFormat/constructor-locales-invalid.js b/js/src/tests/test262/intl402/DurationFormat/constructor-locales-invalid.js new file mode 100644 index 000000000000..687ae01c37d2 --- /dev/null +++ b/js/src/tests/test262/intl402/DurationFormat/constructor-locales-invalid.js @@ -0,0 +1,20 @@ +// |reftest| skip -- Intl.DurationFormat is not supported +// Copyright 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DurationFormat +description: Checks error cases for the locales argument to the DurationFormat constructor. +info: | + Intl.DurationFormat ( [ locales [ , options ] ] ) + (...) + 3. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_). +includes: [testIntl.js] +features: [Intl.DurationFormat] +---*/ + +for (const [locales, expectedError] of getInvalidLocaleArguments()) { + assert.throws(expectedError, function() { new Intl.DurationFormat(locales) }) +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DurationFormat/constructor-locales-valid.js b/js/src/tests/test262/intl402/DurationFormat/constructor-locales-valid.js new file mode 100644 index 000000000000..6d58367d436f --- /dev/null +++ b/js/src/tests/test262/intl402/DurationFormat/constructor-locales-valid.js @@ -0,0 +1,37 @@ +// |reftest| skip -- Intl.DurationFormat is not supported +// Copyright 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DurationFormat +description: Checks cases for the locales argument to the DurationFormat constructor. +info: | + Intl.DurationFormat ( [ locales [ , options ] ] ) + (...) + 3. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_). +features: [Intl.DurationFormat] +---*/ + +const defaultLocale = new Intl.DurationFormat().resolvedOptions().locale; + +const matchers = ["lookup", "best fit"] + +const tests = [ + [undefined, defaultLocale, "undefined"], + ["EN", "en", "Single value"], + [[], defaultLocale, "Empty array"], + [["en", "EN"], "en", "Duplicate value (canonical first)"], + [["EN", "en"], "en", "Duplicate value (canonical last)"], + [{ 0: "DE", length: 0 }, defaultLocale, "Object with zero length"], + [{ 0: "DE", length: 1 }, "de", "Object with length"], +]; + + +for (const [locales, expected, name] of tests) { + matchers.forEach((matcher)=>{ + const drf = new Intl.DurationFormat(locales, {localeMatcher: matcher}); + assert.sameValue(drf.resolvedOptions().locale, expected, name); + }); +}; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DurationFormat/constructor-options-defaults.js b/js/src/tests/test262/intl402/DurationFormat/constructor-options-defaults.js new file mode 100644 index 000000000000..6fae08f6d25c --- /dev/null +++ b/js/src/tests/test262/intl402/DurationFormat/constructor-options-defaults.js @@ -0,0 +1,35 @@ +// |reftest| skip -- Intl.DurationFormat is not supported +// Copyright 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DurationFormat +description: Checks handling of valid options for the DurationFormat constructor. +info: | + Intl.DurationFormat ( [ locales [ , options ] ] ) + (...) + 17. For each row in Table 1, except the header row, in table order, do + a. Let styleSlot be the Style Slot value. + b. Let displaySlot be the Display Slot value. + c. Let unit be the Unit value. + d. Let valueList be the Values value. + e. Let digitalBase be the Digital Default value. + f. Let unitOptions be ? GetUnitOptions(unit, options, style, valueList, digitalBase, prevStyle). + g. Set durationFormat.[[]] to unitOptions.[[Style]]. + h. Set durationFormat.[[]] to unitOptions.[[Display]]. +features: [Intl.DurationFormat] +includes: [testIntl.js] +---*/ + +testOption( Intl.DurationFormat, "years", "string", ["long", "short", "narrow"], "narrow"); +testOption( Intl.DurationFormat, "months", "string", ["long", "short", "narrow"], "narrow"); +testOption( Intl.DurationFormat, "weeks", "string", ["long", "short", "narrow"], "narrow"); +testOption( Intl.DurationFormat, "days", "string", ["long", "short", "narrow", "numeric", "2-digit"], "numeric"); +testOption( Intl.DurationFormat, "hours", "string", ["long", "short", "narrow", "numeric", "2-digit"], "numeric"); +testOption( Intl.DurationFormat, "minutes", "string", ["long", "short", "narrow", "numeric", "2-digit"], "numeric"); +testOption( Intl.DurationFormat, "milliseconds", "string", ["long", "short", "narrow", "numeric", "2-digit"], "numeric"); +testOption( Intl.DurationFormat, "microseconds", "string", ["long", "short", "narrow", "numeric", "2-digit"], "numeric"); +testOption( Intl.DurationFormat, "nanoseconds", "string", ["long", "short", "narrow", "numeric", "2-digit"], "numeric"); + + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DurationFormat/constructor-options-fractionalDigits-invalid.js b/js/src/tests/test262/intl402/DurationFormat/constructor-options-fractionalDigits-invalid.js new file mode 100644 index 000000000000..7f580a8e320f --- /dev/null +++ b/js/src/tests/test262/intl402/DurationFormat/constructor-options-fractionalDigits-invalid.js @@ -0,0 +1,26 @@ +// |reftest| skip -- Intl.DurationFormat is not supported +// Copyright 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DurationFormat +description: Tests that the option localeMatcher is processed correctly. +info: | + Intl.DurationFormat ( [ locales [ , options ] ] ) + (...) + 18. Set durationFormat.[[FractionalDigits]] to ? GetNumberOption(options, "fractionalDigits", 0, 9, undefined). +features: [Intl.DurationFormat] +---*/ + +const invalidOptions = [ + -10, + 10 +]; + +for (const fractionalDigits of invalidOptions) { + assert.throws(RangeError, function() { + new Intl.DurationFormat("en", { fractionalDigits }); + }, `new Intl.DurationFormat("en", {fractionalDigits: "${fractionalDigits}"}) throws RangeError`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DurationFormat/constructor-options-fractionalDigits-valid.js b/js/src/tests/test262/intl402/DurationFormat/constructor-options-fractionalDigits-valid.js new file mode 100644 index 000000000000..aa99b6ad2dcc --- /dev/null +++ b/js/src/tests/test262/intl402/DurationFormat/constructor-options-fractionalDigits-valid.js @@ -0,0 +1,28 @@ +// |reftest| skip -- Intl.DurationFormat is not supported +// Copyright 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DurationFormat +description: Tests that the option localeMatcher is processed correctly. +info: | + Intl.DurationFormat ( [ locales [ , options ] ] ) + (...) + 18. Set durationFormat.[[FractionalDigits]] to ? GetNumberOption(options, "fractionalDigits", 0, 9, undefined). +features: [Intl.DurationFormat] +---*/ + +const validOptions = [ + undefined, + 0, + 1, + 5, + 9 +]; + +for (const fractionalDigits of validOptions) { + const obj = new Intl.DurationFormat("en", {fractionalDigits}); + assert.sameValue(obj.resolvedOptions().fractionalDigits, fractionalDigits, `${fractionalDigits} is supported by DurationFormat`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DurationFormat/constructor-options-invalid.js b/js/src/tests/test262/intl402/DurationFormat/constructor-options-invalid.js new file mode 100644 index 000000000000..26b0c361fa12 --- /dev/null +++ b/js/src/tests/test262/intl402/DurationFormat/constructor-options-invalid.js @@ -0,0 +1,19 @@ +// |reftest| skip -- Intl.DurationFormat is not supported +// Copyright 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DurationFormat +description: Checks handling of a null options argument to the DurationFormat constructor. +info: | + Intl.DurationFormat ( [ locales [ , options ] ] ) + (...) + 4. Let options be GetOptionsObject(options). +features: [Intl.DurationFormat] +---*/ + +assert.sameValue(typeof Intl.DurationFormat, "function"); + +assert.throws(TypeError, function() { new Intl.DurationFormat([], null) }) + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DurationFormat/constructor-options-localeMatcher-invalid.js b/js/src/tests/test262/intl402/DurationFormat/constructor-options-localeMatcher-invalid.js new file mode 100644 index 000000000000..ed89c0787f56 --- /dev/null +++ b/js/src/tests/test262/intl402/DurationFormat/constructor-options-localeMatcher-invalid.js @@ -0,0 +1,33 @@ +// |reftest| skip -- Intl.DurationFormat is not supported +// Copyright 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DurationFormat +description: Checks handling of invalid value for the localeMatcher option to the DurationFormat constructor. +info: | + Intl.DurationFormat ( [ locales [ , options ] ] ) + (...) + 5. Let matcher be ? GetOption(options, "localeMatcher", "string", « "lookup", "best fit" », "best fit"). +features: [Intl.DurationFormat] +---*/ + +const invalidOptions = [ + null, + 1, + "", + "Lookup", + "LOOKUP", + "lookup\0", + "Best fit", + "BEST FIT", + "best\u00a0fit", +]; + +for (const localeMatcher of invalidOptions) { + assert.throws(RangeError, function() { + new Intl.DurationFormat([], { localeMatcher }); + }, `${localeMatcher} is an invalid localeMatcher option value`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DurationFormat/constructor-options-localeMatcher-valid.js b/js/src/tests/test262/intl402/DurationFormat/constructor-options-localeMatcher-valid.js new file mode 100644 index 000000000000..0190aabe73a4 --- /dev/null +++ b/js/src/tests/test262/intl402/DurationFormat/constructor-options-localeMatcher-valid.js @@ -0,0 +1,18 @@ +// |reftest| skip -- Intl.DurationFormat is not supported +// Copyright 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DurationFormat +description: Tests that the option localeMatcher is processed correctly. +info: | + Intl.DurationFormat ( [ locales [ , options ] ] ) + (...) + 5. Let matcher be ? GetOption(options, "localeMatcher", "string", « "lookup", "best fit" », "best fit"). +features: [Intl.DurationFormat] +includes: [testIntl.js] +---*/ + +testOption(Intl.DurationFormat, "localeMatcher", "string", ["lookup", "best fit"], "best fit", {noReturn: true}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DurationFormat/constructor-options-numberingSystem-invalid.js b/js/src/tests/test262/intl402/DurationFormat/constructor-options-numberingSystem-invalid.js new file mode 100644 index 000000000000..eac66df308a5 --- /dev/null +++ b/js/src/tests/test262/intl402/DurationFormat/constructor-options-numberingSystem-invalid.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Intl.DurationFormat is not supported +// Copyright 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DurationFormat +description: > + Checks error cases for the options argument to the DurationFormat constructor. +info: | + Intl.DurationFormat ( [ locales [ , options ] ] ) + (...) + 6. Let numberingSystem be ? GetOption(options, "numberingSystem", "string", undefined, undefined). + 7. If numberingSystem does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception. +features: [Intl.DurationFormat] +---*/ + +const invalidOptions = [ + "", + "a", + "ab", + "abcdefghi", + "abc-abcdefghi", + "!invalid!", + "-latn-", + "latn-", + "latn--", + "latn-ca", + "latn-ca-", + "latn-ca-gregory", + "latné", + "latn编号", +]; +for (const numberingSystem of invalidOptions) { + assert.throws(RangeError, function() { + new Intl.DurationFormat('en', {numberingSystem}); + }, `new Intl.DurationFormat("en", {numberingSystem: "${numberingSystem}"}) throws RangeError`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DurationFormat/constructor-options-numberingSystem-valid.js b/js/src/tests/test262/intl402/DurationFormat/constructor-options-numberingSystem-valid.js new file mode 100644 index 000000000000..c053bba51a6f --- /dev/null +++ b/js/src/tests/test262/intl402/DurationFormat/constructor-options-numberingSystem-valid.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Intl.DurationFormat is not supported +// Copyright 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DurationFormat +description: > + Checks error cases for the options argument to the DurationFormat constructor. +info: | + Intl.DurationFormat ( [ locales [ , options ] ] ) + (...) + 6. Let numberingSystem be ? GetOption(options, "numberingSystem", "string", undefined, undefined). + 7. If numberingSystem does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception. +features: [Intl.DurationFormat] +---*/ + +const numberingSystems = Intl.supportedValuesOf("numberingSystem"); + +for (const numberingSystem of numberingSystems) { + const obj = new Intl.DurationFormat("en", {numberingSystem}); + assert.sameValue(obj.resolvedOptions().numberingSystem, numberingSystem, `${numberingSystem} is supported by DurationFormat`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DurationFormat/constructor-options-order.js b/js/src/tests/test262/intl402/DurationFormat/constructor-options-order.js new file mode 100644 index 000000000000..073a62fb5c5d --- /dev/null +++ b/js/src/tests/test262/intl402/DurationFormat/constructor-options-order.js @@ -0,0 +1,44 @@ +// |reftest| skip -- Intl.DurationFormat is not supported +// Copyright 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DurationFormat +description: Checks the order of operations on the options argument to the DurationFormat constructor. +info: | + Intl.DurationFormat ( [ locales [ , options ] ] ) + (...) + 5. Let matcher be ? GetOption(options, "localeMatcher", "string", « "lookup", "best fit" », "best fit"). + 6. Let numberingSystem be ? GetOption(options, "numberingSystem", "string", undefined, undefined). + 13. Let style be ? GetOption(options, "style", "string", « "long", "short", "narrow", "digital" », "long"). +includes: [compareArray.js] +features: [Intl.DurationFormat] +---*/ + +var actual = []; + +const options = { + get localeMatcher() { + actual.push("localeMatcher"); + return undefined; + }, + get numberingSystem() { + actual.push("numberingSystem"); + return undefined; + }, + get style() { + actual.push("style"); + return undefined; + }, +}; + +const expected = [ + "localeMatcher", + "numberingSystem", + "style" +]; + +let nf = new Intl.DurationFormat(undefined, options); +assert.compareArray(actual, expected); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DurationFormat/constructor-options-style-invalid.js b/js/src/tests/test262/intl402/DurationFormat/constructor-options-style-invalid.js new file mode 100644 index 000000000000..7b8bcced9d04 --- /dev/null +++ b/js/src/tests/test262/intl402/DurationFormat/constructor-options-style-invalid.js @@ -0,0 +1,40 @@ +// |reftest| skip -- Intl.DurationFormat is not supported +// Copyright 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DurationFormat +description: Checks handling of invalid value for the style option to the DurationFormat constructor. +info: | + InitializeDurationFormat (DurationFormat, locales, options) + (...) + 13. Let style be ? GetOption(options, "style", "string", « "long", "short", "narrow", "digital" », "long"). + 14. Set durationFormat.[[Style]] to style. +features: [Intl.DurationFormat] +---*/ + +const invalidOptions = [ + null, + 1, + "", + "Long", + "LONG", + "long\0", + "Short", + "SHORT", + "short\0", + "Narrow", + "NARROW", + "narrow\0", + "Digital", + "DIGITAL", + "digital\0", +]; + +for (const invalidOption of invalidOptions) { + assert.throws(RangeError, function() { + new Intl.DurationFormat([], {"style": invalidOption}); + }, `${invalidOption} is an invalid style option value`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DurationFormat/constructor-options-style-valid.js b/js/src/tests/test262/intl402/DurationFormat/constructor-options-style-valid.js new file mode 100644 index 000000000000..ba23ecc7022a --- /dev/null +++ b/js/src/tests/test262/intl402/DurationFormat/constructor-options-style-valid.js @@ -0,0 +1,34 @@ +// |reftest| skip -- Intl.DurationFormat is not supported +// Copyright 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DurationFormat +description: Checks handling of valid values for the style option to the DurationFormat constructor. +info: | + InitializeDurationFormat (DurationFormat, locales, options) + (...) + 13. Let style be ? GetOption(options, "style", "string", « "long", "short", "narrow", "digital" », "long"). + 14. Set durationFormat.[[Style]] to style. +features: [Intl.DurationFormat] +---*/ + +const validOptions = [ + [undefined, "long"], + ["long", "long"], + ["short", "short"], + ["narrow", "narrow"], + ["digital", "digital"], + [{ toString() { return "short"; } }, "short"], + [{ toString() { return "long"; } }, "long"], + [{ toString() { return "narrow"; } }, "narrow"], + [{ toString() { return "digital"; } }, "digital"], +]; + +for (const [validOption, expected] of validOptions) { + const df = new Intl.DurationFormat([], {"style": validOption}); + const resolvedOptions = df.resolvedOptions(); + assert.sameValue(resolvedOptions.style, expected); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DurationFormat/instance/extensibility.js b/js/src/tests/test262/intl402/DurationFormat/extensibility.js similarity index 100% rename from js/src/tests/test262/intl402/DurationFormat/instance/extensibility.js rename to js/src/tests/test262/intl402/DurationFormat/extensibility.js diff --git a/js/src/tests/test262/intl402/DurationFormat/instance/length.js b/js/src/tests/test262/intl402/DurationFormat/length.js similarity index 100% rename from js/src/tests/test262/intl402/DurationFormat/instance/length.js rename to js/src/tests/test262/intl402/DurationFormat/length.js diff --git a/js/src/tests/test262/intl402/DurationFormat/instance/name.js b/js/src/tests/test262/intl402/DurationFormat/name.js similarity index 100% rename from js/src/tests/test262/intl402/DurationFormat/instance/name.js rename to js/src/tests/test262/intl402/DurationFormat/name.js diff --git a/js/src/tests/test262/intl402/DurationFormat/newtarget-undefined.js b/js/src/tests/test262/intl402/DurationFormat/newtarget-undefined.js new file mode 100644 index 000000000000..5cafac677255 --- /dev/null +++ b/js/src/tests/test262/intl402/DurationFormat/newtarget-undefined.js @@ -0,0 +1,30 @@ +// |reftest| skip -- Intl.DurationFormat is not supported +// Copyright 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DurationFormat +description: > + Verifies the NewTarget check for Intl.DurationFormat. +info: | + Intl.DurationFormat ([ locales [ , options ]]) + (...) + 1. If NewTarget is undefined, throw a TypeError exception. +features: [Intl.DurationFormat] +---*/ + +assert.sameValue(typeof Intl.DurationFormat, "function"); + +assert.throws(TypeError, function() { + Intl.DurationFormat(); +}); + +assert.throws(TypeError, function() { + Intl.DurationFormat("en"); +}); + +assert.throws(TypeError, function() { + Intl.DurationFormat("not-valid-tag"); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DurationFormat/instance/prop-desc.js b/js/src/tests/test262/intl402/DurationFormat/prop-desc.js similarity index 100% rename from js/src/tests/test262/intl402/DurationFormat/instance/prop-desc.js rename to js/src/tests/test262/intl402/DurationFormat/prop-desc.js diff --git a/js/src/tests/test262/intl402/DurationFormat/instance/prototype.js b/js/src/tests/test262/intl402/DurationFormat/prototype.js similarity index 100% rename from js/src/tests/test262/intl402/DurationFormat/instance/prototype.js rename to js/src/tests/test262/intl402/DurationFormat/prototype.js diff --git a/js/src/tests/test262/intl402/DurationFormat/supportedLocalesOf/basic.js b/js/src/tests/test262/intl402/DurationFormat/supportedLocalesOf/basic.js new file mode 100644 index 000000000000..300e1d24ee09 --- /dev/null +++ b/js/src/tests/test262/intl402/DurationFormat/supportedLocalesOf/basic.js @@ -0,0 +1,22 @@ +// |reftest| skip -- Intl.DurationFormat is not supported +// Copyright 2022 Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DurationFormat.supportedLocalesOf +description: Tests that Intl.DurationFormat has a supportedLocalesOf property, and it works as expected. +features: [Intl.DurationFormat] +---*/ + +assert.sameValue(typeof Intl.DurationFormat.supportedLocalesOf, "function", + "supportedLocalesOf should be supported."); + +const defaultLocale = new Intl.DurationFormat().resolvedOptions().locale; +const notSupported = "zxx"; // "no linguistic content" +const requestedLocales = [defaultLocale, notSupported]; + +const supportedLocales = Intl.DurationFormat.supportedLocalesOf(requestedLocales); +assert.sameValue(supportedLocales.length, 1, "The length of the supported locales list should be 1"); +assert.sameValue(supportedLocales[0], defaultLocale, "The default locale is returned in the supported list."); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DurationFormat/supportedLocalesOf/branding.js b/js/src/tests/test262/intl402/DurationFormat/supportedLocalesOf/branding.js new file mode 100644 index 000000000000..d8ab61d33807 --- /dev/null +++ b/js/src/tests/test262/intl402/DurationFormat/supportedLocalesOf/branding.js @@ -0,0 +1,35 @@ +// |reftest| skip -- Intl.DurationFormat is not supported +// Copyright 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DurationFormat.supportedLocalesOf +description: > + Verifies there's no branding check for Intl.DurationFormat.supportedLocalesOf(). +info: | + Intl.DurationFormat.supportedLocalesOf ( locales [, options ]) +features: [Intl.DurationFormat] +---*/ + +const supportedLocalesOf = Intl.DurationFormat.supportedLocalesOf; + +assert.sameValue(typeof supportedLocalesOf, "function"); + +const thisValues = [ + undefined, + null, + true, + "", + Symbol(), + 1, + {}, + Intl.DurationFormat, + Intl.DurationFormat.prototype, +]; + +for (const thisValue of thisValues) { + const result = supportedLocalesOf.call(thisValue); + assert.sameValue(Array.isArray(result), true); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DurationFormat/supportedLocalesOf/browser.js b/js/src/tests/test262/intl402/DurationFormat/supportedLocalesOf/browser.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/js/src/tests/test262/intl402/DurationFormat/supportedLocalesOf/length.js b/js/src/tests/test262/intl402/DurationFormat/supportedLocalesOf/length.js new file mode 100644 index 000000000000..b3c6b3e1d2d0 --- /dev/null +++ b/js/src/tests/test262/intl402/DurationFormat/supportedLocalesOf/length.js @@ -0,0 +1,25 @@ +// |reftest| skip -- Intl.DurationFormat is not supported +// Copyright 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DurationFormat.supportedLocalesOf +description: > + Checks the "length" property of Intl.DurationFormat.supportedLocalesOf(). +info: | + The value of the length property of the supportedLocalesOf method is 1. + Unless specified otherwise in this document, the objects, functions, and constructors described in this standard are subject to the generic requirements and restrictions specified for standard built-in ECMAScript objects in the ECMAScript 2019 Language Specification, 10th edition, clause 17, or successor. + Every built-in function object, including constructors, has a length property whose value is an integer. + Unless otherwise specified, the length property of a built-in function object has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [Intl.DurationFormat] +---*/ + +verifyProperty(Intl.DurationFormat.supportedLocalesOf, "length", { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DurationFormat/supportedLocalesOf/locales-empty.js b/js/src/tests/test262/intl402/DurationFormat/supportedLocalesOf/locales-empty.js new file mode 100644 index 000000000000..14fc1b049439 --- /dev/null +++ b/js/src/tests/test262/intl402/DurationFormat/supportedLocalesOf/locales-empty.js @@ -0,0 +1,22 @@ +// |reftest| skip -- Intl.DurationFormat is not supported +// Copyright 2022 Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DurationFormat.supportedLocalesOf +description: Checks handling of an empty locales argument to the supportedLocalesOf function. +info: | + Intl.DurationFormat.supportedLocalesOf ( locales [, options ]) + (...) + 3. Return ? SupportedLocales(availableLocales, requestedLocales, options). +includes: [compareArray.js] +features: [Intl.DurationFormat] +---*/ + +assert.sameValue(typeof Intl.DurationFormat.supportedLocalesOf, "function", + "Should support Intl.DurationFormat.supportedLocalesOf."); + +assert.compareArray(Intl.DurationFormat.supportedLocalesOf(), []); +assert.compareArray(Intl.DurationFormat.supportedLocalesOf([]), []); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DurationFormat/supportedLocalesOf/locales-invalid.js b/js/src/tests/test262/intl402/DurationFormat/supportedLocalesOf/locales-invalid.js new file mode 100644 index 000000000000..8f5e8c0e81fa --- /dev/null +++ b/js/src/tests/test262/intl402/DurationFormat/supportedLocalesOf/locales-invalid.js @@ -0,0 +1,23 @@ +// |reftest| skip -- Intl.DurationFormat is not supported +// Copyright 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DurationFormat.supportedLocalesOf +description: Checks error cases for the locales argument to the supportedLocalesOf function. +info: | + Intl.DurationFormat.supportedLocalesOf ( locales [, options ]) + (...) + 2. Let requestedLocales be CanonicalizeLocaleList(locales). +includes: [testIntl.js] +features: [Intl.DurationFormat] +---*/ + +assert.sameValue(typeof Intl.DurationFormat.supportedLocalesOf, "function", + "Should support Intl.DurationFormat.supportedLocalesOf."); + +for (const [locales, expectedError] of getInvalidLocaleArguments()) { + assert.throws(expectedError, () => Intl.DurationFormat.supportedLocalesOf(locales)); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DurationFormat/supportedLocalesOf/locales-specific.js b/js/src/tests/test262/intl402/DurationFormat/supportedLocalesOf/locales-specific.js new file mode 100644 index 000000000000..77696d7ef06e --- /dev/null +++ b/js/src/tests/test262/intl402/DurationFormat/supportedLocalesOf/locales-specific.js @@ -0,0 +1,25 @@ +// |reftest| skip -- Intl.DurationFormat is not supported +// Copyright 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DurationFormat.supportedLocalesOf +description: Checks handling of specific locales arguments to the supportedLocalesOf function. +info: | + Intl.DurationFormat.supportedLocalesOf ( locales [, options ]) + (...) + 3. Return ? SupportedLocales(availableLocales, requestedLocales, options). +includes: [compareArray.js] +locale: [sr, sr-Thai-RS, de, zh-CN] +features: [Intl.DurationFormat] +---*/ + +assert.sameValue(typeof Intl.DurationFormat.supportedLocalesOf, "function", + "Should support Intl.DurationFormat.supportedLocalesOf."); + +assert.compareArray(Intl.DurationFormat.supportedLocalesOf("sr"), ["sr"]); + +const multiLocale = ["sr-Thai-RS", "de", "zh-CN"]; +assert.compareArray(Intl.DurationFormat.supportedLocalesOf(multiLocale, {localeMatcher: "lookup"}), multiLocale); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DurationFormat/supportedLocalesOf/name.js b/js/src/tests/test262/intl402/DurationFormat/supportedLocalesOf/name.js new file mode 100644 index 000000000000..dc452628d03a --- /dev/null +++ b/js/src/tests/test262/intl402/DurationFormat/supportedLocalesOf/name.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Intl.DurationFormat is not supported +// Copyright 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DurationFormat.supportedLocalesOf +description: > + Checks the "name" property of Intl.DurationFormat.supportedLocalesOf(). +info: | + Unless specified otherwise in this document, the objects, functions, and constructors described in this standard are subject to the generic requirements and restrictions specified for standard built-in ECMAScript objects in the ECMAScript 2019 Language Specification, 10th edition, clause 17, or successor. + Every built-in function object, including constructors, that is not identified as an anonymous function has a name property whose value is a String. Unless otherwise specified, this value is the name that is given to the function in this specification. + Unless otherwise specified, the name property of a built-in function object, if it exists, has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [Intl.DurationFormat] +---*/ + +verifyProperty(Intl.DurationFormat.supportedLocalesOf, "name", { + value: "supportedLocalesOf", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DurationFormat/supportedLocalesOf/prop-desc.js b/js/src/tests/test262/intl402/DurationFormat/supportedLocalesOf/prop-desc.js new file mode 100644 index 000000000000..ff212a970497 --- /dev/null +++ b/js/src/tests/test262/intl402/DurationFormat/supportedLocalesOf/prop-desc.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Intl.DurationFormat is not supported +// Copyright 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DurationFormat.supportedLocalesOf +description: > + Checks the "supportedLocalesOf" property of the DurationFormat prototype object. +info: | + Intl.DurationFormat.supportedLocalesOf ( locales [, options ]) + + Unless specified otherwise in this document, the objects, functions, and constructors described in this standard are subject to the generic requirements and restrictions specified for standard built-in ECMAScript objects in the ECMAScript 2019 Language Specification, 10th edition, clause 17, or successor. + + Every other data property described in clauses 18 through 26 and in Annex B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true } unless otherwise specified. +includes: [propertyHelper.js] +features: [Intl.DurationFormat] +---*/ + +assert.sameValue( + typeof Intl.DurationFormat.supportedLocalesOf, + "function", + "typeof Intl.DurationFormat.supportedLocalesOf is function" +); + +verifyProperty(Intl.DurationFormat, "supportedLocalesOf", { + writable: true, + enumerable: false, + configurable: true, +}); + + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DurationFormat/supportedLocalesOf/shell.js b/js/src/tests/test262/intl402/DurationFormat/supportedLocalesOf/shell.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/js/src/tests/test262/intl402/NumberFormat/constructor-roundingIncrement.js b/js/src/tests/test262/intl402/NumberFormat/constructor-roundingIncrement.js index 373c43e65c94..998eef502014 100644 --- a/js/src/tests/test262/intl402/NumberFormat/constructor-roundingIncrement.js +++ b/js/src/tests/test262/intl402/NumberFormat/constructor-roundingIncrement.js @@ -40,7 +40,8 @@ for (const [value, expected] of values) { get roundingIncrement() { callOrder.push("roundingIncrement"); return value; - } + }, + minimumFractionDigits: 3 }); const resolvedOptions = nf.resolvedOptions(); assert("roundingIncrement" in resolvedOptions, "has property for value " + value); diff --git a/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-10.js b/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-10.js index 573d099efe94..1406a91527e1 100644 --- a/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-10.js +++ b/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-10.js @@ -16,26 +16,26 @@ var numberingSystems = ['arab', 'latn', 'thai', 'hanidec']; testNumberFormat( locales, numberingSystems, - {roundingIncrement: 10, maximumFractionDigits: 2}, + {roundingIncrement: 10, maximumFractionDigits: 2, minimumFractionDigits: 2}, { - '1.100': '1.1', - '1.125': '1.1', - '1.150': '1.2', - '1.175': '1.2', - '1.200': '1.2', + '1.100': '1.10', + '1.125': '1.10', + '1.150': '1.20', + '1.175': '1.20', + '1.200': '1.20', } ); testNumberFormat( locales, numberingSystems, - {roundingIncrement: 10, maximumFractionDigits: 3}, + {roundingIncrement: 10, maximumFractionDigits: 3, minimumFractionDigits: 3}, { - '1.0100': '1.01', - '1.0125': '1.01', - '1.0150': '1.02', - '1.0175': '1.02', - '1.0200': '1.02', + '1.0100': '1.010', + '1.0125': '1.010', + '1.0150': '1.020', + '1.0175': '1.020', + '1.0200': '1.020', } ); diff --git a/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-100.js b/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-100.js index 34cf6134c790..f7b55e83220a 100644 --- a/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-100.js +++ b/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-100.js @@ -16,26 +16,26 @@ var numberingSystems = ['arab', 'latn', 'thai', 'hanidec']; testNumberFormat( locales, numberingSystems, - {roundingIncrement: 100, maximumFractionDigits: 3}, + {roundingIncrement: 100, maximumFractionDigits: 3, minimumFractionDigits: 3}, { - '1.100': '1.1', - '1.125': '1.1', - '1.150': '1.2', - '1.175': '1.2', - '1.200': '1.2', + '1.100': '1.100', + '1.125': '1.100', + '1.150': '1.200', + '1.175': '1.200', + '1.200': '1.200', } ); testNumberFormat( locales, numberingSystems, - {roundingIncrement: 100, maximumFractionDigits: 4}, + {roundingIncrement: 100, maximumFractionDigits: 4, minimumFractionDigits: 4}, { - '1.0100': '1.01', - '1.0125': '1.01', - '1.0150': '1.02', - '1.0175': '1.02', - '1.0200': '1.02', + '1.0100': '1.0100', + '1.0125': '1.0100', + '1.0150': '1.0200', + '1.0175': '1.0200', + '1.0200': '1.0200', } ); diff --git a/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-1000.js b/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-1000.js index 6d12cb423d93..75405a53c450 100644 --- a/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-1000.js +++ b/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-1000.js @@ -16,26 +16,26 @@ var numberingSystems = ['arab', 'latn', 'thai', 'hanidec']; testNumberFormat( locales, numberingSystems, - {roundingIncrement: 1000, maximumFractionDigits: 4}, + {roundingIncrement: 1000, maximumFractionDigits: 4, minimumFractionDigits: 4}, { - '1.100': '1.1', - '1.125': '1.1', - '1.150': '1.2', - '1.175': '1.2', - '1.200': '1.2', + '1.100': '1.1000', + '1.125': '1.1000', + '1.150': '1.2000', + '1.175': '1.2000', + '1.200': '1.2000', } ); testNumberFormat( locales, numberingSystems, - {roundingIncrement: 1000, maximumFractionDigits: 5}, + {roundingIncrement: 1000, maximumFractionDigits: 5, minimumFractionDigits: 5}, { - '1.0100': '1.01', - '1.0125': '1.01', - '1.0150': '1.02', - '1.0175': '1.02', - '1.0200': '1.02', + '1.0100': '1.01000', + '1.0125': '1.01000', + '1.0150': '1.02000', + '1.0175': '1.02000', + '1.0200': '1.02000', } ); diff --git a/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-2.js b/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-2.js index 326d2cd0f6d8..f9bf9e5fdc77 100644 --- a/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-2.js +++ b/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-2.js @@ -16,7 +16,7 @@ var numberingSystems = ['arab', 'latn', 'thai', 'hanidec']; testNumberFormat( locales, numberingSystems, - {roundingIncrement: 2, maximumFractionDigits: 1}, + {roundingIncrement: 2, maximumFractionDigits: 1, minimumFractionDigits: 1}, { '1.20': '1.2', '1.25': '1.2', @@ -29,7 +29,7 @@ testNumberFormat( testNumberFormat( locales, numberingSystems, - {roundingIncrement: 2, maximumFractionDigits: 2}, + {roundingIncrement: 2, maximumFractionDigits: 2, minimumFractionDigits: 2}, { '1.020': '1.02', '1.025': '1.02', diff --git a/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-20.js b/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-20.js index a0c5da43c2e9..c4a49d36236c 100644 --- a/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-20.js +++ b/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-20.js @@ -16,26 +16,26 @@ var numberingSystems = ['arab', 'latn', 'thai', 'hanidec']; testNumberFormat( locales, numberingSystems, - {roundingIncrement: 20, maximumFractionDigits: 2}, + {roundingIncrement: 20, maximumFractionDigits: 2, minimumFractionDigits: 2}, { - '1.20': '1.2', - '1.25': '1.2', - '1.30': '1.4', - '1.35': '1.4', - '1.40': '1.4', + '1.20': '1.20', + '1.25': '1.20', + '1.30': '1.40', + '1.35': '1.40', + '1.40': '1.40', } ); testNumberFormat( locales, numberingSystems, - {roundingIncrement: 20, maximumFractionDigits: 3}, + {roundingIncrement: 20, maximumFractionDigits: 3, minimumFractionDigits: 3}, { - '1.020': '1.02', - '1.025': '1.02', - '1.030': '1.04', - '1.035': '1.04', - '1.040': '1.04', + '1.020': '1.020', + '1.025': '1.020', + '1.030': '1.040', + '1.035': '1.040', + '1.040': '1.040', } ); diff --git a/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-200.js b/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-200.js index f8eaa0abee58..eea528007f5e 100644 --- a/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-200.js +++ b/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-200.js @@ -16,26 +16,26 @@ var numberingSystems = ['arab', 'latn', 'thai', 'hanidec']; testNumberFormat( locales, numberingSystems, - {roundingIncrement: 200, maximumFractionDigits: 3}, + {roundingIncrement: 200, maximumFractionDigits: 3, minimumFractionDigits: 3}, { - '1.20': '1.2', - '1.25': '1.2', - '1.30': '1.4', - '1.35': '1.4', - '1.40': '1.4', + '1.20': '1.200', + '1.25': '1.200', + '1.30': '1.400', + '1.35': '1.400', + '1.40': '1.400', } ); testNumberFormat( locales, numberingSystems, - {roundingIncrement: 200, maximumFractionDigits: 4}, + {roundingIncrement: 200, maximumFractionDigits: 4, minimumFractionDigits: 4}, { - '1.020': '1.02', - '1.025': '1.02', - '1.030': '1.04', - '1.035': '1.04', - '1.040': '1.04', + '1.020': '1.0200', + '1.025': '1.0200', + '1.030': '1.0400', + '1.035': '1.0400', + '1.040': '1.0400', } ); diff --git a/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-2000.js b/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-2000.js index 53695ab55d05..8ce0bd24ad32 100644 --- a/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-2000.js +++ b/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-2000.js @@ -16,26 +16,26 @@ var numberingSystems = ['arab', 'latn', 'thai', 'hanidec']; testNumberFormat( locales, numberingSystems, - {roundingIncrement: 2000, maximumFractionDigits: 4}, + {roundingIncrement: 2000, maximumFractionDigits: 4, minimumFractionDigits: 4}, { - '1.20': '1.2', - '1.25': '1.2', - '1.30': '1.4', - '1.35': '1.4', - '1.40': '1.4', + '1.20': '1.2000', + '1.25': '1.2000', + '1.30': '1.4000', + '1.35': '1.4000', + '1.40': '1.4000', } ); testNumberFormat( locales, numberingSystems, - {roundingIncrement: 2000, maximumFractionDigits: 5}, + {roundingIncrement: 2000, maximumFractionDigits: 5, minimumFractionDigits: 5}, { - '1.020': '1.02', - '1.025': '1.02', - '1.030': '1.04', - '1.035': '1.04', - '1.040': '1.04', + '1.020': '1.02000', + '1.025': '1.02000', + '1.030': '1.04000', + '1.035': '1.04000', + '1.040': '1.04000', } ); diff --git a/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-25.js b/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-25.js index d2e3aaefb2f2..dd5262a4bf73 100644 --- a/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-25.js +++ b/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-25.js @@ -16,26 +16,26 @@ var numberingSystems = ['arab', 'latn', 'thai', 'hanidec']; testNumberFormat( locales, numberingSystems, - {roundingIncrement: 25, maximumFractionDigits: 2, minimumFractionDigits: 1}, + {roundingIncrement: 25, maximumFractionDigits: 2, minimumFractionDigits: 2}, { '1.2500': '1.25', '1.3125': '1.25', - '1.3750': '1.5', - '1.4375': '1.5', - '1.5000': '1.5', + '1.3750': '1.50', + '1.4375': '1.50', + '1.5000': '1.50', } ); testNumberFormat( locales, numberingSystems, - {roundingIncrement: 25, maximumFractionDigits: 3}, + {roundingIncrement: 25, maximumFractionDigits: 3, minimumFractionDigits: 3}, { '1.02500': '1.025', '1.03125': '1.025', - '1.03750': '1.05', - '1.04375': '1.05', - '1.05000': '1.05', + '1.03750': '1.050', + '1.04375': '1.050', + '1.05000': '1.050', } ); diff --git a/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-250.js b/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-250.js index 5f3c6ec8e538..6f2183eeb327 100644 --- a/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-250.js +++ b/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-250.js @@ -16,26 +16,26 @@ var numberingSystems = ['arab', 'latn', 'thai', 'hanidec']; testNumberFormat( locales, numberingSystems, - {roundingIncrement: 250, maximumFractionDigits: 3, minimumFractionDigits: 1}, + {roundingIncrement: 250, maximumFractionDigits: 3, minimumFractionDigits: 3}, { - '1.2500': '1.25', - '1.3125': '1.25', - '1.3750': '1.5', - '1.4375': '1.5', - '1.5000': '1.5', + '1.2500': '1.250', + '1.3125': '1.250', + '1.3750': '1.500', + '1.4375': '1.500', + '1.5000': '1.500', } ); testNumberFormat( locales, numberingSystems, - {roundingIncrement: 250, maximumFractionDigits: 4}, + {roundingIncrement: 250, maximumFractionDigits: 4, minimumFractionDigits: 4}, { - '1.02500': '1.025', - '1.03125': '1.025', - '1.03750': '1.05', - '1.04375': '1.05', - '1.05000': '1.05', + '1.02500': '1.0250', + '1.03125': '1.0250', + '1.03750': '1.0500', + '1.04375': '1.0500', + '1.05000': '1.0500', } ); diff --git a/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-2500.js b/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-2500.js index f7cc0e5e3b4c..afae882ee9b9 100644 --- a/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-2500.js +++ b/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-2500.js @@ -16,26 +16,26 @@ var numberingSystems = ['arab', 'latn', 'thai', 'hanidec']; testNumberFormat( locales, numberingSystems, - {roundingIncrement: 2500, maximumFractionDigits: 4, minimumFractionDigits: 1}, + {roundingIncrement: 2500, maximumFractionDigits: 4, minimumFractionDigits: 4}, { - '1.2500': '1.25', - '1.3125': '1.25', - '1.3750': '1.5', - '1.4375': '1.5', - '1.5000': '1.5', + '1.2500': '1.2500', + '1.3125': '1.2500', + '1.3750': '1.5000', + '1.4375': '1.5000', + '1.5000': '1.5000', } ); testNumberFormat( locales, numberingSystems, - {roundingIncrement: 2500, maximumFractionDigits: 5}, + {roundingIncrement: 2500, maximumFractionDigits: 5, minimumFractionDigits: 5}, { - '1.02500': '1.025', - '1.03125': '1.025', - '1.03750': '1.05', - '1.04375': '1.05', - '1.05000': '1.05', + '1.02500': '1.02500', + '1.03125': '1.02500', + '1.03750': '1.05000', + '1.04375': '1.05000', + '1.05000': '1.05000', } ); diff --git a/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-5.js b/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-5.js index fe314ad1d3a2..23bf39eb6c47 100644 --- a/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-5.js +++ b/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-5.js @@ -29,13 +29,13 @@ testNumberFormat( testNumberFormat( locales, numberingSystems, - {roundingIncrement: 5, maximumFractionDigits: 2}, + {roundingIncrement: 5, maximumFractionDigits: 2, minimumFractionDigits: 2}, { '1.0500': '1.05', '1.0625': '1.05', - '1.0750': '1.1', - '1.0875': '1.1', - '1.1000': '1.1', + '1.0750': '1.10', + '1.0875': '1.10', + '1.1000': '1.10', } ); diff --git a/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-50.js b/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-50.js index 864ae7fe1e67..f7e9cbb4c48d 100644 --- a/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-50.js +++ b/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-50.js @@ -16,26 +16,26 @@ var numberingSystems = ['arab', 'latn', 'thai', 'hanidec']; testNumberFormat( locales, numberingSystems, - {roundingIncrement: 50, maximumFractionDigits: 2, minimumFractionDigits: 1}, + {roundingIncrement: 50, maximumFractionDigits: 2, minimumFractionDigits: 2}, { - '1.500': '1.5', - '1.625': '1.5', - '1.750': '2.0', - '1.875': '2.0', - '2.000': '2.0', + '1.500': '1.50', + '1.625': '1.50', + '1.750': '2.00', + '1.875': '2.00', + '2.000': '2.00', } ); testNumberFormat( locales, numberingSystems, - {roundingIncrement: 50, maximumFractionDigits: 3}, + {roundingIncrement: 50, maximumFractionDigits: 3, minimumFractionDigits: 3}, { - '1.0500': '1.05', - '1.0625': '1.05', - '1.0750': '1.1', - '1.0875': '1.1', - '1.1000': '1.1', + '1.0500': '1.050', + '1.0625': '1.050', + '1.0750': '1.100', + '1.0875': '1.100', + '1.1000': '1.100', } ); diff --git a/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-500.js b/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-500.js index e2d8ffcb898e..d8d00e7621e9 100644 --- a/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-500.js +++ b/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-500.js @@ -16,26 +16,26 @@ var numberingSystems = ['arab', 'latn', 'thai', 'hanidec']; testNumberFormat( locales, numberingSystems, - {roundingIncrement: 500, maximumFractionDigits: 3, minimumFractionDigits: 1}, + {roundingIncrement: 500, maximumFractionDigits: 3, minimumFractionDigits: 3}, { - '1.500': '1.5', - '1.625': '1.5', - '1.750': '2.0', - '1.875': '2.0', - '2.000': '2.0', + '1.500': '1.500', + '1.625': '1.500', + '1.750': '2.000', + '1.875': '2.000', + '2.000': '2.000', } ); testNumberFormat( locales, numberingSystems, - {roundingIncrement: 500, maximumFractionDigits: 4}, + {roundingIncrement: 500, maximumFractionDigits: 4, minimumFractionDigits: 4}, { - '1.0500': '1.05', - '1.0625': '1.05', - '1.0750': '1.1', - '1.0875': '1.1', - '1.1000': '1.1', + '1.0500': '1.0500', + '1.0625': '1.0500', + '1.0750': '1.1000', + '1.0875': '1.1000', + '1.1000': '1.1000', } ); diff --git a/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-5000.js b/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-5000.js index 4e4cd1c302b0..f9d956c13ef3 100644 --- a/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-5000.js +++ b/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-increment-5000.js @@ -16,26 +16,26 @@ var numberingSystems = ['arab', 'latn', 'thai', 'hanidec']; testNumberFormat( locales, numberingSystems, - {roundingIncrement: 5000, maximumFractionDigits: 4, minimumFractionDigits: 1}, + {roundingIncrement: 5000, maximumFractionDigits: 4, minimumFractionDigits: 4}, { - '1.500': '1.5', - '1.625': '1.5', - '1.750': '2.0', - '1.875': '2.0', - '2.000': '2.0', + '1.500': '1.5000', + '1.625': '1.5000', + '1.750': '2.0000', + '1.875': '2.0000', + '2.000': '2.0000', } ); testNumberFormat( locales, numberingSystems, - {roundingIncrement: 5000, maximumFractionDigits: 5}, + {roundingIncrement: 5000, maximumFractionDigits: 5, minimumFractionDigits: 5}, { - '1.0500': '1.05', - '1.0625': '1.05', - '1.0750': '1.1', - '1.0875': '1.1', - '1.1000': '1.1', + '1.0500': '1.05000', + '1.0625': '1.05000', + '1.0750': '1.10000', + '1.0875': '1.10000', + '1.1000': '1.10000', } ); diff --git a/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-priority-more-precision.js b/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-priority-more-precision.js index 93ff0169c573..a3591d002e68 100644 --- a/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-priority-more-precision.js +++ b/js/src/tests/test262/intl402/NumberFormat/prototype/format/format-rounding-priority-more-precision.js @@ -15,15 +15,15 @@ var locales = [ ]; var numberingSystems = ['arab', 'latn', 'thai', 'hanidec']; -// minimumSignificantDigits is less precise +// maximumSignificantDigits defaults to 21, beating maximumFractionDigits, which defaults to 3 testNumberFormat( locales, numberingSystems, {useGrouping: false, roundingPriority: 'morePrecision', minimumSignificantDigits: 2, minimumFractionDigits: 2}, - {'1': '1.00'} + {'1': '1.0'} ); -// minimumSignificantDigits is more precise +// maximumSignificantDigits defaults to 21, beating maximumFractionDigits, which defaults to 3 testNumberFormat( locales, numberingSystems, diff --git a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/dateAdd/shell.js b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/dateAdd/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/dateAdd/shell.js +++ b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/dateAdd/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/dateFromFields/shell.js b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/dateFromFields/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/dateFromFields/shell.js +++ b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/dateFromFields/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/dateUntil/shell.js b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/dateUntil/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/dateUntil/shell.js +++ b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/dateUntil/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/day/shell.js b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/day/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/day/shell.js +++ b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/day/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/dayOfWeek/shell.js b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/dayOfWeek/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/dayOfWeek/shell.js +++ b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/dayOfWeek/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/dayOfYear/shell.js b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/dayOfYear/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/dayOfYear/shell.js +++ b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/dayOfYear/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/daysInMonth/shell.js b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/daysInMonth/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/daysInMonth/shell.js +++ b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/daysInMonth/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/daysInWeek/shell.js b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/daysInWeek/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/daysInWeek/shell.js +++ b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/daysInWeek/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/daysInYear/shell.js b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/daysInYear/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/daysInYear/shell.js +++ b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/daysInYear/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/era/argument-number.js b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/era/argument-number.js new file mode 100644 index 000000000000..86e0a8b73546 --- /dev/null +++ b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/era/argument-number.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.era +description: A number is converted to a string, then to Temporal.PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const arg = 19761118; + +const result = instance.era(arg); +assert.sameValue(result, undefined, "19761118 is a valid ISO string for PlainDate"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.era(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/era/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/era/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..f383d743a649 --- /dev/null +++ b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/era/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,31 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.era +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.era(arg); +assert.sameValue( + result1, + undefined, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.era(arg); +assert.sameValue( + result2, + undefined, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/era/argument-propertybag-calendar-number.js b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/era/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..380b59a09265 --- /dev/null +++ b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/era/argument-propertybag-calendar-number.js @@ -0,0 +1,44 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.era +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.era(arg); +assert.sameValue(result1, undefined, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.era(arg); +assert.sameValue(result2, undefined, "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + assert.throws( + RangeError, + () => instance.era(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.era(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/era/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/era/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..d9bae3bbf32f --- /dev/null +++ b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/era/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.era +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.Calendar("iso8601"); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.era(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.era(arg), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.era(arg), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.era(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.era(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/era/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/era/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..a73d71dcd12c --- /dev/null +++ b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/era/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.era +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.era(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/era/argument-wrong-type.js b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/era/argument-wrong-type.js new file mode 100644 index 000000000000..a04cacc7ee57 --- /dev/null +++ b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/era/argument-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.era +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.era(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.era(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/era/leap-second.js b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/era/leap-second.js new file mode 100644 index 000000000000..7c4cf929c4f9 --- /dev/null +++ b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/era/leap-second.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.era +description: Leap second is a valid ISO string for PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.era(arg); +assert.sameValue( + result1, + undefined, + "leap second is a valid ISO string for PlainDate" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.era(arg); +assert.sameValue( + result2, + undefined, + "second: 60 is ignored in property bag for PlainDate" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/era/shell.js b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/era/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/era/shell.js +++ b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/era/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/era/year-zero.js b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/era/year-zero.js index 9686051bef45..c9b96fd06058 100644 --- a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/era/year-zero.js +++ b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/era/year-zero.js @@ -8,13 +8,19 @@ description: Negative zero, as an extended year, is rejected features: [Temporal, arrow-function] ---*/ -const arg = "-000000-10-31"; +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; const instance = new Temporal.Calendar("iso8601"); - -assert.throws( +invalidStrings.forEach((arg) => { + assert.throws( RangeError, - () => { instance.era(arg); }, + () => instance.era(arg), "reject minus zero as extended year" -); + ); +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/eraYear/argument-number.js b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/eraYear/argument-number.js new file mode 100644 index 000000000000..d662a1a2af02 --- /dev/null +++ b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/eraYear/argument-number.js @@ -0,0 +1,32 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.erayear +description: A number is converted to a string, then to Temporal.PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const arg = 19761118; + +const result = instance.eraYear(arg); +assert.sameValue(result, undefined, "19761118 is a valid ISO string for PlainDate"); + +const numbers = [ + 1, + -19761118, + 1234567890, +]; + +for (const arg of numbers) { + assert.throws( + RangeError, + () => instance.eraYear(arg), + `Number ${arg} does not convert to a valid ISO string for PlainDate` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/eraYear/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/eraYear/argument-propertybag-calendar-leap-second.js new file mode 100644 index 000000000000..aa093c6ff520 --- /dev/null +++ b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/eraYear/argument-propertybag-calendar-leap-second.js @@ -0,0 +1,31 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.erayear +description: Leap second is a valid ISO string for a calendar in a property bag +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = "2016-12-31T23:59:60"; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.eraYear(arg); +assert.sameValue( + result1, + undefined, + "leap second is a valid ISO string for calendar" +); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.eraYear(arg); +assert.sameValue( + result2, + undefined, + "leap second is a valid ISO string for calendar (nested property)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/eraYear/argument-propertybag-calendar-number.js b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/eraYear/argument-propertybag-calendar-number.js new file mode 100644 index 000000000000..bb33f23812c5 --- /dev/null +++ b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/eraYear/argument-propertybag-calendar-number.js @@ -0,0 +1,44 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.erayear +description: A number as calendar in a property bag is converted to a string, then to a calendar +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const calendar = 19970327; + +let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; +const result1 = instance.eraYear(arg); +assert.sameValue(result1, undefined, "19970327 is a valid ISO string for calendar"); + +arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; +const result2 = instance.eraYear(arg); +assert.sameValue(result2, undefined, "19970327 is a valid ISO string for calendar (nested property)"); + +const numbers = [ + 1, + -19970327, + 1234567890, +]; + +for (const calendar of numbers) { + let arg = { year: 1976, monthCode: "M11", day: 18, calendar }; + assert.throws( + RangeError, + () => instance.eraYear(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar` + ); + arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } }; + assert.throws( + RangeError, + () => instance.eraYear(arg), + `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)` + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/eraYear/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/eraYear/argument-propertybag-calendar-wrong-type.js new file mode 100644 index 000000000000..aa9d3703def4 --- /dev/null +++ b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/eraYear/argument-propertybag-calendar-wrong-type.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.erayear +description: > + Appropriate error thrown when a calendar property from a property bag cannot + be converted to a calendar object or string +features: [BigInt, Symbol, Temporal] +---*/ + +const timeZone = new Temporal.TimeZone("UTC"); +const instance = new Temporal.Calendar("iso8601"); + +const rangeErrorTests = [ + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [calendar, description] of rangeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(RangeError, () => instance.eraYear(arg), `${description} does not convert to a valid ISO string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(RangeError, () => instance.eraYear(arg), `${description} does not convert to a valid ISO string (nested property)`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], // TypeError due to missing dateFromFields() + [Temporal.Calendar, "Temporal.Calendar, object"], // ditto + [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields() +]; + +for (const [calendar, description] of typeErrorTests) { + let arg = { year: 2019, monthCode: "M11", day: 1, calendar }; + assert.throws(TypeError, () => instance.eraYear(arg), `${description} is not a valid property bag and does not convert to a string`); + + arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } }; + assert.throws(TypeError, () => instance.eraYear(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`); +} + +const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } }; +assert.throws(RangeError, () => instance.eraYear(arg), `nested undefined calendar property is always a RangeError`); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/eraYear/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/eraYear/argument-propertybag-calendar-year-zero.js new file mode 100644 index 000000000000..c7d8970caa99 --- /dev/null +++ b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/eraYear/argument-propertybag-calendar-year-zero.js @@ -0,0 +1,27 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.erayear +description: Negative zero, as an extended year, is rejected +features: [Temporal, arrow-function] +---*/ + +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T17:45", + "-000000-10-31T17:45Z", + "-000000-10-31T17:45+01:00", + "-000000-10-31T17:45+00:00[UTC]", +]; +const instance = new Temporal.Calendar("iso8601"); +invalidStrings.forEach((arg) => { + assert.throws( + RangeError, + () => instance.eraYear(arg), + "reject minus zero as extended year" + ); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/eraYear/argument-wrong-type.js b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/eraYear/argument-wrong-type.js new file mode 100644 index 000000000000..dc5442e7b349 --- /dev/null +++ b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/eraYear/argument-wrong-type.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.erayear +description: > + Appropriate error thrown when argument cannot be converted to a valid string + or property bag for PlainDate +features: [BigInt, Symbol, Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +const rangeErrorTests = [ + [undefined, "undefined"], + [null, "null"], + [true, "boolean"], + ["", "empty string"], + [1, "number that doesn't convert to a valid ISO string"], + [1n, "bigint"], +]; + +for (const [arg, description] of rangeErrorTests) { + assert.throws(RangeError, () => instance.eraYear(arg), `${description} does not convert to a valid ISO string`); +} + +const typeErrorTests = [ + [Symbol(), "symbol"], + [{}, "plain object"], + [Temporal.PlainDate, "Temporal.PlainDate, object"], + [Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"], +]; + +for (const [arg, description] of typeErrorTests) { + assert.throws(TypeError, () => instance.eraYear(arg), `${description} is not a valid property bag and does not convert to a string`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/eraYear/leap-second.js b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/eraYear/leap-second.js new file mode 100644 index 000000000000..14d6143cd892 --- /dev/null +++ b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/eraYear/leap-second.js @@ -0,0 +1,29 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.erayear +description: Leap second is a valid ISO string for PlainDate +features: [Temporal] +---*/ + +const instance = new Temporal.Calendar("iso8601"); + +let arg = "2016-12-31T23:59:60"; +const result1 = instance.eraYear(arg); +assert.sameValue( + result1, + undefined, + "leap second is a valid ISO string for PlainDate" +); + +arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 }; +const result2 = instance.eraYear(arg); +assert.sameValue( + result2, + undefined, + "second: 60 is ignored in property bag for PlainDate" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/eraYear/shell.js b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/eraYear/shell.js index 5228295abfe7..c7e0a3ac4e76 100644 --- a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/eraYear/shell.js +++ b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/eraYear/shell.js @@ -172,20 +172,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -259,39 +260,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/eraYear/year-zero.js b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/eraYear/year-zero.js index 9e25ef926e02..0efe291dcf70 100644 --- a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/eraYear/year-zero.js +++ b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/eraYear/year-zero.js @@ -8,13 +8,19 @@ description: Negative zero, as an extended year, is rejected features: [Temporal, arrow-function] ---*/ -const arg = "-000000-10-31"; +const invalidStrings = [ + "-000000-10-31", + "-000000-10-31T00:45", + "-000000-10-31T00:45+01:00", + "-000000-10-31T00:45+00:00[UTC]", +]; const instance = new Temporal.Calendar("iso8601"); - -assert.throws( +invalidStrings.forEach((arg) => { + assert.throws( RangeError, - () => { instance.eraYear(arg); }, + () => instance.eraYear(arg), "reject minus zero as extended year" -); + ); +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/inLeapYear/shell.js b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/inLeapYear/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/inLeapYear/shell.js +++ b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/inLeapYear/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/month/shell.js b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/month/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/month/shell.js +++ b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/month/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/monthCode/shell.js b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/monthCode/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/monthCode/shell.js +++ b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/monthCode/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/monthDayFromFields/shell.js b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/monthDayFromFields/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/monthDayFromFields/shell.js +++ b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/monthDayFromFields/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/monthsInYear/shell.js b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/monthsInYear/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/monthsInYear/shell.js +++ b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/monthsInYear/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/weekOfYear/shell.js b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/weekOfYear/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/weekOfYear/shell.js +++ b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/weekOfYear/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/year/shell.js b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/year/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/year/shell.js +++ b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/year/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/yearMonthFromFields/shell.js b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/yearMonthFromFields/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/Calendar/prototype/yearMonthFromFields/shell.js +++ b/js/src/tests/test262/intl402/Temporal/Calendar/prototype/yearMonthFromFields/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/Duration/compare/browser.js b/js/src/tests/test262/intl402/Temporal/Duration/compare/browser.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/js/src/tests/test262/intl402/Temporal/Duration/compare/relativeto-hour.js b/js/src/tests/test262/intl402/Temporal/Duration/compare/relativeto-hour.js new file mode 100644 index 000000000000..325482b62d50 --- /dev/null +++ b/js/src/tests/test262/intl402/Temporal/Duration/compare/relativeto-hour.js @@ -0,0 +1,34 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.compare +description: relativeTo with hours. +features: [Temporal] +---*/ + +const oneDay = new Temporal.Duration(0, 0, 0, 1); +const hours24 = new Temporal.Duration(0, 0, 0, 0, 24); + +assert.sameValue( + Temporal.Duration.compare(oneDay, hours24, { relativeTo: Temporal.ZonedDateTime.from('2017-01-01T00:00[America/Montevideo]') }), + 0, + 'relativeTo does not affect days if ZonedDateTime, and duration encompasses no DST change'); +assert.sameValue( + Temporal.Duration.compare(oneDay, hours24, { relativeTo: Temporal.ZonedDateTime.from('2019-11-03T00:00[America/Vancouver]') }), + 1, + 'relativeTo does affect days if ZonedDateTime, and duration encompasses DST change'); +assert.sameValue( + Temporal.Duration.compare(oneDay, hours24, { relativeTo: '2019-11-03T00:00[America/Vancouver]' }), + 1, + 'casts relativeTo to ZonedDateTime from string'); +assert.sameValue( + Temporal.Duration.compare(oneDay, hours24, { + relativeTo: { year: 2019, month: 11, day: 3, timeZone: 'America/Vancouver' } + }), + 1, + 'casts relativeTo to ZonedDateTime from object'); + + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Temporal/Duration/compare/shell.js b/js/src/tests/test262/intl402/Temporal/Duration/compare/shell.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/js/src/tests/test262/intl402/Temporal/Duration/prototype/add/shell.js b/js/src/tests/test262/intl402/Temporal/Duration/prototype/add/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/Duration/prototype/add/shell.js +++ b/js/src/tests/test262/intl402/Temporal/Duration/prototype/add/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/Duration/prototype/round/shell.js b/js/src/tests/test262/intl402/Temporal/Duration/prototype/round/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/Duration/prototype/round/shell.js +++ b/js/src/tests/test262/intl402/Temporal/Duration/prototype/round/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/Duration/prototype/subtract/shell.js b/js/src/tests/test262/intl402/Temporal/Duration/prototype/subtract/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/Duration/prototype/subtract/shell.js +++ b/js/src/tests/test262/intl402/Temporal/Duration/prototype/subtract/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/Duration/prototype/total/shell.js b/js/src/tests/test262/intl402/Temporal/Duration/prototype/total/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/Duration/prototype/total/shell.js +++ b/js/src/tests/test262/intl402/Temporal/Duration/prototype/total/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/Instant/prototype/toString/timezone-offset.js b/js/src/tests/test262/intl402/Temporal/Instant/prototype/toString/timezone-offset.js new file mode 100644 index 000000000000..15cc0dfaca19 --- /dev/null +++ b/js/src/tests/test262/intl402/Temporal/Instant/prototype/toString/timezone-offset.js @@ -0,0 +1,22 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2021 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.instant.prototype.tostring +description: The time zone offset part of the string serialization (Intl time zones) +features: [BigInt, Temporal] +---*/ + +const instant = new Temporal.Instant(0n); + +function test(timeZoneIdentifier, expected, description) { + const timeZone = new Temporal.TimeZone(timeZoneIdentifier); + assert.sameValue(instant.toString({ timeZone }), expected, description); +} + +test("Europe/Berlin", "1970-01-01T01:00:00+01:00", "positive offset"); +test("America/New_York", "1969-12-31T19:00:00-05:00", "negative offset"); +test("Africa/Monrovia", "1969-12-31T23:15:30-00:45", "sub-minute offset"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Temporal/PlainDate/compare/shell.js b/js/src/tests/test262/intl402/Temporal/PlainDate/compare/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/PlainDate/compare/shell.js +++ b/js/src/tests/test262/intl402/Temporal/PlainDate/compare/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/PlainDate/from/shell.js b/js/src/tests/test262/intl402/Temporal/PlainDate/from/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/PlainDate/from/shell.js +++ b/js/src/tests/test262/intl402/Temporal/PlainDate/from/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/PlainDate/prototype/equals/shell.js b/js/src/tests/test262/intl402/Temporal/PlainDate/prototype/equals/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/PlainDate/prototype/equals/shell.js +++ b/js/src/tests/test262/intl402/Temporal/PlainDate/prototype/equals/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/PlainDate/prototype/since/shell.js b/js/src/tests/test262/intl402/Temporal/PlainDate/prototype/since/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/PlainDate/prototype/since/shell.js +++ b/js/src/tests/test262/intl402/Temporal/PlainDate/prototype/since/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/PlainDate/prototype/until/shell.js b/js/src/tests/test262/intl402/Temporal/PlainDate/prototype/until/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/PlainDate/prototype/until/shell.js +++ b/js/src/tests/test262/intl402/Temporal/PlainDate/prototype/until/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/PlainDateTime/compare/shell.js b/js/src/tests/test262/intl402/Temporal/PlainDateTime/compare/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/PlainDateTime/compare/shell.js +++ b/js/src/tests/test262/intl402/Temporal/PlainDateTime/compare/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/PlainDateTime/from/shell.js b/js/src/tests/test262/intl402/Temporal/PlainDateTime/from/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/PlainDateTime/from/shell.js +++ b/js/src/tests/test262/intl402/Temporal/PlainDateTime/from/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/equals/shell.js b/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/equals/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/equals/shell.js +++ b/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/equals/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/since/shell.js b/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/since/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/since/shell.js +++ b/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/since/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/toString/browser.js b/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/toString/browser.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/toString/calendarname-always.js b/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/toString/calendarname-always.js new file mode 100644 index 000000000000..2c4299d62451 --- /dev/null +++ b/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/toString/calendarname-always.js @@ -0,0 +1,19 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.tostring +description: Show calendar when calendarName is "always" +features: [Temporal] +---*/ + +const dt = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 0, 0, 0, 0, "gregory"); + +assert.sameValue( + dt.toString({ calendarName: "always" }), + "1976-11-18T15:23:00[u-ca=gregory]", + "shows non-ISO calendar if calendarName = always" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/toString/calendarname-auto.js b/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/toString/calendarname-auto.js new file mode 100644 index 000000000000..69849ce7393c --- /dev/null +++ b/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/toString/calendarname-auto.js @@ -0,0 +1,17 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.tostring +description: Possibly display calendar when calendarName is "auto" +features: [Temporal] +---*/ + +const dt = new Temporal.PlainDateTime(1976, 11, 18, 15, 23, 0, 0, 0, 0, "gregory"); +const expected = "1976-11-18T15:23:00[u-ca=gregory]"; + +assert.sameValue(dt.toString(), expected, "shows non-ISO calendar by default (no arguments)"); +assert.sameValue(dt.toString({ calendarName: "auto" }), expected, "shows only non-ISO calendar if calendarName = auto"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/toString/calendarname-never.js b/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/toString/calendarname-never.js new file mode 100644 index 000000000000..a38ce2c4a872 --- /dev/null +++ b/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/toString/calendarname-never.js @@ -0,0 +1,19 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.tostring +description: Do not show calendar (even non-ISO calendars) if calendarName = "never" +features: [Temporal] +---*/ + +const dt = new Temporal.PlainDateTime(1976, 11, 18, 15, 23); + +assert.sameValue( + dt.withCalendar("gregory").toString({ calendarName: "never" }), + "1976-11-18T15:23:00", + "omits non-ISO calendar if calendarName = never" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/toString/shell.js b/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/toString/shell.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/until/shell.js b/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/until/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/until/shell.js +++ b/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/until/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-noniso.js b/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-noniso.js new file mode 100644 index 000000000000..c0f21db19acc --- /dev/null +++ b/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-noniso.js @@ -0,0 +1,41 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.withplaindate +description: PlainDate calendar is preserved with ISO PDT +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const cal = { + id: 'thisisnotiso', + era() { return "the era"; }, + eraYear() { return 1909; }, + toString() { return "this is a string"; }, + year() { return 2008; }, + month() { return 9; }, + monthCode() { return "M09"; }, + day() { return 6; } +}; +const pdt = new Temporal.PlainDateTime(1995, 12, 7, 3, 24, 30, 0, 0, 0); +assert.sameValue(pdt.calendar.toString(), "iso8601", "PlainDateTime with ISO calendar"); +const pd = new Temporal.PlainDate(2010, 11, 12, cal); +const shifted = pdt.withPlainDate(pd); + +TemporalHelpers.assertPlainDateTime( + shifted, + 2008, 9, "M09", 6, 3, 24, 30, 0, 0, 0, + "calendar is changed if receiver has ISO calendar (1)", + "the era", + 1909 +); + +assert.sameValue( + shifted.calendar, + cal, + "calendar is changed if receiver has ISO calendar (2)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-same-id.js b/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-same-id.js new file mode 100644 index 000000000000..3bccbefa9117 --- /dev/null +++ b/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-same-id.js @@ -0,0 +1,43 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.withplaindate +description: PlainDate calendar is preserved when both calendars have the same id +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const cal1 = { + toString() { return "this is a string"; }, +}; +const cal2 = { + id: 'thisisnotiso', + era() { return "the era"; }, + eraYear() { return 1909; }, + toString() { return "this is a string"; }, + year() { return 2008; }, + month() { return 9; }, + monthCode() { return "M09"; }, + day() { return 6; } +}; +const pdt = new Temporal.PlainDateTime(1995, 12, 7, 3, 24, 30, 0, 0, 0, cal1); +const pd = new Temporal.PlainDate(2010, 11, 12, cal2); +const shifted = pdt.withPlainDate(pd); + +TemporalHelpers.assertPlainDateTime( + shifted, + 2008, 9, "M09", 6, 3, 24, 30, 0, 0, 0, + "calendar is changed with same id (1)", + "the era", + 1909 +); + +assert.sameValue( + shifted.calendar, + cal2, + "calendar is changed with same id (2)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-same-object.js b/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-same-object.js new file mode 100644 index 000000000000..d05f2cf3a709 --- /dev/null +++ b/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar-same-object.js @@ -0,0 +1,45 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.withplaindate +description: PlainDate calendar is preserved when both calendars are the same object +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +let calls = 0; +const cal = { + id: 'thisisnotiso', + era() { return "the era"; }, + eraYear() { return 1909; }, + toString() { + ++calls; + return "this is a string"; + }, + year() { return 2008; }, + month() { return 9; }, + monthCode() { return "M09"; }, + day() { return 6; } +}; +const pdt = new Temporal.PlainDateTime(1995, 12, 7, 3, 24, 30, 0, 0, 0, cal); +const pd = new Temporal.PlainDate(2010, 11, 12, cal); +const shifted = pdt.withPlainDate(pd); + +TemporalHelpers.assertPlainDateTime( + shifted, + 2008, 9, "M09", 6, 3, 24, 30, 0, 0, 0, + "calendar is unchanged with same calendars (1)", + "the era", + 1909 +); + +assert.sameValue( + shifted.calendar, + cal, + "calendar is unchanged with same calendars (2)" +); +assert.sameValue(calls, 0, "should not have called cal.toString()"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar.js b/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar.js new file mode 100644 index 000000000000..0505904ffd7a --- /dev/null +++ b/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-plaindate-calendar.js @@ -0,0 +1,41 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.withplaindate +description: Original PDT calendar is preserved with ISO PlainDate +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const cal = { + id: 'thisisnotiso', + era() { return "the era"; }, + eraYear() { return 1909; }, + toString() { return "this is a string"; }, + year() { return 2008; }, + month() { return 9; }, + monthCode() { return "M09"; }, + day() { return 6; } +}; +const pdt = new Temporal.PlainDateTime(1995, 12, 7, 3, 24, 30, 0, 0, 0, cal); +const pd = new Temporal.PlainDate(2010, 11, 12); +assert.sameValue(pd.calendar.toString(), "iso8601", "PlainDate with ISO calendar"); +const shifted = pdt.withPlainDate(pd); + +TemporalHelpers.assertPlainDateTime( + shifted, + 2008, 9, "M09", 6, 3, 24, 30, 0, 0, 0, + "calendar is unchanged if input has ISO calendar (1)", + "the era", + 1909 +); + +assert.sameValue( + shifted.calendar, + cal, + "calendar is unchanged if input has ISO calendar (2)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-string-calendar.js b/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-string-calendar.js new file mode 100644 index 000000000000..60915294fdce --- /dev/null +++ b/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-string-calendar.js @@ -0,0 +1,28 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.withplaindate +description: non-ISO calendars are handled correctly +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const isopdt = new Temporal.PlainDateTime(1995, 12, 7, 3, 24, 30, 123, 456, 789); +const gregorypdt = new Temporal.PlainDateTime(1995, 12, 7, 3, 24, 30, 123, 456, 789, "gregory"); + +const result1 = isopdt.withPlainDate("2020-11-13[u-ca=gregory]"); +TemporalHelpers.assertPlainDateTime(result1, 2020, 11, "M11", 13, 3, 24, 30, 123, 456, 789, + "result1", "ce", 2020); +assert.sameValue(result1.calendar.toString(), "gregory", "non-ISO calendar in argument overrides ISO calendar in receiver"); + +const result2 = gregorypdt.withPlainDate("2020-11-13[u-ca=iso8601]"); +TemporalHelpers.assertPlainDateTime(result2, 2020, 11, "M11", 13, 3, 24, 30, 123, 456, 789, + "result2", "ce", 2020); +assert.sameValue(result2.calendar.toString(), "gregory", "non-ISO calendar in receiver overrides ISO calendar in argument"); + +assert.throws(RangeError, () => gregorypdt.withPlainDate("2020-11-13[u-ca=japanese]"), + "throws if both `this` and `other` have a non-ISO calendar"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-string-iso-calendar.js b/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-string-iso-calendar.js new file mode 100644 index 000000000000..e6bc686f5f47 --- /dev/null +++ b/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/withPlainDate/argument-string-iso-calendar.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Temporal is not supported +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.withplaindate +description: Original PDT calendar is preserved with ISO string +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const cal = { + id: "thisisnotiso", + era() { return "the era"; }, + eraYear() { return 1909; }, + toString() { return "this is a string"; }, + year() { return 2008; }, + month() { return 9; }, + monthCode() { return "M09"; }, + day() { return 6; } +}; +const dt = new Temporal.PlainDateTime(1995, 12, 7, 3, 24, 30, 0, 0, 0, cal); +const shifted = dt.withPlainDate("2010-11-12"); + +TemporalHelpers.assertPlainDateTime( + shifted, + 2008, 9, "M09", 6, 3, 24, 30, 0, 0, 0, + "calendar is unchanged if input has ISO calendar (1)", + "the era", + 1909 +); + +assert.sameValue( + shifted.calendar, + cal, + "calendar is unchanged if input has ISO calendar (2)" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/withPlainDate/shell.js b/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/withPlainDate/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/withPlainDate/shell.js +++ b/js/src/tests/test262/intl402/Temporal/PlainDateTime/prototype/withPlainDate/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/PlainMonthDay/prototype/equals/shell.js b/js/src/tests/test262/intl402/Temporal/PlainMonthDay/prototype/equals/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/PlainMonthDay/prototype/equals/shell.js +++ b/js/src/tests/test262/intl402/Temporal/PlainMonthDay/prototype/equals/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/PlainMonthDay/prototype/toPlainDate/shell.js b/js/src/tests/test262/intl402/Temporal/PlainMonthDay/prototype/toPlainDate/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/PlainMonthDay/prototype/toPlainDate/shell.js +++ b/js/src/tests/test262/intl402/Temporal/PlainMonthDay/prototype/toPlainDate/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/PlainTime/prototype/toPlainDateTime/shell.js b/js/src/tests/test262/intl402/Temporal/PlainTime/prototype/toPlainDateTime/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/PlainTime/prototype/toPlainDateTime/shell.js +++ b/js/src/tests/test262/intl402/Temporal/PlainTime/prototype/toPlainDateTime/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/PlainTime/prototype/toZonedDateTime/shell.js b/js/src/tests/test262/intl402/Temporal/PlainTime/prototype/toZonedDateTime/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/PlainTime/prototype/toZonedDateTime/shell.js +++ b/js/src/tests/test262/intl402/Temporal/PlainTime/prototype/toZonedDateTime/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/PlainYearMonth/compare/shell.js b/js/src/tests/test262/intl402/Temporal/PlainYearMonth/compare/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/PlainYearMonth/compare/shell.js +++ b/js/src/tests/test262/intl402/Temporal/PlainYearMonth/compare/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/PlainYearMonth/from/shell.js b/js/src/tests/test262/intl402/Temporal/PlainYearMonth/from/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/PlainYearMonth/from/shell.js +++ b/js/src/tests/test262/intl402/Temporal/PlainYearMonth/from/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/PlainYearMonth/prototype/equals/shell.js b/js/src/tests/test262/intl402/Temporal/PlainYearMonth/prototype/equals/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/PlainYearMonth/prototype/equals/shell.js +++ b/js/src/tests/test262/intl402/Temporal/PlainYearMonth/prototype/equals/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/PlainYearMonth/prototype/since/shell.js b/js/src/tests/test262/intl402/Temporal/PlainYearMonth/prototype/since/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/PlainYearMonth/prototype/since/shell.js +++ b/js/src/tests/test262/intl402/Temporal/PlainYearMonth/prototype/since/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/PlainYearMonth/prototype/until/shell.js b/js/src/tests/test262/intl402/Temporal/PlainYearMonth/prototype/until/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/PlainYearMonth/prototype/until/shell.js +++ b/js/src/tests/test262/intl402/Temporal/PlainYearMonth/prototype/until/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/TimeZone/prototype/getInstantFor/shell.js b/js/src/tests/test262/intl402/Temporal/TimeZone/prototype/getInstantFor/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/TimeZone/prototype/getInstantFor/shell.js +++ b/js/src/tests/test262/intl402/Temporal/TimeZone/prototype/getInstantFor/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/TimeZone/prototype/getPlainDateTimeFor/shell.js b/js/src/tests/test262/intl402/Temporal/TimeZone/prototype/getPlainDateTimeFor/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/TimeZone/prototype/getPlainDateTimeFor/shell.js +++ b/js/src/tests/test262/intl402/Temporal/TimeZone/prototype/getPlainDateTimeFor/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/TimeZone/prototype/getPossibleInstantsFor/shell.js b/js/src/tests/test262/intl402/Temporal/TimeZone/prototype/getPossibleInstantsFor/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/TimeZone/prototype/getPossibleInstantsFor/shell.js +++ b/js/src/tests/test262/intl402/Temporal/TimeZone/prototype/getPossibleInstantsFor/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/ZonedDateTime/compare/shell.js b/js/src/tests/test262/intl402/Temporal/ZonedDateTime/compare/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/ZonedDateTime/compare/shell.js +++ b/js/src/tests/test262/intl402/Temporal/ZonedDateTime/compare/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/ZonedDateTime/from/shell.js b/js/src/tests/test262/intl402/Temporal/ZonedDateTime/from/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/ZonedDateTime/from/shell.js +++ b/js/src/tests/test262/intl402/Temporal/ZonedDateTime/from/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/ZonedDateTime/prototype/equals/shell.js b/js/src/tests/test262/intl402/Temporal/ZonedDateTime/prototype/equals/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/ZonedDateTime/prototype/equals/shell.js +++ b/js/src/tests/test262/intl402/Temporal/ZonedDateTime/prototype/equals/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/ZonedDateTime/prototype/era/shell.js b/js/src/tests/test262/intl402/Temporal/ZonedDateTime/prototype/era/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/ZonedDateTime/prototype/era/shell.js +++ b/js/src/tests/test262/intl402/Temporal/ZonedDateTime/prototype/era/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/ZonedDateTime/prototype/eraYear/shell.js b/js/src/tests/test262/intl402/Temporal/ZonedDateTime/prototype/eraYear/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/ZonedDateTime/prototype/eraYear/shell.js +++ b/js/src/tests/test262/intl402/Temporal/ZonedDateTime/prototype/eraYear/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/ZonedDateTime/prototype/since/shell.js b/js/src/tests/test262/intl402/Temporal/ZonedDateTime/prototype/since/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/ZonedDateTime/prototype/since/shell.js +++ b/js/src/tests/test262/intl402/Temporal/ZonedDateTime/prototype/since/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/ZonedDateTime/prototype/until/shell.js b/js/src/tests/test262/intl402/Temporal/ZonedDateTime/prototype/until/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/ZonedDateTime/prototype/until/shell.js +++ b/js/src/tests/test262/intl402/Temporal/ZonedDateTime/prototype/until/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/intl402/Temporal/ZonedDateTime/prototype/withPlainDate/shell.js b/js/src/tests/test262/intl402/Temporal/ZonedDateTime/prototype/withPlainDate/shell.js index 1d70b7579ee9..6b347c4c3a6c 100644 --- a/js/src/tests/test262/intl402/Temporal/ZonedDateTime/prototype/withPlainDate/shell.js +++ b/js/src/tests/test262/intl402/Temporal/ZonedDateTime/prototype/withPlainDate/shell.js @@ -153,20 +153,21 @@ var TemporalHelpers = { }, /* - * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]): + * assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear, referenceISODay]]): * * Shorthand for asserting that each field of a Temporal.PlainYearMonth is * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the result of yearMonth.calendar.toString().) */ - assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined) { + assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { assert(yearMonth instanceof Temporal.PlainYearMonth, `${description} instanceof`); assert.sameValue(yearMonth.era, era, `${description} era result`); assert.sameValue(yearMonth.eraYear, eraYear, `${description} eraYear result`); assert.sameValue(yearMonth.year, year, `${description} year result`); assert.sameValue(yearMonth.month, month, `${description} month result`); assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`); + assert.sameValue(yearMonth.getISOFields().isoDay, referenceISODay, `${description} referenceISODay result`); }, /* @@ -240,39 +241,6 @@ var TemporalHelpers = { }); }, - /* - * checkFractionalSecondDigitsOptionWrongType(temporalObject): - * - * Checks the string-or-number type handling of the fractionalSecondDigits - * option to the various types' toString() methods. temporalObject is an - * instance of the Temporal type under test. - */ - checkFractionalSecondDigitsOptionWrongType(temporalObject) { - // null is not a number, and converts to the string "null", which is an invalid string value - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: null }), "null"); - // Booleans are not numbers, and convert to the strings "true" or "false", which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: true }), "true"); - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: false }), "false"); - // Symbols are not numbers and cannot convert to strings - assert.throws(TypeError, () => temporalObject.toString({ fractionalSecondDigits: Symbol() }), "symbol"); - // BigInts are not numbers and convert to strings which are invalid - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: 2n }), "bigint"); - - // Objects are not numbers and prefer their toString() methods when converting to a string - assert.throws(RangeError, () => temporalObject.toString({ fractionalSecondDigits: {} }), "plain object"); - - const toStringExpected = temporalObject.toString({ fractionalSecondDigits: 'auto' }); - const expected = [ - "get fractionalSecondDigits.toString", - "call fractionalSecondDigits.toString", - ]; - const actual = []; - const observer = TemporalHelpers.toPrimitiveObserver(actual, "auto", "fractionalSecondDigits"); - const result = temporalObject.toString({ fractionalSecondDigits: observer }); - assert.sameValue(result, toStringExpected, "object with toString"); - assert.compareArray(actual, expected, "order of operations"); - }, - /* * checkPlainDateTimeConversionFastPath(func): * diff --git a/js/src/tests/test262/language/statements/for-in/S12.6.4_A7_T2.js b/js/src/tests/test262/language/statements/for-in/S12.6.4_A7_T2.js index f43fb8b1b1a6..ae7800a41479 100644 --- a/js/src/tests/test262/language/statements/for-in/S12.6.4_A7_T2.js +++ b/js/src/tests/test262/language/statements/for-in/S12.6.4_A7_T2.js @@ -21,25 +21,25 @@ __obj.ca = 3; __accum=""; for (var __key in __obj){ - + erasator_T_1000(__obj,"b"); - __accum+=(__key+__obj[__key]); + __accum+=(__key+__obj[__key]); } assert( - __accum === "aa1ca3" || __accum === "ca3aa1", - "Unexpected value: '" + __accum + "'" + __accum === "aa1ca3" || __accum === "ca3aa1", + "Unexpected value: '" + __accum + "'" ); // erasator is the hash map terminator function erasator_T_1000(hash_map, charactr){ - for (var key in hash_map){ - if (key.indexOf(charactr)===0) { - delete hash_map[key]; - }; - } + for (var key in hash_map){ + if (key.indexOf(charactr)===0) { + delete hash_map[key]; + }; + } } reportCompare(0, 0);