Skip to content

Commit

Permalink
refactor: use TestSWRConfig for error-test (#1404)
Browse files Browse the repository at this point in the history
  • Loading branch information
koba04 authored Sep 1, 2021
1 parent b819c25 commit 822f07d
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 34 deletions.
116 changes: 83 additions & 33 deletions test/use-swr-error.test.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
import { act, fireEvent, render, screen } from '@testing-library/react'
import React, { useEffect, useState } from 'react'
import useSWR, { mutate } from 'swr'
import { sleep, createResponse } from './utils'
import useSWR from 'swr'
import { sleep, createResponse, TestSWRConfig } from './utils'

describe('useSWR - error', () => {
it('should handle errors', async () => {
function Page() {
const { data, error } = useSWR('error-1', () =>
const { data, error } = useSWR('error-key', () =>
createResponse(new Error('error!'))
)
if (error) return <div>{error.message}</div>
return <div>hello, {data}</div>
}

render(<Page />)
render(
<TestSWRConfig>
<Page />
</TestSWRConfig>
)
screen.getByText('hello,')

// mount
Expand All @@ -24,27 +28,31 @@ describe('useSWR - error', () => {
let erroredSWR = null
function Page() {
const { data, error } = useSWR(
'error-2',
'error-key',
() => createResponse(new Error('error!')),
{ onError: (_, key) => (erroredSWR = key) }
)
if (error) return <div>{error.message}</div>
return <div>hello, {data}</div>
}

render(<Page />)
render(
<TestSWRConfig>
<Page />
</TestSWRConfig>
)
screen.getByText('hello,')

// mount
await screen.findByText('error!')
expect(erroredSWR).toEqual('error-2')
expect(erroredSWR).toEqual('error-key')
})

it('should trigger error retry', async () => {
let count = 0
function Page() {
const { data, error } = useSWR(
'error-3',
'error-key',
() => createResponse(new Error('error: ' + count++), { delay: 100 }),
{
onErrorRetry: (_, __, ___, revalidate, revalidateOpts) => {
Expand All @@ -57,7 +65,11 @@ describe('useSWR - error', () => {
return <div>hello, {data}</div>
}

render(<Page />)
render(
<TestSWRConfig>
<Page />
</TestSWRConfig>
)
screen.getByText('hello,')

// mount
Expand All @@ -75,7 +87,7 @@ describe('useSWR - error', () => {
success = null
function Page() {
const { data } = useSWR(
'error-4',
'error-key',
() => createResponse('SWR', { delay: 200 }),
{
onLoadingSlow: key => (loadingSlow = key),
Expand All @@ -86,23 +98,27 @@ describe('useSWR - error', () => {
return <div>hello, {data}</div>
}

render(<Page />)
render(
<TestSWRConfig>
<Page />
</TestSWRConfig>
)
screen.getByText('hello,')
expect(loadingSlow).toEqual(null)

await act(() => sleep(150)) // trigger onLoadingSlow event
expect(loadingSlow).toEqual('error-4')
expect(loadingSlow).toEqual('error-key')
expect(success).toEqual(null)

await act(() => sleep(150)) // finish the request
expect(success).toEqual('error-4')
expect(success).toEqual('error-key')
screen.getByText('hello, SWR')
})
it('should trigger limited error retries if errorRetryCount exists', async () => {
let count = 0
function Page() {
const { data, error } = useSWR(
'error-5',
'error-key',
() => createResponse(new Error('error: ' + count++)),
{
errorRetryCount: 1,
Expand All @@ -114,7 +130,11 @@ describe('useSWR - error', () => {
return <div>hello, {data}</div>
}

render(<Page />)
render(
<TestSWRConfig>
<Page />
</TestSWRConfig>
)
screen.getByText('hello,')

// mount
Expand All @@ -130,7 +150,7 @@ describe('useSWR - error', () => {
let loadingSlow = null,
success = null
function Page() {
const { data } = useSWR('error-6', () => createResponse('SWR'), {
const { data } = useSWR('error-key', () => createResponse('SWR'), {
onLoadingSlow: key => {
loadingSlow = key
},
Expand All @@ -151,7 +171,11 @@ describe('useSWR - error', () => {
)
}

render(<App />)
render(
<TestSWRConfig>
<App />
</TestSWRConfig>
)
screen.getByText('hello,')
expect(loadingSlow).toEqual(null)
expect(success).toEqual(null)
Expand All @@ -167,7 +191,7 @@ describe('useSWR - error', () => {
failed = null
function Page() {
const { data } = useSWR(
'error-7',
'error-key',
() => createResponse(new Error('error!')),
{
onError: (_, key) => {
Expand All @@ -191,7 +215,11 @@ describe('useSWR - error', () => {
)
}

render(<App />)
render(
<TestSWRConfig>
<App />
</TestSWRConfig>
)
screen.getByText('hello,')
expect(retry).toEqual(null)
expect(failed).toEqual(null)
Expand All @@ -206,7 +234,7 @@ describe('useSWR - error', () => {
let count = 0
function Page() {
const { data, error } = useSWR(
'error-8',
'error-key',
() => createResponse(new Error('error: ' + count++)),
{
errorRetryCount: 0,
Expand All @@ -218,7 +246,11 @@ describe('useSWR - error', () => {
return <div>hello, {data}</div>
}

render(<Page />)
render(
<TestSWRConfig>
<Page />
</TestSWRConfig>
)
screen.getByText('hello,')

// mount
Expand All @@ -230,34 +262,44 @@ describe('useSWR - error', () => {

it('should not clear error during revalidating until fetcher is finished successfully', async () => {
const errors = []
const key = 'error-9'
const key = 'error-key'
let mutate
function Page() {
const { error } = useSWR(key, () => createResponse(new Error('error')), {
errorRetryCount: 0,
errorRetryInterval: 0,
dedupingInterval: 0
})
const { error, mutate: _mutate } = useSWR(
key,
() => createResponse(new Error('error')),
{
errorRetryCount: 0,
errorRetryInterval: 0,
dedupingInterval: 0
}
)
mutate = _mutate
useEffect(() => {
errors.push(error ? error.message : null)
}, [error])

return <div>hello, {error ? error.message : null}</div>
}

render(<Page />)
render(
<TestSWRConfig>
<Page />
</TestSWRConfig>
)

// mount
await screen.findByText('hello, error')

await act(() => mutate(key, undefined, true))
await act(() => mutate(undefined, true))
// initial -> first error -> mutate -> receive another error
// error won't be cleared during revalidation
expect(errors).toEqual([null, 'error', 'error'])
})

it('should reset isValidating when an error occured synchronously', async () => {
function Page() {
const { error, isValidating } = useSWR('error-10', () => {
const { error, isValidating } = useSWR('error-key', () => {
throw new Error('error!')
})
if (error)
Expand All @@ -269,13 +311,17 @@ describe('useSWR - error', () => {
return <div>hello,{isValidating.toString()}</div>
}

render(<Page />)
render(
<TestSWRConfig>
<Page />
</TestSWRConfig>
)
screen.getByText('error!,false')
})

it('should reset isValidating when an error occured asynchronously', async () => {
function Page() {
const { error, isValidating } = useSWR('error-11', () =>
const { error, isValidating } = useSWR('error-key', () =>
createResponse(new Error('error!'))
)
if (error)
Expand All @@ -287,7 +333,11 @@ describe('useSWR - error', () => {
return <div>hello,{isValidating.toString()}</div>
}

render(<Page />)
render(
<TestSWRConfig>
<Page />
</TestSWRConfig>
)
screen.getByText('hello,true')

await screen.findByText('error!,false')
Expand Down
16 changes: 15 additions & 1 deletion test/utils.ts → test/utils.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { act, fireEvent } from '@testing-library/react'
import React from 'react'
import { SWRConfiguration, SWRConfig } from 'swr'

export function sleep(time: number) {
return new Promise(resolve => setTimeout(resolve, time))
}

export const createResponse = <T = any>(
export const createResponse = <T extends any>(
response: T,
{ delay } = { delay: 10 }
): Promise<T> =>
Expand All @@ -26,3 +28,15 @@ export const focusOn = (element: any) =>
})

export const createKey = () => 'swr-key-' + ~~(Math.random() * 1e7)

export const TestSWRConfig = ({
children,
value
}: {
children: React.ReactNode
value?: SWRConfiguration
}) => (
<SWRConfig value={{ provider: () => new Map(), ...value }}>
{children}
</SWRConfig>
)

0 comments on commit 822f07d

Please sign in to comment.