Skip to content
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

New testing helpers using using, replace old console mocking functions. #11177

Merged
merged 14 commits into from
Sep 14, 2023

Conversation

phryneas
Copy link
Member

@phryneas phryneas commented Aug 29, 2023

This PR introduces three new internal test helpers to make use of the new "Explicit Resource Management" feature with using and await using that has made it into TypeScript 5.2.

using obj = withCleanup(object, cleanup): T & Disposable

to create disposable objects and the two helpers

using consoleSpy = spyOnConsole("log", "info", ...)
using consoleSpy = spyOnConsole.takeSnapshots("log", "info", ...)

that mock console methods until disposed on scope exit.

To make sure that Disposable and AsyncDisposable objects are always initialized with using, I added a lint rule.

It also @deprecates the old mocking helper functions withErrorSpy, withWarningSpy and withLogSpy and removes all usage of them from our code.

The PR removes a most usages of manual console mocking, but not all of them (a few last one would require bigger test refactors).

This might look like a small change, but the withCleanup pattern will allow us to write more self-contained test without the use of beforeEach, afterEach etc.
Those helpers seemed nice for setting up tests, but as the tests grew, made it really hard to reason about our tests later on.


Checklist:

  • If this PR contains changes to the library itself (not necessary for e.g. docs updates), please include a changeset (see CONTRIBUTING.md)
  • If this PR is a new feature, please reference an issue where a consensus about the design was reached (not necessary for small changes)
  • Make sure all of the significant new logic is covered by tests

@changeset-bot
Copy link

changeset-bot bot commented Aug 29, 2023

⚠️ No Changeset found

Latest commit: 5e05938

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@github-actions
Copy link
Contributor

github-actions bot commented Aug 29, 2023

size-limit report 📦

Path Size
dist/apollo-client.min.cjs 37.28 KB (0%)
import { ApolloClient, InMemoryCache, HttpLink } from "dist/main.cjs" 43.75 KB (0%)
import { ApolloClient, InMemoryCache, HttpLink } from "dist/main.cjs" (production) 42.32 KB (0%)
import { ApolloClient, InMemoryCache, HttpLink } from "dist/index.js" 32.52 KB (0%)
import { ApolloClient, InMemoryCache, HttpLink } from "dist/index.js" (production) 31.27 KB (0%)
import { ApolloProvider } from "dist/react/index.js" 1.21 KB (0%)
import { ApolloProvider } from "dist/react/index.js" (production) 1.2 KB (0%)
import { useQuery } from "dist/react/index.js" 4.27 KB (0%)
import { useQuery } from "dist/react/index.js" (production) 4.08 KB (0%)
import { useLazyQuery } from "dist/react/index.js" 4.58 KB (0%)
import { useLazyQuery } from "dist/react/index.js" (production) 4.4 KB (0%)
import { useMutation } from "dist/react/index.js" 2.52 KB (0%)
import { useMutation } from "dist/react/index.js" (production) 2.51 KB (0%)
import { useSubscription } from "dist/react/index.js" 2.24 KB (0%)
import { useSubscription } from "dist/react/index.js" (production) 2.2 KB (0%)
import { useSuspenseQuery } from "dist/react/index.js" 4.76 KB (0%)
import { useSuspenseQuery } from "dist/react/index.js" (production) 4.19 KB (0%)
import { useBackgroundQuery } from "dist/react/index.js" 4.28 KB (0%)
import { useBackgroundQuery } from "dist/react/index.js" (production) 3.7 KB (0%)
import { useReadQuery } from "dist/react/index.js" 2.96 KB (0%)
import { useReadQuery } from "dist/react/index.js" (production) 2.91 KB (0%)
import { useFragment } from "dist/react/index.js" 2.08 KB (0%)
import { useFragment } from "dist/react/index.js" (production) 2.03 KB (0%)

@netlify
Copy link

netlify bot commented Aug 29, 2023

Deploy Preview for apollo-client-docs ready!

Name Link
🔨 Latest commit 4a49723
🔍 Latest deploy log https://app.netlify.com/sites/apollo-client-docs/deploys/64f995fb4cd6010008f7aa55
😎 Deploy Preview https://deploy-preview-11177--apollo-client-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@@ -3,13 +3,6 @@
exports[`@client @export tests should NOT refetch if an @export variable has not changed, the current fetch policy is not cache-only, and the query includes fields that need to be resolved remotely 1`] = `
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This snapshot was confusing me to no end, but it seems that for some reason, delayed console.log calls from other tests has spilled over into these ones.

On main, calling these tests individually, they had very different snapshots from just running the whole test file.

That seems to have somehow surfaced during this refactor.

(resolve, reject) => {
it("should warn if server returns wrong data", async () => {
using _consoleSpies = spyOnConsole.takeSnapshots("error");
await new Promise((resolve, reject) => {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not incredibly happy about this way of removing itAsync, but in this case, we need a way of holding _consoleSpies in scope until the test is finished. This was the "least code changes" way of doing so.

I don't expect this pattern to be necessary in future code, as we have generally moved away from itAsync.

jest.SpyInstance<void, any[], any>
>;

/** @internal */
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By the way, I've started using these @internal annotations because it might make sense to bring Api Extractor into the picture at some point, which would help us keep a good overview of changes in our public type surface.

@phryneas phryneas changed the title example testing helpers with using New testing helpers using using, replace old console mocking functions. Sep 8, 2023
Copy link
Contributor

@alessbell alessbell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@phryneas and I walked through this in details offline - very excited to begin using these utilities (pun unavoidable in my defense) 🎉🎉

@phryneas phryneas merged commit dc4baed into main Sep 14, 2023
8 checks passed
@phryneas phryneas deleted the pr/tests-using branch September 14, 2023 13:41
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 15, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants