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.
Sebastian Markbage committed
Dec 2, 2016 at 19:33 UTC
910044a41dbbf69aebc67598e0f052e13e7a767f
3 files changed
+55
-2
scripts/fiber/tests-failing.txt
+4
@@ -27,6 +27,10 @@ src/renderers/art/__tests__/ReactART-test.js
27
src/renderers/dom/__tests__/ReactDOMProduction-test.js
28
* should throw with an error code in production
29
30
+src/renderers/dom/shared/__tests__/ReactBrowserEventEmitter-test.js
31
+* should bubble to the right handler after an update
32
+* should invoke handlers that were removed while bubbling
33
+
34
src/renderers/dom/shared/__tests__/ReactDOM-test.js
35
* throws in render() if the mount callback is not a function
36
* throws in render() if the update callback is not a function
scripts/fiber/tests-passing.txt
-1
@@ -561,7 +561,6 @@ src/renderers/dom/shared/__tests__/ReactBrowserEventEmitter-test.js
561
* should support stopPropagation()
562
* should stop after first dispatch if stopPropagation
563
* should not stopPropagation if false is returned
564
-* should invoke handlers that were removed while bubbling
564
* should not invoke newly inserted handlers while bubbling
565
* should have mouse enter simulated by test utils
566
* should infer onTouchTap from a touchStart/End
src/renderers/dom/shared/__tests__/ReactBrowserEventEmitter-test.js
+51
-1
@@ -75,11 +75,21 @@ describe('ReactBrowserEventEmitter', () => {
75
var PARENT_PROPS = {};
76
var CHILD_PROPS = {};
77
78
+ function Child(props) {
79
+ return <div ref={(c) => CHILD = c} {...props} />;
80
+ }
81
+
82
+ class ChildWrapper extends React.PureComponent {
83
+ render() {
84
+ return <Child {...this.props} />;
85
+ }
86
+ }
87
+
88
function renderTree() {
89
ReactDOM.render(
90
<div ref={(c) => GRANDPARENT = c} {...GRANDPARENT_PROPS}>
91
<div ref={(c) => PARENT = c} {...PARENT_PROPS}>
82
- <div ref={(c) => CHILD = c} {...CHILD_PROPS} />
92
+ <ChildWrapper {...CHILD_PROPS} />
93
</div>
94
</div>,
95
container
@@ -193,6 +203,46 @@ describe('ReactBrowserEventEmitter', () => {
203
expect(idCallOrder[2]).toBe(GRANDPARENT);
204
});
205
206
+ it('should bubble to the right handler after an update', () => {
207
+ putListener(
208
+ GRANDPARENT,
209
+ ON_CLICK_KEY,
210
+ recordID.bind(null, 'GRANDPARENT')
211
+ );
212
+ putListener(
213
+ PARENT,
214
+ ON_CLICK_KEY,
215
+ recordID.bind(null, 'PARENT')
216
+ );
217
+ putListener(
218
+ CHILD,
219
+ ON_CLICK_KEY,
220
+ recordID.bind(null, 'CHILD')
221
+ );
222
+ ReactTestUtils.Simulate.click(CHILD);
223
+ expect(idCallOrder).toEqual([
224
+ 'CHILD',
225
+ 'PARENT',
226
+ 'GRANDPARENT',
227
+ ]);
228
+
229
+ idCallOrder = [];
230
+
231
+ // Update just the grand parent without updating the child.
232
+ putListener(
233
+ GRANDPARENT,
234
+ ON_CLICK_KEY,
235
+ recordID.bind(null, 'UPDATED_GRANDPARENT')
236
+ );
237
+
238
+ ReactTestUtils.Simulate.click(CHILD);
239
+ expect(idCallOrder).toEqual([
240
+ 'CHILD',
241
+ 'PARENT',
242
+ 'UPDATED_GRANDPARENT',
243
+ ]);
244
+ });
245
+
246
it('should continue bubbling if an error is thrown', () => {
247
putListener(
248
CHILD,