From 86c8043fc95a0f1dba8a6250b384126558dfa100 Mon Sep 17 00:00:00 2001 From: Brandon Dail Date: Mon, 28 Nov 2016 10:54:57 -0600 Subject: [PATCH] Use a closure to bind argument to callback in ReactErrorUtils (#8363) * Use a closure to bind gaurded callback This way the fake event isn't being implicitly passed into the event handler * Add tests for ReactErrorUtils Add fiber test report Linting fixes --- scripts/fiber/tests-passing.txt | 7 ++ src/renderers/shared/utils/ReactErrorUtils.js | 4 +- .../utils/__tests__/ReactErrorUtils-test.js | 73 +++++++++++++++++++ 3 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 src/renderers/shared/utils/__tests__/ReactErrorUtils-test.js diff --git a/scripts/fiber/tests-passing.txt b/scripts/fiber/tests-passing.txt index 3ab6b1c7337ea..a89631324dbb6 100644 --- a/scripts/fiber/tests-passing.txt +++ b/scripts/fiber/tests-passing.txt @@ -1482,6 +1482,13 @@ src/renderers/shared/stack/reconciler/__tests__/refs-test.js * ref called correctly for stateless component when __DEV__ = true * coerces numbers to strings +src/renderers/shared/utils/__tests__/ReactErrorUtils-test.js +* should call the callback with only the passed argument +* should catch errors +* should rethrow caught errors +* should call the callback with only the passed argument +* should use invokeGuardedCallbackWithCatch in production + src/renderers/shared/utils/__tests__/accumulateInto-test.js * throws if the second item is null * returns the second item if first is null diff --git a/src/renderers/shared/utils/ReactErrorUtils.js b/src/renderers/shared/utils/ReactErrorUtils.js index adbf6a8726d48..6e48a49a4fa54 100644 --- a/src/renderers/shared/utils/ReactErrorUtils.js +++ b/src/renderers/shared/utils/ReactErrorUtils.js @@ -72,7 +72,9 @@ if (__DEV__) { func: (a: A) => void, a: A, ): void { - var boundFunc = func.bind(null, a); + var boundFunc = function() { + func(a); + }; var evtType = `react-${name}`; fakeNode.addEventListener(evtType, boundFunc, false); var evt = document.createEvent('Event'); diff --git a/src/renderers/shared/utils/__tests__/ReactErrorUtils-test.js b/src/renderers/shared/utils/__tests__/ReactErrorUtils-test.js new file mode 100644 index 0000000000000..b152a674d7002 --- /dev/null +++ b/src/renderers/shared/utils/__tests__/ReactErrorUtils-test.js @@ -0,0 +1,73 @@ +/** + * Copyright 2014-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @emails react-core + */ + +'use strict'; + +var ReactErrorUtils; + +describe('ReactErrorUtils', () => { + + beforeEach(() => { + ReactErrorUtils = require('ReactErrorUtils'); + }); + + describe('invokeGuardedCallbackWithCatch', () => { + it('should call the callback with only the passed argument', () => { + var callback = jest.fn(); + ReactErrorUtils.invokeGuardedCallbackWithCatch('foo', callback, 'arg'); + expect(callback).toBeCalledWith('arg'); + }); + + it('should catch errors', () => { + var callback = function() { + throw new Error('foo'); + }; + expect( + () => ReactErrorUtils.invokeGuardedCallbackWithCatch('foo', callback) + ).not.toThrow(); + }); + }); + + describe('rethrowCaughtError', () => { + it('should rethrow caught errors', () => { + var err = new Error('foo'); + var callback = function() { + throw err; + }; + ReactErrorUtils.invokeGuardedCallbackWithCatch('foo', callback); + expect(() => ReactErrorUtils.rethrowCaughtError()).toThrow(err); + }); + }); + + describe('invokeGuardedCallback', () => { + it('should call the callback with only the passed argument', () => { + var callback = jest.fn(); + ReactErrorUtils.invokeGuardedCallback('foo', callback, 'arg'); + expect(callback).toBeCalledWith('arg'); + }); + + it('should use invokeGuardedCallbackWithCatch in production', () => { + expect(ReactErrorUtils.invokeGuardedCallback).not.toEqual( + ReactErrorUtils.invokeGuardedCallbackWithCatch + ); + __DEV__ = false; + var oldProcess = process; + global.process = {env: {NODE_ENV: 'production'}}; + jest.resetModuleRegistry(); + ReactErrorUtils = require('ReactErrorUtils'); + expect(ReactErrorUtils.invokeGuardedCallback).toEqual( + ReactErrorUtils.invokeGuardedCallbackWithCatch + ); + __DEV__ = true; + global.process = oldProcess; + }); + }); +});