From cdbd392a0c54e868ca9019fb74daf5dbab2b51d8 Mon Sep 17 00:00:00 2001 From: Denis Pushkarev Date: Sat, 25 Jun 2022 22:13:34 +0700 Subject: [PATCH] detect early implementations of `%TypedArray%.prototype.toSpliced` --- .../modules/esnext.typed-array.to-spliced.js | 18 +++++++++++++++++- tests/compat/tests.js | 11 ++++++++++- tests/tests/esnext.typed-array.to-spliced.js | 11 ++++++++++- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/packages/core-js/modules/esnext.typed-array.to-spliced.js b/packages/core-js/modules/esnext.typed-array.to-spliced.js index f6779975a0a5..0d23729c703f 100644 --- a/packages/core-js/modules/esnext.typed-array.to-spliced.js +++ b/packages/core-js/modules/esnext.typed-array.to-spliced.js @@ -6,6 +6,7 @@ var toAbsoluteIndex = require('../internals/to-absolute-index'); var toBigInt = require('../internals/to-big-int'); var toIntegerOrInfinity = require('../internals/to-integer-or-infinity'); var uncurryThis = require('../internals/function-uncurry-this'); +var fails = require('../internals/fails'); var aTypedArray = ArrayBufferViewCore.aTypedArray; var getTypedArrayConstructor = ArrayBufferViewCore.getTypedArrayConstructor; @@ -14,6 +15,21 @@ var push = uncurryThis([].push); var max = Math.max; var min = Math.min; +// some early implementations, like WebKit, does not follow the final semantic +var PROPER_ORDER = !fails(function () { + // eslint-disable-next-line es-x/no-typed-arrays -- required for testing + var array = new Int8Array([1]); + + var spliced = array.toSpliced(1, 0, { + valueOf: function () { + array[0] = 2; + return 3; + } + }); + + return spliced[0] !== 2 || spliced[1] !== 3; +}); + // `%TypedArray%.prototype.toSpliced` method // https://tc39.es/proposal-change-array-by-copy/#sec-%typedarray%.prototype.toSpliced exportTypedArrayMethod('toSpliced', function toSpliced(start, deleteCount /* , ...items */) { @@ -48,4 +64,4 @@ exportTypedArrayMethod('toSpliced', function toSpliced(start, deleteCount /* , . for (; k < newLen; k++) A[k] = O[k + actualDeleteCount - insertCount]; return A; -}); +}, !PROPER_ORDER); diff --git a/tests/compat/tests.js b/tests/compat/tests.js index 64b0822b3f77..d05c75015e49 100644 --- a/tests/compat/tests.js +++ b/tests/compat/tests.js @@ -1714,7 +1714,16 @@ GLOBAL.tests = { return Int8Array.prototype.toSorted; }, 'esnext.typed-array.to-spliced': function () { - return Int8Array.prototype.toSpliced; + var array = new Int8Array([1]); + + var spliced = array.toSpliced(1, 0, { + valueOf: function () { + array[0] = 2; + return 3; + } + }); + + return spliced[0] === 2 && spliced[1] === 3; }, 'esnext.typed-array.unique-by': function () { return Int8Array.prototype.uniqueBy; diff --git a/tests/tests/esnext.typed-array.to-spliced.js b/tests/tests/esnext.typed-array.to-spliced.js index c24e7b491047..16115be9bd13 100644 --- a/tests/tests/esnext.typed-array.to-spliced.js +++ b/tests/tests/esnext.typed-array.to-spliced.js @@ -11,7 +11,7 @@ if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.toSpliced', assert => { assert.name(toSpliced, 'toSpliced', `${ name }::toSpliced name is 'toSpliced'`); assert.looksNative(toSpliced, `${ name }::toSpliced looks native`); - const array = new TypedArray([1, 2, 3, 4, 5]); + let array = new TypedArray([1, 2, 3, 4, 5]); assert.notSame(array.toSpliced(2), array, 'immutable'); assert.deepEqual(new TypedArray([1, 2, 3, 4, 5]).toSpliced(2), new TypedArray([1, 2])); @@ -20,6 +20,15 @@ if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.toSpliced', assert => { assert.deepEqual(new TypedArray([1, 2, 3, 4, 5]).toSpliced(2, -2), new TypedArray([1, 2, 3, 4, 5])); assert.deepEqual(new TypedArray([1, 2, 3, 4, 5]).toSpliced(2, 2, 6, 7), new TypedArray([1, 2, 6, 7, 5])); + array = new TypedArray([1]); + + assert.deepEqual(array.toSpliced(1, 0, { + valueOf() { + array[0] = 2; + return 3; + }, + }), new TypedArray([2, 3]), 'operations order'); + assert.throws(() => toSpliced.call(null), TypeError, "isn't generic #1"); assert.throws(() => toSpliced.call(undefined), TypeError, "isn't generic #2"); assert.throws(() => toSpliced.call([1, 2]), TypeError, "isn't generic #3");