-
Notifications
You must be signed in to change notification settings - Fork 46.9k
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
Remove tests in ReactDOMComponent-test depending on internal API #11337
Remove tests in ReactDOMComponent-test depending on internal API #11337
Conversation
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.
Doesn't this just create another tracker on top? I'm not sure this actually tells us that the existing tracker works.
I think there might not be a super clear way to implement this. You could just read the tracker from node. _valueTracker
instead (and assert it exists). This does test an implementation detail, but at least it’ll be obvious when it breaks. I’m open to better suggestions though.
Hi @gaearon , could just use the container to verify the value? Thanks. it('should track input values', () => {
var container = document.createElement('div');
var inst = ReactDOM.render(
<input type="text" defaultValue="foo" />,
container,
);
-
- var tracker = inputValueTracking._getTrackerFromNode(inst);
-
- expect(tracker.getValue()).toEqual('foo');
+ expect(container.firstChild.value).toEqual('foo');
});
|
@gaearon Thank you for reviewing. Actually I did it the way you mentioned, using |
I haven’t dived deeply into what it’s supposed to test. (I’m not very familiar with that part of code.) But it would be nice if you could try to “break” it on master by doing bad changes to |
06be042
to
7117f52
Compare
@gaearon I took your advice to use |
7117f52
to
3e9bfe3
Compare
Yes. I think it would be better to apply the same strategy as in #11309, if possible. |
based on #11309, should I change the
and then in the test case, I still can get the value of the input by using
this is possible because |
@AudyOdi Yes, I think so. |
Maybe we can invite @SadPandaBear to look at these changes are right? var ReactTestUtils;
var ReactDOM;
var ReactDOMServer;
- var inputValueTracking;
function normalizeCodeLocInfo(str) {
return str && str.replace(/\(at .+?:\d+\)/g, '(at **)');
@@ -26,8 +25,6 @@ describe('ReactDOMComponent', () => {
ReactDOM = require('react-dom');
ReactDOMServer = require('react-dom/server');
ReactTestUtils = require('react-dom/test-utils');
- // TODO: can we express this test with only public API?
- inputValueTracking = require('../client/inputValueTracking');
});
describe('updateDOM', () => {
@@ -833,6 +830,11 @@ describe('ReactDOMComponent', () => {
describe('mountComponent', () => {
var mountComponent;
+ var getTrackedValue = Object.getOwnPropertyDescriptor(
+ HTMLInputElement.prototype,
+ 'value',
+ ).get;
+
beforeEach(() => {
mountComponent = function(props) {
var container = document.createElement('div');
@@ -1151,19 +1153,13 @@ describe('ReactDOMComponent', () => {
<input type="text" defaultValue="foo" />,
container,
);
-
- var tracker = inputValueTracking._getTrackerFromNode(inst);
-
- expect(tracker.getValue()).toEqual('foo');
+ expect(getTrackedValue.call(inst)).toEqual('foo');
});
it('should track textarea values', () => {
var container = document.createElement('div');
var inst = ReactDOM.render(<textarea defaultValue="foo" />, container);
-
- var tracker = inputValueTracking._getTrackerFromNode(inst);
-
- expect(tracker.getValue()).toEqual('foo');
+ expect(getTrackedValue.call(inst)).toEqual('foo');
});
it('should throw for children on void elements', () => { |
@gaearon @zhaozhiming I have submitted new commit that use |
node.constructor.prototype, | ||
'value', | ||
).get; | ||
}; |
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.
Nice!
Really liked what you did here for the html interfaces. 👍
@@ -1151,19 +1154,37 @@ describe('ReactDOMComponent', () => { | |||
<input type="text" defaultValue="foo" />, | |||
container, | |||
); | |||
var getTrackedValue = getValueTracker(inst); |
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'm not sure if you do have to create an instance for the trackers. See, the solution I made for ReactDOMInput-test actually only had the calls for the input values i wanted to test.
Anyway, I can't see any trouble really about this solution. 😄
I see you are setting the value directly into inst. What happens if you set with the tracker instance you created (like this)? Will the test still pass (considering you write the setUntrackedValue and everything)?
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.
@SadPandaBear Thank you for reviewing. I have confirmed that changing value using tracker instance still pass the test. The reason I create an instance for the tracker is because getValueTracker
is being used for both input
and textarea
element. Not sure about using HTMLInputElement
for textarea
is the correct way to do it.
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.
Not sure about using HTMLInputElement for textarea is the correct way to do it.
Can you declare two separate helpers (for input and textarea) 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.
@gaearon got it, I will define the helper in each test case instead so that input
will use HTMLInputElement
, and textarea
will use HTMLTextAreaElement
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.
Let's use the prototype getter to make sure we're reading the right thing. Since we test both input and textarea, let's read each and keep them in separate variables.
@gaearon I push new commit that move |
expect(getValueTracker.call(inst)).toEqual('foo'); | ||
|
||
inst.defaultValue = 'new foo'; | ||
expect(getValueTracker.call(inst)).not.toEqual('new foo'); |
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.
This check is redundant. You already check for the other value later.
@@ -1152,18 +1149,46 @@ describe('ReactDOMComponent', () => { | |||
container, | |||
); | |||
|
|||
var tracker = inputValueTracking._getTrackerFromNode(inst); | |||
var getValueTracker = Object.getOwnPropertyDescriptor( |
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.
This should ideally be done before React is imported.
Leaving this to @jquense to review because I don't understand what the original test is supposed to test. |
So the original test is supposed to confirm that the input tracking stuff is set up from initial values when you render an input for the first time. Which is to say that the tracking logic ensures change events don't fire twice for the same value. I'm trying to think of a public side effect that would indicate this isn't working...I think the test case might be that if you initialize an input with value |
If you wanted to keep it simple, I'd just test that the DOM node has the tracker attached to it and has the same value as the jsx value. Not quite public api only but I'm not really sure anything else is gonna succinctly test the right thing |
Why is it important to test that the tracker is attached? Does something break if it's not? :-) |
You'd en up defeating the change dedupe logic at least... Tbh I don't remember if there is a more severe consequence. I do think this set of tests doesn't really belong here. They make sense when testing the specific implementation of the tracker getting attached here, but ultimately this is change event specific code |
Is there any way we can salvage these tests to offer the same coverage they currently offer without actually relying on implementation details? Or can we just delete them? |
Thanks @jquense and @gaearon. I appreciate the insight. The original test was only testing if the tracker is attached, I added some other tests because I didn't know that it's been covered in |
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.
Let's just remove these test.
I'll add a follow up to #11333 instead.
@gaearon got it. I just pushed new commit that remove the tests and change it back to original test, also move the value tracker definition, for both |
|
||
function normalizeCodeLocInfo(str) { | ||
return str && str.replace(/\(at .+?:\d+\)/g, '(at **)'); | ||
} | ||
|
||
beforeEach(() => { | ||
jest.resetModules(); | ||
|
||
getInputValueTracker = Object.getOwnPropertyDescriptor( |
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 don't understand what this does in the context of this test.
As @jquense explained above, the original purpose of the test is to verify our custom tracker object "sees" the original value.
However this notion of "tracker" is not the same thing that you get from the HTMLInputElement's prototype. I think you got confused by naming used in some other test.
The thing you read from HTMLInputElement prototype is just the jsdom's value accessor itself. So there is no need to test it at all. You're just testing that jsdom works. (But we already know it works as it has its own test suite :-)
I just removed these tests, as they aren't very useful, and we'll cover the relevant scenarios as part of |
@gaearon No problem! Yes I agree that the tests are not that useful, and a lot of confusion with |
…ebook#11337) * Remove inputValueTracking from ReactDOMComponent-test dependency * prettier * use node._valueTracker and add some test cases to make sure that value being tracked * using Object.getOwnPropertyDescriptor to get the tracked value * move getValueTracker to each test case and use its corresponding prototype * remove tests and move the value tracker definition before React is imported * Delete these tests completely
Removed
inputValueTracking
dependency inReactDOMComponent-test
based on list in #11299. I took this approach based on #11309 review. Please let me know if this is not the way we should test it.