diff --git a/test/built-ins/Array/prototype/with/index-throw-completion.js b/test/built-ins/Array/prototype/with/index-throw-completion.js new file mode 100644 index 00000000000..a3965f7e21e --- /dev/null +++ b/test/built-ins/Array/prototype/with/index-throw-completion.js @@ -0,0 +1,27 @@ +// Copyright (C) 2025 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.with +description: > + Index coercion returns a throw completion. +info: | + Array.prototype.with ( index, value ) + + ... + 4. Let relativeIndex be ? ToIntegerOrInfinity(index). + ... +features: [change-array-by-copy] +---*/ + +function MyError() {} + +var index = { + valueOf() { + throw new MyError(); + } +}; + +assert.throws(MyError, function() { + [].with(index, null); +}); diff --git a/test/built-ins/Array/prototype/with/negative-fractional-index-truncated-to-zero.js b/test/built-ins/Array/prototype/with/negative-fractional-index-truncated-to-zero.js new file mode 100644 index 00000000000..ab50faeb4f2 --- /dev/null +++ b/test/built-ins/Array/prototype/with/negative-fractional-index-truncated-to-zero.js @@ -0,0 +1,26 @@ +// Copyright (C) 2025 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.with +description: > + Negative fractional index which is truncated to zero. +info: | + Array.prototype.with ( index, value ) + + ... + 3. Let relativeIndex be ? ToIntegerOrInfinity(index). + ... + + ToIntegerOrInfinity ( argument ) + + 1. Let number be ? ToNumber(argument). + 2. If number is one of NaN, +0𝔽, or -0𝔽, return 0. + 3. If number is +∞𝔽, return +∞. + 4. If number is -∞𝔽, return -∞. + 5. Return truncate(ℝ(number)). +features: [change-array-by-copy] +---*/ + +var result = [0].with(-0.5, 123); +assert.sameValue(result[0], 123); diff --git a/test/built-ins/TypedArray/prototype/lastIndexOf/negative-index-and-resize-to-smaller.js b/test/built-ins/TypedArray/prototype/lastIndexOf/negative-index-and-resize-to-smaller.js new file mode 100644 index 00000000000..752d07d75db --- /dev/null +++ b/test/built-ins/TypedArray/prototype/lastIndexOf/negative-index-and-resize-to-smaller.js @@ -0,0 +1,57 @@ +// Copyright (C) 2025 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.lastIndexOf +description: > + Negative index is relative to the original typed array length. +info: | + %TypedArray%.prototype.lastIndexOf ( searchElement [ , fromIndex ] ) + + ... + 5. If fromIndex is present, let n be ? ToIntegerOrInfinity(fromIndex); else let n be len - 1. + 6. If n = -∞, return -1𝔽. + 7. If n ≥ 0, then + a. Let k be min(n, len - 1). + 8. Else, + a. Let k be len + n. + ... +features: [TypedArray, resizable-arraybuffer] +includes: [testTypedArray.js] +---*/ + +testWithTypedArrayConstructors(function(TA) { + var byteLength = 4 * TA.BYTES_PER_ELEMENT; + var rab = new ArrayBuffer(0, {maxByteLength: byteLength}); + var ta = new TA(rab); + + var indices = [ + [-1, 2], + [-2, 2], + [-3, 1], + [-4, 0], + [-5, -1], + ]; + + for (var i = 0; i < indices.length; ++i) { + var index = indices[i][0]; + var expected = indices[i][1]; + var searchElement = 123; + + rab.resize(byteLength); + ta.fill(searchElement); + + var indexValue = { + valueOf() { + rab.resize(3 * TA.BYTES_PER_ELEMENT); + return index; + } + }; + + assert.sameValue( + ta.lastIndexOf(searchElement, indexValue), + expected, + "For index " + index + ); + } +}); diff --git a/test/built-ins/TypedArray/prototype/slice/speciesctor-return-same-buffer-with-offset.js b/test/built-ins/TypedArray/prototype/slice/speciesctor-return-same-buffer-with-offset.js new file mode 100644 index 00000000000..6a91d5c4e32 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/slice/speciesctor-return-same-buffer-with-offset.js @@ -0,0 +1,45 @@ +// Copyright (C) 2025 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.slice +description: > + When species constructs a typed array using the same buffer but with a + different byte offset, slice output reflects element-by-element copying into + that buffer. +info: | + %TypedArray%.prototype.slice ( start, end ) + + ... + 14. If countBytes > 0, then + g. If srcType is targetType, then + ix. Repeat, while targetByteIndex < endByteIndex, + 1. Let value be GetValueFromBuffer(srcBuffer, srcByteIndex, uint8, true, unordered). + 2. Perform SetValueInBuffer(targetBuffer, targetByteIndex, uint8, value, true, unordered). + ... +features: [TypedArray] +includes: [testTypedArray.js, compareArray.js] +---*/ + +testWithTypedArrayConstructors(function(TA) { + var ta = new TA([ + 10, + 20, + 30, + 40, + 50, + 60, + ]); + + ta.constructor = { + [Symbol.species]: function() { + return new TA(ta.buffer, 2 * TA.BYTES_PER_ELEMENT); + } + }; + + var result = ta.slice(1, 4); + + assert.compareArray(result, [ + 20, 20, 20, 60, + ]); +}); diff --git a/test/built-ins/TypedArray/prototype/subarray/byteoffset-with-detached-buffer.js b/test/built-ins/TypedArray/prototype/subarray/byteoffset-with-detached-buffer.js new file mode 100644 index 00000000000..ebe1b877c9f --- /dev/null +++ b/test/built-ins/TypedArray/prototype/subarray/byteoffset-with-detached-buffer.js @@ -0,0 +1,45 @@ +// Copyright (C) 2025 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.subarray +description: > + Species constructor is called with the correct byte-offset value +info: | + %TypedArray%.prototype.subarray ( start, end ) + + ... + 13. Let srcByteOffset be O.[[ByteOffset]]. + 14. Let beginByteOffset be srcByteOffset + (startIndex × elementSize). + ... + 16. Else, + ... + f. Let argumentsList be « buffer, 𝔽(beginByteOffset), 𝔽(newLength) ». + 17. Return ? TypedArraySpeciesCreate(O, argumentsList). +features: [TypedArray] +includes: [testTypedArray.js, detachArrayBuffer.js] +---*/ + +testWithTypedArrayConstructors(function(TA) { + var ab = new ArrayBuffer(2 * TA.BYTES_PER_ELEMENT); + var ta = new TA(ab, TA.BYTES_PER_ELEMENT, 1); + var result = new TA(0); + + ta.constructor = { + [Symbol.species]: function(buffer, byteOffset, length) { + assert.sameValue(buffer, ab); + assert.sameValue(byteOffset, 2 * TA.BYTES_PER_ELEMENT); + assert.sameValue(length, 0); + return result; + } + }; + + var end = { + valueOf() { + $DETACHBUFFER(ab); + return 0; + } + }; + + assert.sameValue(ta.subarray(1, end), result); +}); diff --git a/test/built-ins/TypedArray/prototype/with/index-throw-completion.js b/test/built-ins/TypedArray/prototype/with/index-throw-completion.js new file mode 100644 index 00000000000..c5dc254a384 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/with/index-throw-completion.js @@ -0,0 +1,38 @@ +// Copyright (C) 2025 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.with +description: > + Index coercion returns a throw completion. +info: | + %TypedArray%.prototype.with ( index, value ) + + ... + 4. Let relativeIndex be ? ToIntegerOrInfinity(index). + ... +features: [TypedArray, change-array-by-copy] +includes: [testTypedArray.js] +---*/ + +function MyError() {} + +testWithTypedArrayConstructors(function(TA) { + var ta = new TA(1); + + var index = { + valueOf() { + throw new MyError(); + } + }; + + var value = { + valueOf() { + throw new Test262Error("Unexpected value coercion"); + } + }; + + assert.throws(MyError, function() { + ta.with(index, value); + }); +}); diff --git a/test/built-ins/TypedArray/prototype/with/negative-fractional-index-truncated-to-zero.js b/test/built-ins/TypedArray/prototype/with/negative-fractional-index-truncated-to-zero.js new file mode 100644 index 00000000000..15428c5fa8d --- /dev/null +++ b/test/built-ins/TypedArray/prototype/with/negative-fractional-index-truncated-to-zero.js @@ -0,0 +1,30 @@ +// Copyright (C) 2025 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.with +description: > + Negative fractional index which is truncated to zero. +info: | + %TypedArray%.prototype.with ( index, value ) + + ... + 4. Let relativeIndex be ? ToIntegerOrInfinity(index). + ... + + ToIntegerOrInfinity ( argument ) + + 1. Let number be ? ToNumber(argument). + 2. If number is one of NaN, +0𝔽, or -0𝔽, return 0. + 3. If number is +∞𝔽, return +∞. + 4. If number is -∞𝔽, return -∞. + 5. Return truncate(ℝ(number)). +features: [TypedArray, change-array-by-copy] +includes: [testTypedArray.js] +---*/ + +testWithTypedArrayConstructors(function(TA) { + var ta = new TA(1); + var result = ta.with(-0.5, 123); + assert.sameValue(result[0], 123); +}); diff --git a/test/built-ins/TypedArray/prototype/with/negative-index-resize-to-in-bounds.js b/test/built-ins/TypedArray/prototype/with/negative-index-resize-to-in-bounds.js new file mode 100644 index 00000000000..2f19a36f234 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/with/negative-index-resize-to-in-bounds.js @@ -0,0 +1,37 @@ +// Copyright (C) 2025 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.with +description: > + Negative index is relative to the original typed array length. +info: | + %TypedArray%.prototype.with ( index, value ) + + ... + 4. Let relativeIndex be ? ToIntegerOrInfinity(index). + 5. If relativeIndex ≥ 0, let actualIndex be relativeIndex. + 6. Else, let actualIndex be len + relativeIndex. + ... + 9. If IsValidIntegerIndex(O, 𝔽(actualIndex)) is false, throw a RangeError exception. + ... +features: [TypedArray, change-array-by-copy, resizable-arraybuffer] +includes: [testTypedArray.js] +---*/ + +testWithTypedArrayConstructors(function(TA) { + var byteLength = 4 * TA.BYTES_PER_ELEMENT; + var rab = new ArrayBuffer(0, {maxByteLength: byteLength}); + var ta = new TA(rab); + + var value = { + valueOf() { + rab.resize(byteLength); + return 123; + } + }; + + assert.throws(RangeError, function() { + ta.with(-1, value); + }); +}); diff --git a/test/built-ins/TypedArray/prototype/with/negative-index-resize-to-out-of-bounds.js b/test/built-ins/TypedArray/prototype/with/negative-index-resize-to-out-of-bounds.js new file mode 100644 index 00000000000..06a990d1cff --- /dev/null +++ b/test/built-ins/TypedArray/prototype/with/negative-index-resize-to-out-of-bounds.js @@ -0,0 +1,37 @@ +// Copyright (C) 2025 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.with +description: > + Negative index is relative to the original typed array length. +info: | + %TypedArray%.prototype.with ( index, value ) + + ... + 4. Let relativeIndex be ? ToIntegerOrInfinity(index). + 5. If relativeIndex ≥ 0, let actualIndex be relativeIndex. + 6. Else, let actualIndex be len + relativeIndex. + ... + 9. If IsValidIntegerIndex(O, 𝔽(actualIndex)) is false, throw a RangeError exception. + ... +features: [TypedArray, change-array-by-copy, resizable-arraybuffer] +includes: [testTypedArray.js] +---*/ + +testWithTypedArrayConstructors(function(TA) { + var byteLength = 4 * TA.BYTES_PER_ELEMENT; + var rab = new ArrayBuffer(byteLength, {maxByteLength: byteLength}); + var ta = new TA(rab); + + var value = { + valueOf() { + rab.resize(TA.BYTES_PER_ELEMENT); + return 123; + } + }; + + assert.throws(RangeError, function() { + ta.with(-1, value); + }); +}); diff --git a/test/built-ins/TypedArray/prototype/with/value-throw-completion.js b/test/built-ins/TypedArray/prototype/with/value-throw-completion.js new file mode 100644 index 00000000000..760571da243 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/with/value-throw-completion.js @@ -0,0 +1,37 @@ +// Copyright (C) 2025 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.with +description: > + Value coercion returns a throw completion. +info: | + %TypedArray%.prototype.with ( index, value ) + + ... + 7. If O.[[ContentType]] is bigint, let numericValue be ? ToBigInt(value). + 8. Else, let numericValue be ? ToNumber(value). + ... +features: [TypedArray, change-array-by-copy] +includes: [testTypedArray.js] +---*/ + +function MyError() {} + +testWithTypedArrayConstructors(function(TA) { + var ta = new TA(1); + + var value = { + valueOf() { + throw new MyError(); + } + }; + + assert.throws(MyError, function() { + ta.with(100, value); + }, "Positive too large index"); + + assert.throws(MyError, function() { + ta.with(-100, value); + }, "Negative too large index"); +}); diff --git a/test/built-ins/Uint8Array/prototype/setFromHex/throws-when-string-length-is-odd.js b/test/built-ins/Uint8Array/prototype/setFromHex/throws-when-string-length-is-odd.js new file mode 100644 index 00000000000..d62f4d4073b --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/setFromHex/throws-when-string-length-is-odd.js @@ -0,0 +1,40 @@ +// Copyright (C) 2025 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-uint8array.prototype.setfromhex +description: > + Throws a SyntaxError when the string length is odd. +info: | + Uint8Array.prototype.setFromHex ( string ) + + ... + 7. Let result be FromHex(string, byteLength). + ... + 13. If result.[[Error]] is not none, then + a. Throw result.[[Error]]. + ... + + FromHex ( string [ , maxLength ] ) + + ... + 5. If length modulo 2 is not 0, then + a. Let error be a new SyntaxError exception. + b. Return the Record { [[Read]]: read, [[Bytes]]: bytes, [[Error]]: error }. + ... + +features: [TypedArray, uint8array-base64] +---*/ + +var zeroLength = new Uint8Array(0); + +assert.throws(SyntaxError, function() { + zeroLength.setFromHex("1") +}, "Uint8Array has length 0"); + + +var nonZeroLength = new Uint8Array(1); + +assert.throws(SyntaxError, function() { + nonZeroLength.setFromHex("1") +}, "Uint8Array has length >0");