-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
UnitControl: rewrite tests in TypeScript #40697
Conversation
// The unit is not being displayed! | ||
const label = screen.getByText( '%' ); |
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.
Currently this line is failing in unit tests — that's because we switched from just checking that an element with class components-unit-control__unit-label
exists, to actually looking for the unit label being displayed (testing-library
FTW!)
I'm not sure if we should call this a bug, though. Technically we're not passing any value
to UnitControl
, and therefore the component internally has not value
to parse a unit from. If we passed value="30%"
, then this test would pass.
If our expectations are that UnitControl
would display the %
unit, for how the component is coded right now, it would mean that effectively the selected unit is %
(which would also be reflected in the new components's value
and probably fired through the change
callbacks). Would that be a correct behavior to expect? I'm personally not so sure.
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.
From how I'd interpret it, the purpose of this test is exactly what it says: "should render label if single units". The fact that it's rendered with no value defined is just an oversight, and I think the original PR confirms that (#33634).
I think we should just render it with value="30%"
like you suggest.
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 think we should just render it with
value="30%"
like you suggest.
I went ahead and did this in 8929d0b (which should fix the tests for now).
I still decided to look into this a bit more, and therefore I decided to add a couple of Storybook examples for this scenario:
- One closely representing the failing unit test (e.g. uncontrolled
UnitControl
with just one unit) - Another one where
UnitControl
is controlled, but its starting value isundefined
(still with just one unit)
In the controlled case, the unit is not visible when value
is set to undefined
(its starting value). The unit then becomes visible when a number is entered, and stays visible even if those numbers are deleted (likely because the value
becomes an empty string rather than undefined
):
unit-control-single-unit-controlled.mp4
In the uncontrolled case, the unit is never shown even after the user enters a value
:
unit-control-single-unit-uncontrolled.mp4
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.
Huh, good investigation! I would expect that when there is only one unit, the unit would be visible at mount and stay visible no matter what. This kind of seems like a common use case so I'd say it's worth fixing if it isn't too hard. What do you think?
Size Change: +1.03 kB (0%) Total Size: 1.23 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.
Really appreciate the meticulous work here 🙂
// The unit is not being displayed! | ||
const label = screen.getByText( '%' ); |
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.
From how I'd interpret it, the purpose of this test is exactly what it says: "should render label if single units". The fact that it's rendered with no value defined is just an oversight, and I think the original PR confirms that (#33634).
I think we should just render it with value="30%"
like you suggest.
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.
Aside from the possible bug you uncovered, I think this PR itself is good to go 👍
I wonder if this bug would be fixed by the changes in #40518 and #40568 Since this PR doesn't introduce any new features / fixes, I'm going to hold and merge it only after #40518 and #40568 are merged. This will also avoid introducing conflicts in those PRs (which are already quite complex and introduce changes to the same unit tests that this PR touches). |
This all looks good to me.
I looked into this and it seems the single unit A one-liner can fix it. Maybe I'll put it in a PR.diff --git a/packages/components/src/unit-control/index.tsx b/packages/components/src/unit-control/index.tsx
index 089155b9d2..00810c45ef 100644
--- a/packages/components/src/unit-control/index.tsx
+++ b/packages/components/src/unit-control/index.tsx
@@ -88,7 +88,7 @@ function UnforwardedUnitControl(
);
const [ unit, setUnit ] = useControlledState< string | undefined >(
- unitProp,
+ units.length === 1 ? units[ 0 ].label : unitProp,
{
initial: parsedUnit,
fallback: '',
I think it's fine if you want to go ahead and an merge this as any conflict would be trivial to resolve. Actually, if you were to add any missing |
Thank you for the help in coordinating around these changes! I went ahead and merged this PR as-is. I'm going to open 2 follow-ups:
(will update this message with links to those PRs once opened) |
What?
Rewrite
UnitControl
's unit tests to TypeScript, and add a few related tweaks/fixes that were highlighted by the refactor.Why?
See #35744 for more context.
How?
toBeInTheDocument
,getByRole
...)TODO: maybe add another bug fix changelog entry (see comment below)
Testing Instructions