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

Modernize unit test setup #4114

Merged
merged 20 commits into from
Jan 24, 2024
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
68d718a
Rename `vitest.config.ts` to `vitest.config.mts`
aryaemami59 Jan 20, 2024
9b3eb8f
Change `vitest.config.ts` to `vitest.config.mts` inside `tests.yml` file
aryaemami59 Jan 23, 2024
58a106e
Remove `interopDefault` from `vitest.config.mts` as it is enabled by …
aryaemami59 Jan 20, 2024
e7019ee
Replace the deprecated `deps.inline` with `server.deps.inline`
aryaemami59 Jan 20, 2024
8f69f3b
Rename `vitest.setup.js` to `vitest.setup.ts`
aryaemami59 Jan 20, 2024
ae7de6c
Add `test:watch` NPM script
aryaemami59 Jan 20, 2024
50a1a64
Add `vitest.setup.ts` to `setupFiles` in `vitest.config.mts`
aryaemami59 Jan 20, 2024
834a7c9
Bump `node-fetch` dev dependency
aryaemami59 Jan 20, 2024
c4c874d
Bump msw
aryaemami59 Jan 23, 2024
0820d20
Fix stubbing globals in `vitest.setup.ts`
aryaemami59 Jan 23, 2024
c6b4213
Fix handlers to be compatible with latest version of `msw`
aryaemami59 Jan 23, 2024
a021617
Split up handlers and server files
aryaemami59 Jan 23, 2024
c8a5f3b
Use codemods provided by msw to modernize msw syntax
aryaemami59 Jan 23, 2024
9576c3d
Convert `createSlice` skip test to todo test
aryaemami59 Jan 23, 2024
b3a2d59
Fix timeout tests
aryaemami59 Jan 23, 2024
4212a97
Fix `FormData` tests
aryaemami59 Jan 23, 2024
5def501
Use the `delay` function recommended by MSW
aryaemami59 Jan 23, 2024
9e3d91a
Remove `msw-npm-0.40.2-2107d48752` file
aryaemami59 Jan 23, 2024
e0cb187
Remove `as any` type assertions inside `buildHooks.test.tsx`
aryaemami59 Jan 23, 2024
21fe9fc
Fix type issues related to `PathParams` inside `handlers.ts`
aryaemami59 Jan 23, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ jobs:
- name: Install build artifact
run: yarn workspace @reduxjs/toolkit add $(pwd)/package.tgz

- run: sed -i -e /@remap-prod-remove-line/d ./tsconfig.base.json ./vitest.config.ts ./src/tests/*.* ./src/query/tests/*.*
- run: sed -i -e /@remap-prod-remove-line/d ./tsconfig.base.json ./vitest.config.mts ./src/tests/*.* ./src/query/tests/*.*

- name: Run tests, against dist
run: yarn test
Expand Down Expand Up @@ -133,7 +133,7 @@ jobs:
- name: Show installed RTK versions
run: yarn info @reduxjs/toolkit

- run: sed -i -e /@remap-prod-remove-line/d ./tsconfig.base.json ./vitest.config.ts ./src/tests/*.* ./src/query/tests/*.*
- run: sed -i -e /@remap-prod-remove-line/d ./tsconfig.base.json ./vitest.config.mts ./src/tests/*.* ./src/query/tests/*.*

- name: Test types
run: |
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
"@babel/types": "7.19.3",
"esbuild": "0.19.7",
"jest-snapshot": "29.3.1",
"msw": "patch:msw@npm:0.40.2#.yarn/patches/msw-npm-0.40.2-2107d48752",
aryaemami59 marked this conversation as resolved.
Show resolved Hide resolved
"jscodeshift": "0.13.1",
"react-redux": "npm:8.0.2",
"react": "npm:18.2.0",
Expand Down
5 changes: 3 additions & 2 deletions packages/toolkit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@
"invariant": "^2.2.4",
"jsdom": "^21.0.0",
"json-stringify-safe": "^5.0.1",
"msw": "^0.40.2",
"node-fetch": "^2.6.1",
"msw": "^2.1.4",
"node-fetch": "^3.3.2",
"prettier": "^2.2.1",
"query-string": "^7.0.1",
"rimraf": "^3.0.2",
Expand All @@ -101,6 +101,7 @@
"format:check": "prettier --list-different \"(src|examples)/**/*.{ts,tsx}\" \"docs/*/**.md\"",
"lint": "eslint src examples",
"test": "vitest --run",
"test:watch": "vitest --watch",
"type-tests": "yarn tsc -p src/tests/tsconfig.typetests.json && yarn tsc -p src/query/tests/tsconfig.typetests.json",
"prepack": "yarn build"
},
Expand Down
10 changes: 5 additions & 5 deletions packages/toolkit/src/query/tests/apiProvider.test.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import * as React from 'react'
import { createApi, ApiProvider } from '@reduxjs/toolkit/query/react'
import { configureStore } from '@reduxjs/toolkit'
import { ApiProvider, createApi } from '@reduxjs/toolkit/query/react'
import { fireEvent, render, waitFor } from '@testing-library/react'
import { waitMs } from './helpers'
import { delay } from 'msw'
import * as React from 'react'
import { Provider } from 'react-redux'
import { configureStore } from '@reduxjs/toolkit'

