-
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
ObservableMap: optimize unsubscribe and add unit tests #60892
Conversation
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.
To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
list = new Set(); | ||
listeners.set( name, list ); | ||
} | ||
const list = getListeners( name ); |
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.
Is getListeners
intended to be reused at some point?
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 extracted getListeners
so that TypeScript stops bothering me 🙂 This code doesn't pass type check:
let list = ...
if ( ! list ) {
list = ...
}
return () => list.delete();
TypeScript (5.1.x) thinks that list
can be undefined
inside the body of the returned function. Because after the first line it really can be undefined
. TypeScript 5.4 no longer has this bug. But it forced me to extract the list
-assigning code to a function.
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.
After merging TS upgrade to 5.4.5 in #60793, I was able to inline the getListeners
function. TypeScript now knows list
is never undefined
.
Size Change: -12 B (0%) Total Size: 1.74 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.
Thanks for adding tests 🙌
Left some nits, but looks great to me!
// check that unsubscription really works. | ||
unsubA(); | ||
unsubB(); | ||
map.set( 'a', 3 ); | ||
expect( notifsFromA ).toBe( 3 ); | ||
expect( notifsFromB ).toBe( 1 ); |
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.
Minor: Should those subscription assertions be in separate tests? This particular one tests that after unsubscribing individual values are no longer observed, which is exactly the opposite of what the test claims to do 🤔
const map = observableMap(); | ||
map.set( 'a', 1 ); | ||
|
||
let renders = 0; |
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.
Perhaps a cleaner way to store the count inside a ref in the component?
We could then render that value and assert it the same way we assert "value is N"
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, but this works equally well, it's not complicated or confusing in anyway, and we're already doing this in other tests, like for useSelect
.
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.
It kind of feels off to me to pass and modify an external variable in a component, but it's not critical in a test. Leaving it to your judgment.
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 wrapped the functions where we count how many times they are called in a jest.fn
, and started checking the call counts with .toHaveBeenCalledTimes
. That should be a more professional way to do it 🙂
b0d3994
to
5ae7a80
Compare
Followup to #60879 that implements some review suggestions: