-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
NumberControl
: refactor styles/tests/stories to TypeScript, replace fireEvent
with user-event
#45990
NumberControl
: refactor styles/tests/stories to TypeScript, replace fireEvent
with user-event
#45990
Conversation
Open in CodeSandbox Web Editor | VS Code | VS Code Insiders |
it( 'should parse to number value on ENTER keypress when required', async () => { | ||
const user = userEvent.setup( { | ||
advanceTimers: jest.advanceTimersByTime, | ||
} ); | ||
|
||
render( <NumberControl value={ 5 } required={ true } /> ); | ||
|
||
const input = getInput(); | ||
await user.clear( input ); | ||
await user.type( input, 'abc' ); | ||
await user.keyboard( '[Enter]' ); | ||
|
||
expect( input ).toHaveValue( 0 ); | ||
} ); | ||
|
||
it( 'should parse to empty string on ENTER keypress when not required', async () => { | ||
const user = userEvent.setup( { | ||
advanceTimers: jest.advanceTimersByTime, | ||
} ); | ||
|
||
render( <NumberControl value={ 5 } required={ false } /> ); | ||
|
||
const input = getInput(); | ||
await user.clear( input ); | ||
await user.type( input, 'abc' ); | ||
await user.keyboard( '[Enter]' ); | ||
|
||
// React Testing Library associated `null` to empty string types for | ||
// numeric `input` elements | ||
// (see https://github.com/testing-library/jest-dom/blob/v5.16.5/src/utils.js#L191-L192) | ||
expect( input ).toHaveValue( null ); |
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.
Previously, in these two tests we were using fireEvent
to submit a new value 10 abc
— the fact that the value was set in one go meant that the whole string couldn't be parsed as a number.
Switching to user-event
meant that each single character in that string would be typed individually. This change was causing the tests to fail, because the component would first parse the number 10
correctly, and then refuse to parse ' abc'
— meaning that the input's value would become 10
in both tests, instead of 0
and null
.
I therefore decided to change slightly the tests, and simulate the user entering a fully invalid number (ie. 'abc'
), which makes the tests pass again.
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.
A question related to the second of these tests: Do we expect the visible value in regular browsers to actually clear? That's what the test suggests to me but it's not the case.
number-control-test-parse-to-empty.mp4
If that's what we expect, I don't think it can actually be tested by jsdom (or even very easily in most browsers) because in number inputs non-numeric value
s are reported as ''. That means the second test is really only good for testing that NumberControl
doesn't produce a numeric value in this scenario. I suppose there’s some value in that but maybe the test could be more clearly written that way.
I don't think it’s anything this PR should address. I just wanted to bring it up.
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.
Good point! I tried to make some small improvements in 6732efb, hopefully it's a step in the right direction!
// React Testing Library associated `null` to empty string types for | ||
// numeric `input` elements | ||
// (see https://github.com/testing-library/jest-dom/blob/v5.16.5/src/utils.js#L191-L192) |
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.
As part of the refactor, I switched from expect( input.value ).toBe( ... )
to expect( input ).toHaveValue( ... )
.
This change has two consequences, caused by how Testing Library extracts the value of numeric inputs:
- the expected value is parsed as a number (previously the tests were expecting strings)
- empty strings are converted to
null
These are effectively only changes to how the assertions are made, but I wanted to clarify them since there's already enough confusion around the type of the value
prop.
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.
How about .not.toHaveValue()
? If that works, I believe it will be a better representation of what we're asserting here.
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 tried that out, and realised that unfortunately .not.toHaveValue()
passes for all falsey values — which means that we wouldn't have a way to tell the difference between 0
and ''
.
Going to stick with the current checks for now
Size Change: -1 B (0%) Total Size: 1.31 MB
ℹ️ View Unchanged
|
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.
Solid improvements! 🚢
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.
Looking pretty awesome, great work!
Left a few minor suggestions, nothing blocking.
🚀
// React Testing Library associated `null` to empty string types for | ||
// numeric `input` elements | ||
// (see https://github.com/testing-library/jest-dom/blob/v5.16.5/src/utils.js#L191-L192) |
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.
How about .not.toHaveValue()
? If that works, I believe it will be a better representation of what we're asserting here.
f644ed5
to
f75fcd0
Compare
f75fcd0
to
98d8b1d
Compare
98d8b1d
to
6732efb
Compare
What?
This PR refactors to TypeScript all remaining JavaScript files in
NumberControl
Why?
@wordpress/components
package to TypeScript #35744NumberControl
: introducestring
as a type for thevalue
prop #45949NumberControl
: tidy up and fix types aroundvalue
prop #45982How?
Most of the changes are trivial, but I'll highlight the 🌶️ bits with inline comments.
Reviewing commit-by-commit should be a much easier task
Testing Instructions