const api = createApi({
baseQuery: async (arg: any) => {
await waitMs()
await delay(150)
return { data: arg?.body ? arg.body : null }
},
endpoints: (build) => ({
Expand Down
51 changes: 12 additions & 39 deletions packages/toolkit/src/query/tests/buildCreateApi.test.tsx
Original file line number Diff line number Diff line change
@@ -1,47 +1,20 @@
import { createSelectorCreator, lruMemoize } from '@reduxjs/toolkit'
import {
buildCreateApi,
coreModule,
reactHooksModule,
} from '@reduxjs/toolkit/query/react'
import { render, screen, waitFor } from '@testing-library/react'
import { delay } from 'msw'
import * as React from 'react'
import type { ReactReduxContextValue } from 'react-redux'
import {
Provider,
createDispatchHook,
createSelectorHook,
createStoreHook,
Provider,
} from 'react-redux'
import {
buildCreateApi,
coreModule,
reactHooksModule,
} from '@reduxjs/toolkit/query/react'
import {
act,
fireEvent,
render,
screen,
waitFor,
renderHook,
} from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { rest } from 'msw'
import {
actionsReducer,
ANY,
expectExactType,
expectType,
setupApiStore,
withProvider,
useRenderCounter,
waitMs,
} from './helpers'
import { server } from './mocks/server'
import type { UnknownAction } from 'redux'
import type { SubscriptionOptions } from '@reduxjs/toolkit/dist/query/core/apiState'
import type { SerializedError } from '@reduxjs/toolkit'
import {
createListenerMiddleware,
configureStore,
lruMemoize,
createSelectorCreator,
} from '@reduxjs/toolkit'
import { delay } from '../../utils'
import { setupApiStore, useRenderCounter } from './helpers'

const MyContext = React.createContext<ReactReduxContextValue>(null as any)

Expand All @@ -60,7 +33,7 @@ describe('buildCreateApi', () => {

const api = customCreateApi({
baseQuery: async (arg: any) => {
await waitMs()
await delay(150)

return {
data: arg?.body ? { ...arg.body } : {},
Expand Down Expand Up @@ -140,7 +113,7 @@ describe('buildCreateApi', () => {
)
const api = createApi({
baseQuery: async (arg: any) => {
await waitMs()
await delay(150)

return {
data: arg?.body ? { ...arg.body } : {},
Expand Down
64 changes: 30 additions & 34 deletions packages/toolkit/src/query/tests/buildHooks.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,9 @@ import {
renderHook,
} from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { rest } from 'msw'
import { http, HttpResponse } from 'msw'
import {
actionsReducer,
ANY,
expectExactType,
expectType,
setupApiStore,
Expand Down Expand Up @@ -104,7 +103,7 @@ const api = createApi({
query: (update) => ({ body: update }),
}),
getError: build.query({
query: (query) => '/error',
query: () => '/error',
}),
listItems: build.query<Item[], { pageNumber: number }>({
serializeQueryArgs: ({ endpointName }) => {
Expand All @@ -119,7 +118,7 @@ const api = createApi({
merge: (currentCache, newItems) => {
currentCache.push(...newItems)
},
forceRefetch: ({ currentArg, previousArg }) => {
forceRefetch: () => {
return true
},
}),
Expand Down Expand Up @@ -757,7 +756,7 @@ describe('hooks tests', () => {
}

// 1) Initial state: an active subscription
const { result, rerender, unmount } = renderHook(
const { rerender, unmount } = renderHook(
([arg, options]: Parameters<
typeof pokemonApi.useGetPokemonByNameQuery
>) => pokemonApi.useGetPokemonByNameQuery(arg, options),
Expand Down Expand Up @@ -1752,14 +1751,14 @@ describe('hooks tests', () => {
test('initially failed useQueries that provide an tag will refetch after a mutation invalidates it', async () => {
const checkSessionData = { name: 'matt' }
server.use(
rest.get('https://example.com/me', (req, res, ctx) => {
return res.once(ctx.status(500))
http.get('https://example.com/me', () => {
return HttpResponse.json(null, { status: 500 })
}, { once: true }),
http.get('https://example.com/me', () => {
return HttpResponse.json(checkSessionData)
}),
rest.get('https://example.com/me', (req, res, ctx) => {
return res(ctx.json(checkSessionData))
}),
rest.post('https://example.com/login', (req, res, ctx) => {
return res(ctx.status(200))
http.post('https://example.com/login', () => {
return HttpResponse.json(null, { status: 200 })
})
)
let data, isLoading, isError
Expand Down Expand Up @@ -1977,47 +1976,49 @@ describe('hooks with createApi defaults set', () => {
posts = [...initialPosts]

const handlers = [
rest.get('https://example.com/posts', (req, res, ctx) => {
return res(ctx.json(posts))
http.get('https://example.com/posts', () => {
return HttpResponse.json(posts)
}),
rest.put<Partial<Post>>(
http.put<Post, Partial<Post>>(
'https://example.com/post/:id',
(req, res, ctx) => {
const id = Number(req.params.id)
async ({ request, params }) => {
const body = await request.json();
const id = Number(params.id)
const idx = posts.findIndex((post) => post.id === id)

const newPosts = posts.map((post, index) =>
index !== idx
? post
: {
...req.body,
...body,
id,
name: req.body.name || post.name,
name: body?.name || post.name,
fetched_at: new Date().toUTCString(),
}
)
posts = [...newPosts]

return res(ctx.json(posts))
return HttpResponse.json(posts)
}
),
rest.post('https://example.com/post', (req, res, ctx) => {
let post = req.body as Omit<Post, 'id'>
http.post<any, Omit<Post, 'id'>>('https://example.com/post', async ({ request }) => {
const body = await request.json();
let post = body
startingId += 1
posts.concat({
...post,
fetched_at: new Date().toISOString(),
id: startingId,
})
return res(ctx.json(posts))
return HttpResponse.json(posts)
}),
]

server.use(...handlers)
})

interface Post {
id: number
id: string
aryaemami59 marked this conversation as resolved.
Show resolved Hide resolved
name: string
fetched_at: string
}
Expand Down Expand Up @@ -2091,7 +2092,7 @@ describe('hooks with createApi defaults set', () => {
function SelectedPost() {
const { post } = api.endpoints.getPosts.useQueryState(undefined, {
selectFromResult: ({ data }) => ({
post: data?.find((post) => post.id === 1),
post: data?.find((post) => post.id === 1 as any),
}),
})
getRenderCount = useRenderCounter()
Expand Down Expand Up @@ -2170,7 +2171,7 @@ describe('hooks with createApi defaults set', () => {
isSuccess,
isError,
}) => ({
post: data?.find((post) => post.id === 1),
post: data?.find((post) => post.id === 1 as any),
isUninitialized,
isLoading,
isFetching,
Expand Down Expand Up @@ -2227,7 +2228,7 @@ describe('hooks with createApi defaults set', () => {
getRenderCount = useRenderCounter()
const { post } = api.endpoints.getPosts.useQuery(undefined, {
selectFromResult: ({ data }) => ({
post: data?.find((post) => post.id === 1),
post: data?.find((post) => post.id === 1 as any),
}),
})

Expand Down Expand Up @@ -2276,7 +2277,7 @@ describe('hooks with createApi defaults set', () => {
</button>
<button
data-testid="updatePost"
onClick={() => updatePost({ id: 1, name: 'supercoooll!' })}
onClick={() => updatePost({ id: 1, name: 'supercoooll!' } as any)}
>
Update post
</button>
Expand All @@ -2287,7 +2288,7 @@ describe('hooks with createApi defaults set', () => {
function SelectedPost() {
const { post } = api.endpoints.getPosts.useQuery(undefined, {
selectFromResult: ({ data }) => ({
post: data?.find((post) => post.id === 1),
post: data?.find((post) => post.id === 1 as any),
}),
})
getRenderCount = useRenderCounter()
Expand Down Expand Up @@ -2377,11 +2378,6 @@ describe('hooks with createApi defaults set', () => {

test('useQuery with selectFromResult option has a type error if the result is not an object', async () => {
function SelectedPost() {
const _res1 = api.endpoints.getPosts.useQuery(undefined, {
// selectFromResult must always return an object
// @ts-expect-error
selectFromResult: ({ data }) => data?.length ?? 0,
})

const res2 = api.endpoints.getPosts.useQuery(undefined, {
// selectFromResult must always return an object
Expand Down
7 changes: 4 additions & 3 deletions packages/toolkit/src/query/tests/buildMiddleware.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { createApi } from '@reduxjs/toolkit/query'
import { actionsReducer, setupApiStore, waitMs } from './helpers'
import { delay } from 'msw'
import { actionsReducer, setupApiStore } from './helpers'

const baseQuery = (args?: any) => ({ data: args })
const api = createApi({
Expand Down Expand Up @@ -43,7 +44,7 @@ it('invalidates the specified tags', async () => {
await storeRef.store.dispatch(api.util.invalidateTags(['Banana', 'Bread']))

// Slight pause to let the middleware run and such
await waitMs(20)
await delay(20)

const firstSequence = [
api.internalActions.middlewareRegistered.match,
Expand All @@ -58,7 +59,7 @@ it('invalidates the specified tags', async () => {
await storeRef.store.dispatch(getBread.initiate(1))
await storeRef.store.dispatch(api.util.invalidateTags([{ type: 'Bread' }]))

await waitMs(20)
await delay(20)

expect(storeRef.store.getState().actions).toMatchSequence(
...firstSequence,
Expand Down
2 changes: 1 addition & 1 deletion packages/toolkit/src/query/tests/buildSlice.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createSlice } from '@reduxjs/toolkit'
import { createApi } from '@reduxjs/toolkit/query'
import { delay } from 'msw'
import { setupApiStore } from './helpers'
import { delay } from '../../utils'

let shouldApiResponseSuccess = true

Expand Down