Skip to content
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

Use only public API for EnterLeaveEventPlugin Tests #11316

Merged
merged 8 commits into from
Nov 3, 2017

Conversation

accordeiro
Copy link
Contributor

This PR is related to issue #11299 – Express more tests via public API

I've managed to rewrite the EnterLeavePlugin tests using public API, but I'm not sure if I'm on the right path. What I did was basically analyze what was being done inside EnterLeaveEventPlugin.js and move the needed parts to the test (which luckily led to a much simpler code).

Does this make sense? Happy to make any necessary changes or follow a different path if need be.

Thanks for the opportunity of contributing! :)

Copy link
Collaborator

@gaearon gaearon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This tests that jsdom works, but doesn't actually test our code. If you make a mistake in EnterLeavePlugin, this test will still pass because it repeats rather than exercises that code path.

You would need to figure out how to make that code path actually happen. For example you could trigger a native event with ReactTestUtils.SimulateNative.mouseOver() and then make an assertion on the e event object in a <div onMouseOver={...} /> handler.

You can see another test here that is doing something similar. Hope this helps.

@accordeiro
Copy link
Contributor Author

Hi, @gaearon – thanks for the thorough feedback! :)

I've just pushed a new commit, trying to follow the path you've suggested. I've noticed two things:

  1. When using ReactTestUtils.SimulateNative, the event's relatedTarget was set to undefined, so I had to set the relatedTarget manually, which made the last assertion a bit redundant. Am I missing something, or do you think this test makes sense anyway?

  2. It seems that triggering the event via ReactTestUtils.SimulateNative isn't actually exercising the EnterLeavePlugin.js codepath (I've put some logs on it to validate this assumption), while the second test on this file – which uses ReactTestUtils.simulateNativeEventOnNode– actually exercises it. Should I rewrite the test to use this other event triggering function?

Thanks!

@gaearon
Copy link
Collaborator

gaearon commented Oct 26, 2017

I think I was wrong actually. SimulateNative is also not great because it bypasses the real browser events (which is what we want to test). Ideally we should just call dispatchEvent on nodes, like #11309 did.

Copy link
Collaborator

@gaearon gaearon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rewrite both to use dispatchEvent.

#11309 can serve as an inspiration. (You won't need the "value setter" part in it, just the event dispatching.)

@gaearon gaearon mentioned this pull request Oct 26, 2017
26 tasks
@accordeiro
Copy link
Contributor Author

OK, that makes sense – I've rewritten both tests to use dispatchEvent :)

gaearon
gaearon previously approved these changes Oct 26, 2017
div,
);
expect(extracted.length).toBe(2);
simulateMouseEvent(component, 'mouseover', iframe.contentWindow);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't it be simulated on the component?
(which should be renamed to node btw)

I believe the original test did that.

expect(enter.relatedTarget).toBe(iframe.contentWindow);
expect(events.length).toBe(1);
expect(events[0].target).toBe(component);
expect(events[0].relatedTarget).toBe(iframe.contentWindow);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which part of the code are this testing here? Are we confident that removing it causes test to fail?

Copy link
Collaborator

@gaearon gaearon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the first test is wrong because it doesn't test EnterLeavePlugin anymore.

EnterLeavePlugin uses mouseover event subscription to determine which elements are entered and which are left. But we should be testing it by verifying React's onMouseEnter and onMouseLeave events, not onMouseOver itself.

@gaearon
Copy link
Collaborator

gaearon commented Oct 26, 2017

Specifically you can see the first test was added in a2ecee5.

This tells you which section of code it’s supposed to be testing. You can see that removing these changes doesn’t make the test fail, but it should.

You can also check that with the original test file, reverting those changes makes it hang. Which is not ideal (I'd prefer it fail 😛 ) but does demonstrate that we had coverage for this.

@gaearon
Copy link
Collaborator

gaearon commented Oct 31, 2017

Gentle ping, are you interested in following up on this?

@accordeiro
Copy link
Contributor Author

Yes, of course – sorry for not following up on this before. I'll try to make the changes tomorrow at latest, is this ok? :)

@accordeiro
Copy link
Contributor Author

Hi @gaearon – I've just pushed some changes.

I've checked that deleting the code that you referenced here now makes the test fail. I've also tried setting the win var on the current implementation of EnterLeavePlugin.js to null makes the test fail.

I'm still having a hard time testing the onMouseEnter React event. I've tried dispatching both the mouseout and the mouseenter events (from opposite origins, naturally) and none of them have actually called the onMouseEnter function on the node. Is this something I should be worried about?

Using onMouseLeave + dispatching the mouseleave MouseEvent [like on the current diff] worked like a charm, though.

Please let me know if I'm on the right direction.

@gaearon
Copy link
Collaborator

gaearon commented Nov 3, 2017

I'm still having a hard time testing the onMouseEnter React event. I've tried dispatching both the mouseout and the mouseenter events (from opposite origins, naturally) and none of them have actually called the onMouseEnter function on the node. Is this something I should be worried about?

You can see by the source that the only events React actually listens to in order to implement onMouseEnter (or onMouseLeave) is mouseover and mouseout. Does this help?

@gaearon
Copy link
Collaborator

gaearon commented Nov 3, 2017

Thanks! This looks awesome.
I also added coverage for the onMouseEnter case which wasn't being tested by the new code.

@gaearon gaearon merged commit 43a1e0d into facebook:master Nov 3, 2017
Ethan-Arrowood pushed a commit to Ethan-Arrowood/react that referenced this pull request Dec 8, 2017
* Use only public API for EnterLeaveEventPlugin Tests (facebook#11299)

* Trigger native event to test EnterLeaveEventPlugin (facebook#11299)

* Rewrite EnterLeaveEventPlugin tests to use dispatchEvent

* Update EnterLeaveEventPlugin test to use OnMouseLeave event

* Add coverage for onMouseEnter too
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants