From 09c96b280c385b67d811367325fd8f36417c649a Mon Sep 17 00:00:00 2001 From: Denis Pushkarev Date: Fri, 28 Jul 2023 00:48:21 +0700 Subject: [PATCH] detect and fix early `Set` methods implementations --- CHANGELOG.md | 1 + packages/core-js-compat/src/data.mjs | 14 ----- .../internals/set-method-accept-set-like.js | 17 +++-- tests/compat/tests.js | 62 +++++++++++++------ 4 files changed, 55 insertions(+), 39 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 50c9effe33bb..d5f3d5edd46d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,7 @@ - `DataView.prototype.setUint8Clamped` - Used strict mode in some missed cases, [#1269](https://github.com/zloirock/core-js/issues/1269) - Fixed [a Chromium 117 bug](https://bugs.chromium.org/p/v8/issues/detail?id=14222) in `value` argument of `URLSearchParams.prototype.{ has, delete }` +- Fixed early WebKit `Set` methods implementation by the actual spec - Fixed incorrect `Symbol.{ dispose, asyncDispose }` descriptors from [NodeJS 20.4](https://github.com/nodejs/node/issues/48699) / transpilers helpers / userland code - Fixed forced polyfilling of some iterator helpers that should return wrapped iterator in the pure version - Fixed and exposed [`AsyncIteratorPrototype` `core-js/configurator` option](https://github.com/zloirock/core-js#asynciterator-helpers), [#1268](https://github.com/zloirock/core-js/issues/1268) diff --git a/packages/core-js-compat/src/data.mjs b/packages/core-js-compat/src/data.mjs index c4a9ac797213..b5ce677b2e66 100644 --- a/packages/core-js-compat/src/data.mjs +++ b/packages/core-js-compat/src/data.mjs @@ -2200,8 +2200,6 @@ export const data = { 'esnext.set.delete-all': { }, 'esnext.set.difference.v2': { - bun: '0.6.0', - safari: '17.0', }, // TODO: Remove from `core-js@4` 'esnext.set.difference': { @@ -2215,29 +2213,21 @@ export const data = { 'esnext.set.from': { }, 'esnext.set.intersection.v2': { - bun: '0.5.7', - safari: '17.0', }, // TODO: Remove from `core-js@4` 'esnext.set.intersection': { }, 'esnext.set.is-disjoint-from.v2': { - bun: '0.5.7', - safari: '17.0', }, // TODO: Remove from `core-js@4` 'esnext.set.is-disjoint-from': { }, 'esnext.set.is-subset-of.v2': { - bun: '0.5.7', - safari: '17.0', }, // TODO: Remove from `core-js@4` 'esnext.set.is-subset-of': { }, 'esnext.set.is-superset-of.v2': { - bun: '0.5.7', - safari: '17.0', }, // TODO: Remove from `core-js@4` 'esnext.set.is-superset-of': { @@ -2253,15 +2243,11 @@ export const data = { 'esnext.set.some': { }, 'esnext.set.symmetric-difference.v2': { - bun: '0.5.7', - safari: '17.0', }, // TODO: Remove from `core-js@4` 'esnext.set.symmetric-difference': { }, 'esnext.set.union.v2': { - bun: '0.5.7', - safari: '17.0', }, // TODO: Remove from `core-js@4` 'esnext.set.union': { diff --git a/packages/core-js/internals/set-method-accept-set-like.js b/packages/core-js/internals/set-method-accept-set-like.js index cecb0b64c013..7cf0c23ba53d 100644 --- a/packages/core-js/internals/set-method-accept-set-like.js +++ b/packages/core-js/internals/set-method-accept-set-like.js @@ -1,9 +1,9 @@ 'use strict'; var getBuiltIn = require('../internals/get-built-in'); -var createEmptySetLike = function () { +var createSetLike = function (size) { return { - size: 0, + size: size, has: function () { return false; }, @@ -18,10 +18,17 @@ var createEmptySetLike = function () { }; module.exports = function (name) { + var Set = getBuiltIn('Set'); try { - var Set = getBuiltIn('Set'); - new Set()[name](createEmptySetLike()); - return true; + new Set()[name](createSetLike(0)); + try { + // late spec change, early Safari implementation does not pass it + // https://github.com/tc39/proposal-set-methods/pull/88 + new Set()[name](createSetLike(-1)); + return false; + } catch (error2) { + return true; + } } catch (error) { return false; } diff --git a/tests/compat/tests.js b/tests/compat/tests.js index 52b6644da080..9caa65d37db4 100644 --- a/tests/compat/tests.js +++ b/tests/compat/tests.js @@ -223,6 +223,40 @@ function createStringTrimMethodTest(METHOD_NAME) { }; } +function createSetLike(size) { + return { + size: size, + has: function () { + return false; + }, + keys: function () { + return { + next: function () { + return { done: true }; + } + }; + } + }; +} + +function createSetMethodTest(METHOD_NAME) { + return function () { + try { + new Set()[METHOD_NAME](createSetLike(0)); + try { + // late spec change, early Safari implementation does not pass it + // https://github.com/tc39/proposal-set-methods/pull/88 + new Set()[METHOD_NAME](createSetLike(-1)); + return false; + } catch (error2) { + return true; + } + } catch (error) { + return false; + } + }; +} + function NATIVE_RAW_JSON() { var unsafeInt = '9007199254740993'; var raw = JSON.rawJSON(unsafeInt); @@ -1731,9 +1765,7 @@ GLOBAL.tests = { 'esnext.set.delete-all': function () { return Set.prototype.deleteAll; }, - 'esnext.set.difference.v2': function () { - return Set.prototype.difference; - }, + 'esnext.set.difference.v2': createSetMethodTest('difference'), 'esnext.set.every': function () { return Set.prototype.every; }, @@ -1746,18 +1778,12 @@ GLOBAL.tests = { 'esnext.set.from': function () { return Set.from; }, - 'esnext.set.intersection.v2': function () { + 'esnext.set.intersection.v2': [createSetMethodTest('intersection'), function () { return Array.from(new Set([1, 2, 3]).intersection(new Set([3, 2]))) == '3,2'; - }, - 'esnext.set.is-disjoint-from.v2': function () { - return Set.prototype.isDisjointFrom; - }, - 'esnext.set.is-subset-of.v2': function () { - return Set.prototype.isSubsetOf; - }, - 'esnext.set.is-superset-of.v2': function () { - return Set.prototype.isSupersetOf; - }, + }], + 'esnext.set.is-disjoint-from.v2': createSetMethodTest('isDisjointFrom'), + 'esnext.set.is-subset-of.v2': createSetMethodTest('isSubsetOf'), + 'esnext.set.is-superset-of.v2': createSetMethodTest('isSupersetOf'), 'esnext.set.join': function () { return Set.prototype.join; }, @@ -1773,12 +1799,8 @@ GLOBAL.tests = { 'esnext.set.some': function () { return Set.prototype.some; }, - 'esnext.set.symmetric-difference.v2': function () { - return Set.prototype.symmetricDifference; - }, - 'esnext.set.union.v2': function () { - return Set.prototype.union; - }, + 'esnext.set.symmetric-difference.v2': createSetMethodTest('symmetricDifference'), + 'esnext.set.union.v2': createSetMethodTest('union'), 'esnext.string.code-points': function () { return String.prototype.codePoints; },