Skip to content

[polyfill] Add warning for bad Map/Set polyfills #33575

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion packages/react/src/BadMapPolyfill.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ if (__DEV__) {
new Set([frozenObject]);
/* eslint-enable no-new */
} catch (e) {
// TODO: Consider warning about bad polyfills
// Warn about bad polyfills that don't support frozen objects
console['warn'](
'React detected a Map/Set polyfill that cannot handle frozen objects. ' +
'This might cause issues with React\'s internals.'
);
hasBadMapPolyfill = true;
}
}
71 changes: 71 additions & 0 deletions packages/react/src/__tests__/BadMapPolyfill-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

'use strict';

describe('BadMapPolyfill', () => {
let consoleWarnSpy;

beforeEach(() => {
consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {});
});

afterEach(() => {
consoleWarnSpy.mockRestore();
});

// @gate __DEV__
it('should warn when a bad Map/Set polyfill is detected', () => {
// Mock a Map/Set that fails with frozen objects
const originalMap = global.Map;
const originalSet = global.Set;

global.Map = function BadMap() {
if (arguments.length > 0 && arguments[0]) {
const entries = arguments[0];
for (let i = 0; i < entries.length; i++) {
if (Object.isFrozen(entries[i][0])) {
throw new Error('Cannot handle frozen object');
}
}
}
};

global.Set = function BadSet() {
if (arguments.length > 0 && arguments[0]) {
const values = arguments[0];
for (let i = 0; i < values.length; i++) {
if (Object.isFrozen(values[i])) {
throw new Error('Cannot handle frozen object');
}
}
}
};

// Re-require the module to trigger the polyfill detection
jest.resetModules();
require('../BadMapPolyfill');

expect(consoleWarnSpy).toHaveBeenCalledWith(
'React detected a Map/Set polyfill that cannot handle frozen objects. ' +
'This might cause issues with React\'s internals.'
);

// Restore original Map/Set
global.Map = originalMap;
global.Set = originalSet;
});

// @gate __DEV__
it('should not warn when Map/Set polyfill works correctly', () => {
// Re-require the module to trigger the polyfill detection with good polyfill
jest.resetModules();
require('../BadMapPolyfill');

expect(consoleWarnSpy).not.toHaveBeenCalled();
});
});