diff --git a/test/use-swr-key.test.tsx b/test/use-swr-key.test.tsx index e3c40f970..208612444 100644 --- a/test/use-swr-key.test.tsx +++ b/test/use-swr-key.test.tsx @@ -1,15 +1,16 @@ -import { act, fireEvent, render, screen } from '@testing-library/react' +import { act, fireEvent, screen } from '@testing-library/react' import React, { useState, useEffect } from 'react' import useSWR from 'swr' -import { createResponse, sleep } from './utils' +import { createKey, createResponse, renderWithConfig, sleep } from './utils' describe('useSWR - key', () => { it('should respect requests after key has changed', async () => { let rerender + const baseKey = createKey() function Page() { const [mounted, setMounted] = useState(0) - const key = `key-1-${mounted ? 'short' : 'long'}` + const key = `${baseKey}-${mounted ? 'short' : 'long'}` const { data } = useSWR(key, () => { if (mounted) { return createResponse('short request', { delay: 50 }) @@ -22,7 +23,7 @@ describe('useSWR - key', () => { return
data:{data}
} - render() + renderWithConfig() screen.getByText('data:') await screen.findByText('data:short request') @@ -38,9 +39,10 @@ describe('useSWR - key', () => { }) it('should render undefined after key has changed', async () => { + const baseKey = createKey() function Page() { const [mounted, setMounted] = useState(false) - const key = `key-${mounted ? '1' : '0'}` + const key = `${baseKey}-${mounted ? '1' : '0'}` const { data } = useSWR(key, k => createResponse(k, { delay: 100 })) useEffect(() => { setTimeout(() => setMounted(true), 200) @@ -53,14 +55,14 @@ describe('useSWR - key', () => { // -> 100 0, '0' // -> 200 undefined, '1' <- this state is required; we can't show 0 here // -> 300 1, '1' - render() + renderWithConfig() screen.getByText('data:') // undefined, time=0 await act(() => sleep(150)) - screen.getByText('data:key-0') // 0, time=150 + screen.getByText(`data:${baseKey}-0`) // 0, time=150 await act(() => sleep(100)) screen.getByText('data:') // undefined, time=250 await act(() => sleep(100)) - screen.getByText('data:key-1') // 1, time=350 + screen.getByText(`data:${baseKey}-1`) // 1, time=350 }) it('should return undefined after key change when fetcher is synchronized', async () => { @@ -70,11 +72,12 @@ describe('useSWR - key', () => { '3': 'c' } + const baseKey = createKey() function Page() { const [sampleKey, setKey] = React.useState(1) const { data } = useSWR( - `key-2-${sampleKey}`, - key => samples[key.replace('key-2-', '')] + `${baseKey}-${sampleKey}`, + key => samples[key.replace(`${baseKey}-`, '')] ) return (
{ ) } - render() + renderWithConfig() screen.getByText('hello, 1:') await screen.findByText('hello, 1:a') @@ -102,9 +105,10 @@ describe('useSWR - key', () => { it('should revalidate if a function key changes identity', async () => { const closureFunctions: { [key: string]: () => Promise } = {} + const baseKey = createKey() const closureFactory = id => { if (closureFunctions[id]) return closureFunctions[id] - closureFunctions[id] = () => Promise.resolve(`data-${id}`) + closureFunctions[id] = () => Promise.resolve(`${baseKey}-${id}`) return closureFunctions[id] } @@ -121,28 +125,28 @@ describe('useSWR - key', () => { return
{data}
} - render() + renderWithConfig() const closureSpy = jest.spyOn(closureFunctions, 'first') - await screen.findByText('data-first') + await screen.findByText(`${baseKey}-first`) expect(closureSpy).toHaveBeenCalledTimes(1) // update, but don't change the id. // Function identity should stay the same, and useSWR should not call the function again. act(() => updateId('first')) - await screen.findByText('data-first') + await screen.findByText(`${baseKey}-first`) expect(closureSpy).toHaveBeenCalledTimes(1) act(() => updateId('second')) - await screen.findByText('data-second') + await screen.findByText(`${baseKey}-second`) }) it('should cleanup state when key turns to empty', async () => { + const key = createKey() function Page() { const [cnt, setCnt] = useState(1) - const { isValidating } = useSWR( - cnt === -1 ? '' : `key-empty-${cnt}`, - () => createResponse('', { delay: 100 }) + const { isValidating } = useSWR(cnt === -1 ? '' : `${key}-${cnt}`, () => + createResponse('', { delay: 100 }) ) return ( @@ -152,7 +156,7 @@ describe('useSWR - key', () => { ) } - render() + renderWithConfig() screen.getByText('true') fireEvent.click(screen.getByText('true')) @@ -168,6 +172,7 @@ describe('useSWR - key', () => { const fetcher = () => createResponse('test', { delay: 100 }) const values = [] + const updatedKey = createKey() function Page() { const [key, setKey] = useState(null) @@ -176,10 +181,10 @@ describe('useSWR - key', () => { values.push([v1, v2]) - return + return } - render() + renderWithConfig() screen.getByText('update key') fireEvent.click(screen.getByText('update key')) @@ -202,7 +207,7 @@ describe('useSWR - key', () => { ) } - render() + renderWithConfig() await screen.findByText('data,data') // Only 1 request since the keys are the same. diff --git a/test/use-swr-middlewares.test.tsx b/test/use-swr-middlewares.test.tsx index 6a0fa6ae6..5899b104c 100644 --- a/test/use-swr-middlewares.test.tsx +++ b/test/use-swr-middlewares.test.tsx @@ -1,9 +1,15 @@ -import { act, render, screen } from '@testing-library/react' +import { act, screen } from '@testing-library/react' import React, { useState, useEffect, useRef } from 'react' import useSWR, { Middleware, SWRConfig } from 'swr' import { withMiddleware } from '../src/utils/with-middleware' -import { createResponse, sleep, createKey, nextTick } from './utils' +import { + createResponse, + sleep, + createKey, + nextTick, + renderWithConfig +} from './utils' describe('useSWR - middleware', () => { it('should use middleware', async () => { @@ -20,7 +26,7 @@ describe('useSWR - middleware', () => { return
hello, {data}
} - render() + renderWithConfig() screen.getByText('hello,') await screen.findByText('hello, data') expect(mockConsoleLog.mock.calls[0][0]).toBe(key) @@ -42,7 +48,7 @@ describe('useSWR - middleware', () => { return
hello, {data}
} - render() + renderWithConfig() screen.getByText('hello,') await screen.findByText('hello, data') expect(mockConsoleLog.mock.calls[0][0]).toEqual([key, 1, 2, 3]) @@ -62,11 +68,7 @@ describe('useSWR - middleware', () => { return
hello, {data}
} - render( - - - - ) + renderWithConfig(, { use: [loggerMiddleware] }) screen.getByText('hello,') await screen.findByText('hello, data') expect(mockConsoleLog.mock.calls[0][0]).toBe(key) @@ -91,7 +93,7 @@ describe('useSWR - middleware', () => { return
hello, {data}
} - render( + renderWithConfig( @@ -138,11 +140,7 @@ describe('useSWR - middleware', () => { return
hello, {data}
} - render( - - - - ) + renderWithConfig(, { use: [createLoggerMiddleware(2)] }) screen.getByText('hello,') await screen.findByText('hello, data') expect(mockConsoleLog.mock.calls.map(call => call[0])).toEqual([ @@ -184,11 +182,7 @@ describe('useSWR - middleware', () => { return
data:{data}
} - render( - - - - ) + renderWithConfig(, { use: [lazyMiddleware] }) screen.getByText('data:') // undefined, time=0 await act(() => sleep(150)) @@ -217,7 +211,7 @@ describe('useSWR - middleware', () => { return
hello, {data}
} - render() + renderWithConfig() screen.getByText('hello,') await screen.findByText(`hello, #!${key}!#`) }) @@ -244,7 +238,7 @@ describe('useSWR - middleware', () => { return
hello, {data || ''}
} - render() + renderWithConfig() screen.getByText('hello,') await nextTick() diff --git a/test/use-swr-suspense.test.tsx b/test/use-swr-suspense.test.tsx index a5ddc977c..d238a0462 100644 --- a/test/use-swr-suspense.test.tsx +++ b/test/use-swr-suspense.test.tsx @@ -1,7 +1,13 @@ -import { act, fireEvent, render, screen } from '@testing-library/react' +import { act, fireEvent, screen } from '@testing-library/react' import React, { ReactNode, Suspense, useEffect, useState } from 'react' import useSWR, { mutate } from 'swr' -import { createResponse, sleep } from './utils' +import { + createKey, + createResponse, + renderWithConfig, + renderWithGlobalCache, + sleep +} from './utils' class ErrorBoundary extends React.Component<{ fallback: ReactNode }> { state = { hasError: false } @@ -25,14 +31,15 @@ describe('useSWR - suspense', () => { }) it('should render fallback', async () => { + const key = createKey() function Section() { - const { data } = useSWR('suspense-1', () => createResponse('SWR'), { + const { data } = useSWR(key, () => createResponse('SWR'), { suspense: true }) return
{data}
} - render( + renderWithConfig( fallback
}>
@@ -44,9 +51,10 @@ describe('useSWR - suspense', () => { }) it('should render multiple SWR fallbacks', async () => { + const key = createKey() function Section() { const { data: v1 } = useSWR( - 'suspense-2', + key, () => createResponse(1, { delay: 50 }), { suspense: true @@ -62,7 +70,7 @@ describe('useSWR - suspense', () => { return
{v1 + v2}
} - render( + renderWithConfig( fallback}>
@@ -77,13 +85,14 @@ describe('useSWR - suspense', () => { }) it('should work for non-promises', async () => { + const key = createKey() function Section() { - const { data } = useSWR('suspense-4', () => 'hello', { + const { data } = useSWR(key, () => 'hello', { suspense: true }) return
{data}
} - render( + renderWithConfig( fallback}>
@@ -94,19 +103,16 @@ describe('useSWR - suspense', () => { it('should throw errors', async () => { // eslint-disable-next-line @typescript-eslint/no-empty-function jest.spyOn(console, 'error').mockImplementation(() => {}) + const key = createKey() function Section() { - const { data } = useSWR( - 'suspense-5', - () => createResponse(new Error('error')), - { - suspense: true - } - ) + const { data } = useSWR(key, () => createResponse(new Error('error')), { + suspense: true + }) return
{data}
} // https://reactjs.org/docs/concurrent-mode-suspense.html#handling-errors - render( + renderWithConfig( error boundary}> fallback}>
@@ -122,12 +128,13 @@ describe('useSWR - suspense', () => { }) it('should render cached data with error', async () => { - mutate('suspense-6', 'hello') + const key = createKey() + mutate(key, 'hello') function Section() { const { data, error } = useSWR( // this value is cached - 'suspense-6', + key, () => createResponse(new Error('error')), { suspense: true @@ -140,7 +147,7 @@ describe('useSWR - suspense', () => { ) } - render( + renderWithGlobalCache( fallback}>
@@ -152,15 +159,17 @@ describe('useSWR - suspense', () => { it('should pause when key changes', async () => { const renderedResults = [] + const initialKey = createKey() + const updatedKey = createKey() function Section() { - const [key, setKey] = useState('suspense-7') + const [key, setKey] = useState(initialKey) const { data } = useSWR(key, k => createResponse(k), { suspense: true }) useEffect(() => { - if (data === 'suspense-7') { - setKey('suspense-8') + if (data === initialKey) { + setKey(updatedKey) } }, [data]) @@ -171,33 +180,38 @@ describe('useSWR - suspense', () => { return <>{data} } - render( + renderWithConfig( fallback}>
) - await screen.findByText('suspense-8') + await screen.findByText(updatedKey) // fixes https://github.com/zeit/swr/issues/57 - // 'suspense-7' -> undefined -> 'suspense-8' - expect(renderedResults).toEqual(['suspense-7', 'suspense-8']) + // initialKey' -> undefined -> updatedKey + expect(renderedResults).toEqual([initialKey, updatedKey]) }) it('should render correctly when key changes (but with same response data)', async () => { // https://github.com/vercel/swr/issues/1056 const renderedResults = [] + const baseKey = createKey() function Section() { const [key, setKey] = useState(1) - const { data } = useSWR(`foo?a=${key}`, () => createResponse('123'), { - suspense: true - }) + const { data } = useSWR( + `${baseKey}-${key}`, + () => createResponse('123'), + { + suspense: true + } + ) if (`${data},${key}` !== renderedResults[renderedResults.length - 1]) { renderedResults.push(`${data},${key}`) } return
setKey(v => v + 1)}>{`${data},${key}`}
} - render( + renderWithConfig( fallback}>
@@ -215,15 +229,16 @@ describe('useSWR - suspense', () => { it('should render initial data if set', async () => { const fetcher = jest.fn(() => 'SWR') + const key = createKey() function Page() { - const { data } = useSWR('suspense-9', fetcher, { + const { data } = useSWR(key, fetcher, { fallbackData: 'Initial', suspense: true }) return
hello, {data}
} - render( + renderWithConfig( fallback}> @@ -236,16 +251,17 @@ describe('useSWR - suspense', () => { it('should avoid unnecessary re-renders', async () => { let renderCount = 0 let startRenderCount = 0 + const key = createKey() function Section() { ++startRenderCount - const { data } = useSWR('suspense-10', () => createResponse('SWR'), { + const { data } = useSWR(key, () => createResponse('SWR'), { suspense: true }) ++renderCount return
{data}
} - render( + renderWithConfig( fallback}>