From 910044a41dbbf69aebc67598e0f052e13e7a767f Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Fri, 2 Dec 2016 19:33:24 -0800 Subject: [PATCH] Add failing event handler test When we perform an update to the event handler we properly update the immediate Fiber pointer of a child to be the current. However, when we bubble events we use the return pointer which is not guaranteed to point to the current Fiber even if we start from the current. This manifests itself when we bailout in a parent. So I made the tests use a PureComponent to illustrate this scenario. There is already a failing case but I'm adding another one too. --- scripts/fiber/tests-failing.txt | 4 ++ scripts/fiber/tests-passing.txt | 1 - .../ReactBrowserEventEmitter-test.js | 52 ++++++++++++++++++- 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/scripts/fiber/tests-failing.txt b/scripts/fiber/tests-failing.txt index 16dd1717af..9b46b63ed5 100644 --- a/scripts/fiber/tests-failing.txt +++ b/scripts/fiber/tests-failing.txt @@ -27,6 +27,10 @@ src/renderers/art/__tests__/ReactART-test.js src/renderers/dom/__tests__/ReactDOMProduction-test.js * should throw with an error code in production +src/renderers/dom/shared/__tests__/ReactBrowserEventEmitter-test.js +* should bubble to the right handler after an update +* should invoke handlers that were removed while bubbling + src/renderers/dom/shared/__tests__/ReactDOM-test.js * throws in render() if the mount callback is not a function * throws in render() if the update callback is not a function diff --git a/scripts/fiber/tests-passing.txt b/scripts/fiber/tests-passing.txt index a1401beb40..7fdf742564 100644 --- a/scripts/fiber/tests-passing.txt +++ b/scripts/fiber/tests-passing.txt @@ -561,7 +561,6 @@ src/renderers/dom/shared/__tests__/ReactBrowserEventEmitter-test.js * should support stopPropagation() * should stop after first dispatch if stopPropagation * should not stopPropagation if false is returned -* should invoke handlers that were removed while bubbling * should not invoke newly inserted handlers while bubbling * should have mouse enter simulated by test utils * should infer onTouchTap from a touchStart/End diff --git a/src/renderers/dom/shared/__tests__/ReactBrowserEventEmitter-test.js b/src/renderers/dom/shared/__tests__/ReactBrowserEventEmitter-test.js index 6462df35f6..0a6244e6f3 100644 --- a/src/renderers/dom/shared/__tests__/ReactBrowserEventEmitter-test.js +++ b/src/renderers/dom/shared/__tests__/ReactBrowserEventEmitter-test.js @@ -75,11 +75,21 @@ describe('ReactBrowserEventEmitter', () => { var PARENT_PROPS = {}; var CHILD_PROPS = {}; + function Child(props) { + return
CHILD = c} {...props} />; + } + + class ChildWrapper extends React.PureComponent { + render() { + return ; + } + } + function renderTree() { ReactDOM.render(
GRANDPARENT = c} {...GRANDPARENT_PROPS}>
PARENT = c} {...PARENT_PROPS}> -
CHILD = c} {...CHILD_PROPS} /> +
, container @@ -193,6 +203,46 @@ describe('ReactBrowserEventEmitter', () => { expect(idCallOrder[2]).toBe(GRANDPARENT); }); + it('should bubble to the right handler after an update', () => { + putListener( + GRANDPARENT, + ON_CLICK_KEY, + recordID.bind(null, 'GRANDPARENT') + ); + putListener( + PARENT, + ON_CLICK_KEY, + recordID.bind(null, 'PARENT') + ); + putListener( + CHILD, + ON_CLICK_KEY, + recordID.bind(null, 'CHILD') + ); + ReactTestUtils.Simulate.click(CHILD); + expect(idCallOrder).toEqual([ + 'CHILD', + 'PARENT', + 'GRANDPARENT', + ]); + + idCallOrder = []; + + // Update just the grand parent without updating the child. + putListener( + GRANDPARENT, + ON_CLICK_KEY, + recordID.bind(null, 'UPDATED_GRANDPARENT') + ); + + ReactTestUtils.Simulate.click(CHILD); + expect(idCallOrder).toEqual([ + 'CHILD', + 'PARENT', + 'UPDATED_GRANDPARENT', + ]); + }); + it('should continue bubbling if an error is thrown', () => { putListener( CHILD,