-
Notifications
You must be signed in to change notification settings - Fork 1
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
Rework metric hooks using SWR, and update tests. #327
Conversation
🦋 Changeset detectedLatest commit: 3c38025 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Visit the preview URL for this PR (updated for commit 3c38025): https://act-now-packages--pr327-mikelehen-metric-hoo-n27yao2g.web.app (expires Mon, 31 Oct 2022 23:59:24 GMT) 🔥 via Firebase Hosting GitHub Action 🌎 Sign: ad39b6c29b2ae4e8fa7983fbf3316d2e514cb069 |
@@ -1,7 +1,7 @@ | |||
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */ | |||
module.exports = { | |||
preset: "ts-jest", | |||
testEnvironment: "node", | |||
testEnvironment: "jsdom", |
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 had to do this after switching to @testing-library/react
. The tests still pass, and I think jsdom
probably makes sense for testing web components anyway, so hopefully it's fine? 🤷
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.
yeah it should be fine :)
@@ -39,7 +39,7 @@ | |||
"@storybook/manager-webpack4": "^6.5.12", | |||
"@storybook/react": "^6.5.12", | |||
"@storybook/testing-library": "^0.0.13", | |||
"@testing-library/react-hooks": "^8.0.1", | |||
"@testing-library/react": "^13.4.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.
I switched because react-hooks is going to be deprecated and this solved a "A worker process has failed to exit gracefully and has been force exited. This is likely caused by tests leaking due to improper teardown" warning I was getting after I started using SWR.
const { result, waitForNextUpdate, rerender } = renderHook< | ||
any, | ||
DataOrError<MultiRegionMultiMetricDataStore> | ||
>( |
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.
There was something messed up with the @testing-library/react-hooks
types that forced me to manually specify the generic types and use any
. But with @testing-library/react
this problem went away.
await waitForNextUpdate(); | ||
await waitFor(() => { | ||
expect(result.current.data).not.toBe(undefined); | ||
}); |
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.
@testing-library/react
got rid of waitForNextUpdate()
and this is the new way to do it, I guess. I don't love it, but it's what's in the migration guide.
@@ -93,8 +88,13 @@ describe("metric data hooks", () => { | |||
// Render the hook again with different regions / metrics. This should perform a fetch. | |||
rerender({ regions: [testRegionWA], metrics: [MetricId.E] }); | |||
expect(catalog.dataFetchesCount).toBe(++expectedFetches); | |||
// Data should go back to loading state. | |||
expect(result.current.data).toBe(undefined); |
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 expectation is new, and it would fail before we switched to SWR. Now, when you request different regions / metrics, we temporarily revert to the loading state.
@@ -75,9 +68,11 @@ describe("metric data hooks", () => { | |||
// The catalog should have performed a data fetch, but since it's anync, | |||
// initially the hook won't return data. | |||
expect(catalog.dataFetchesCount).toBe(++expectedFetches); | |||
expect(result.current.data).toStrictEqual(undefined); | |||
expect(result.current.data).toBe(undefined); |
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.
Drive-by change for consistency. 🤷
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.
Alternatively, we could use toBeUndefined()
and not.toBeUndefined()
(the Jest docs say it's better practice, but they don't say why)
You could write
expect(bestDrinkForFlavor('octopus')).toBe(undefined)
, but it's better practice to avoid referring to undefined directly in your code.
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.
Ah! Interesting. That's probably a tad cleaner. And there's a toBeDefined()
I can use instead of not.toBeUndefined()
which I definitely like better. Updated!
FWIW- In the olden days of JavaScript, when you referenced undefined
in your code, you were actually just referencing a global variable called undefined
that had the value undefined
and if you accidentally wrote code like this:
var globalToUpdate;
window[globalToUpdate] = "hello";
You would accidentally overwrite the undefined
variable and so now whenever you referred to undefined
in your code, you'd end up with "hello"
instead of undefined
.
And so the "correct" way to check for undefined was typeof value === "undefined"
instead of value === undefined
.
But at some point browsers realized that was terrible and started prevented you from overwriting undefined
. So window["test"] = "hello"
will create a global called test
, but window["undefined"] = "hello"
is a no-op. 😁
I'm guessing that's part of why jest has those docs and it's not as relevant now. But toBeUndefined()
is pretty clean, so I'll go ahead and use it!
|
||
// In order to allow people to pass in a new array of metrics that | ||
// contain the same metrics as before without triggering additional | ||
// fetches, we need this caching trick. |
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.
Note that I think SWR is going to serialize the list of metrics / regions in order to check if they changed between calls, which is slower than what I was doing here, but hopefully it's fine. (I'm mostly just nervous about when we do regions.all
for fetching data for rendering the map / compare table, etc. Serializing the whole list of regions isn't ideal.)
* Reworked metric data hooks to use `useSWR` hook from https://swr.vercel.app/. This was surprisingly smooth, and it fixes #315 (the hook will now return to the loading state (data==undefined) when you change the metrics / regions you're asking for). * Reworked the tests to use `@testing-library/react` instead of `@testing-library/react-hooks` as the latter was triggering a is soon going to be deprecated and for some reason with SWR was triggering a "A worker process has failed to exit gracefully and has been force exited. This is likely caused by tests leaking due to improper teardown." warning. * minor cleanup
e605e27
to
01e853d
Compare
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.
Looks good! Optionally we could use .toBeUndefined()
for the tests, but I'm not sure if that's actually better.
@@ -75,9 +68,11 @@ describe("metric data hooks", () => { | |||
// The catalog should have performed a data fetch, but since it's anync, | |||
// initially the hook won't return data. | |||
expect(catalog.dataFetchesCount).toBe(++expectedFetches); | |||
expect(result.current.data).toStrictEqual(undefined); | |||
expect(result.current.data).toBe(undefined); |
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.
Alternatively, we could use toBeUndefined()
and not.toBeUndefined()
(the Jest docs say it's better practice, but they don't say why)
You could write
expect(bestDrinkForFlavor('octopus')).toBe(undefined)
, but it's better practice to avoid referring to undefined directly in your code.
useSWR
hook from https://swr.vercel.app/. This was surprisingly smooth, and it fixes Revisit behavior of asynchronoususeMetricData()
hooks. #315 (the hook will now return to the loading state (data==undefined) when you change the metrics / regions you're asking for).@testing-library/react
instead of@testing-library/react-hooks
as the latter was triggering a is soon going to be deprecated and for some reason with SWR was triggering a "A worker process has failed to exit gracefully and has been force exited. This is likely caused by tests leaking due to improper teardown." warning.