-
Notifications
You must be signed in to change notification settings - Fork 47k
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
Rewrite ReactTreeTraversal-test.js using public APIs #11664
Rewrite ReactTreeTraversal-test.js using public APIs #11664
Conversation
This sounds right.
I'm not sure I understand the problem. The traversal tests verify that we correctly walk the tree for different "types" of walks (enter-leave is one example). It seems right to me that you would test it by listening on React
If you search for |
My thoughts were the wrong way like "to simulate a I will look into the inner workings of the When I added the |
This sounds right. In fact maybe you can move the original test for that part into |
Sounds good. It looks like |
@@ -1360,4 +1360,88 @@ describe('ResponderEventPlugin', () => { | |||
run(config, three, nativeEvent); | |||
expect(ResponderEventPlugin._getResponder()).toBe(null); | |||
}); | |||
|
|||
it('should determine the first common ancestor correctly', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we're not using Responder plugin it's worth adding a comment explaining why the test is here and how it's related to Resonder.
describe('Two phase traversal', () => { | ||
it('should not traverse when target is outside component boundary', () => { | ||
const outerNode = document.createElement('div'); | ||
document.body.appendChild(outerNode); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The node is appended here to the document. We should remove it to clean up after the test. I usually put the rest of the test in try/finally, and remove it in the finally block.
var enterNode = document.createElement('div'); | ||
|
||
document.body.appendChild(leaveNode); | ||
document.body.appendChild(enterNode); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In fact it may be easier to always add these nodes in beforeEach, and then always remove them in afterEach. Some tests will use them, some won't.
var leaveNode = document.createElement('div'); | ||
var enterNode = document.getElementById('P_P1_C1__DIV'); | ||
|
||
document.body.appendChild(leaveNode); // From the window or outside of the React sandbox. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we change nodes to always be added, tests like this will have to remove one instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you elaborate? I don't follow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Never mind, I misread the tests.
Updated according to comments :) |
<div | ||
id={id + '__DIV'} | ||
onClickCapture={e => | ||
eventHandler(e.currentTarget.id, 'captured', e.type, ARG) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic behind choosing to put either ARG
or ARG2
here is not clear to me.
In the original tests, it was specific to a test. We're traversing enter/leave, and calling "from" path with ARG
and "to" path with ARG2
.
Here, we instead encoded ARG
and ARG2
right into components. I don't think this is right. This seems to couple them with specific test cases below. So it might be hard or impossible to add other completely valid tests which test the opposite enter/leave paths. This didn't use to be a problem.
I'm not sure what the solution is; just pointing out an issue I see.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I'm not entirely happy with that either. Will think about a more elegant solution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we're good to just remove the ARG
s since we're now tracking the event type which we haven't done before. If I get it righttraverseEnterLeave(from, to, fn, argFrom, argTo)
will be called with argFrom
and argTo
set to the events that are dispatched on the target anyway so I feel like extracting the target id and event type will be strict enough.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes this sounds right
these were used for testing the internal API to simulate synthetic events passed to traverseEnterLeave. since we're now dealing with actual synthetic events we can remove them.
@gaearon the App Veyor test failures seem unrelated. |
Yeah, I didn't realize it would start appearing on PRs.. |
This is good. Thank you! |
No worries. Was great again! |
* rewrite two phase traversal tests with public APIs * rewrite enter/leave tests * lift render into beforeEach, organise variables * move getLowestCommonAncestor test * remove internal tree traversal test * fix linter errors * move creation of outer nodes into {before,after}Each * explain why getLowestCommonAncestor test was moved * remove unnessecary ARG and ARG2 token these were used for testing the internal API to simulate synthetic events passed to traverseEnterLeave. since we're now dealing with actual synthetic events we can remove them. * run prettier
Hej!
This is a super interesting test to look at since the tests cover 3 different areas when you try to rewrite them using only public APIs. So far I have converted 1/3 of the tests to use public APIs only. The rest I'd like to discuss.
traverseTwoPhase
These were fairly straightforward to rewrite. I could even used the same
expectedCalls
arrays for the expectations on the mock.The only thing that could be a bit nicer is the calls to
eventHandler
. I would like to factor out passing the arguments but #11663 prevents me from passing the event phase dynamically.traverseEnterLeave
In order to test them in the same fashion as most other public API tests I would have to dispatch
onmouseenter
andonmouseleave
events against the DOM nodes and see which event handlers React calls. Unfortunately dispatching these event types doesn't have an effect and looking atEnterLeaveEventPlugin.js
it seems like enter and leave events are implemented usingonmouseover
andonmouseout
.The tests seem to verify the capturing and bubbling behaviour which are inherently different between
onmouseenter
andonmouseover
as well asonmouseleave
andonmouseout
. I would be really thank for some ideas on how we could solve this.getFirstCommonAncestor
akagetLowestCommonAncestor
This function is only used by the
ResponderEventPlugin
which is in turn only used by React Native. This doesn't mean we can't test it only with public APIs but we might struggle with that in our JSDOM environment. Again would be great to discuss alternatives :)