Skip to content

Commit

Permalink
test: refactor use-swr-integration.test.tsx (#1049)
Browse files Browse the repository at this point in the history
  • Loading branch information
koba04 committed Mar 18, 2021
1 parent 7f490c1 commit a64cd2c
Showing 1 changed file with 63 additions and 77 deletions.
140 changes: 63 additions & 77 deletions test/use-swr-integration.test.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import { act, render, screen, fireEvent } from '@testing-library/react'
import React, { useState, useEffect } from 'react'
import useSWR from '../src'
import { sleep } from './utils'
import { createResponse, sleep } from './utils'

const waitForNextTick = () => act(() => sleep(1))

describe('useSWR', () => {
it('should return `undefined` on hydration then return data', async () => {
function Page() {
const { data } = useSWR('constant-2', () => 'SWR')
return <div>hello, {data}</div>
}
const { container } = render(<Page />)

render(<Page />)
// hydration
expect(container.firstChild.textContent).toMatchInlineSnapshot(`"hello, "`)
screen.getByText('hello,')

// mounted
await screen.findByText('hello, SWR')
Expand All @@ -23,29 +25,24 @@ describe('useSWR', () => {
const { data } = useSWR(() => 'constant-2', () => 'SWR')
return <div>hello, {data}</div>
}
const { container } = render(<Page />)

expect(container.firstChild.textContent).toMatchInlineSnapshot(
`"hello, SWR"`
)
render(<Page />)
screen.getByText('hello, SWR')
})

it('should allow async fetcher functions', async () => {
const fetcher = jest.fn(
() => new Promise(res => setTimeout(() => res('SWR'), 200))
)
const fetcher = jest.fn(() => createResponse('SWR'))
function Page() {
const { data } = useSWR('constant-3', fetcher)
return <div>hello, {data}</div>
}
const { container } = render(<Page />)

render(<Page />)
// hydration
expect(container.firstChild.textContent).toMatchInlineSnapshot(`"hello, "`)
screen.getByText('hello,')

await act(() => sleep(210))
expect(fetcher).toBeCalledTimes(1)
await screen.findByText('hello, SWR')
expect(fetcher).toBeCalledTimes(1)
})

it('should not call fetch function when revalidateOnMount is false', async () => {
Expand Down Expand Up @@ -75,20 +72,15 @@ describe('useSWR', () => {
return <div>hello, {data}</div>
}

const { container } = render(<Page />)

expect(container.firstChild.textContent).toMatchInlineSnapshot(
`"hello, gab"`
)
render(<Page />)
screen.getByText('hello, gab')

await screen.findByText('hello, SWR')
expect(fetch).toHaveBeenCalled()
})

it('should dedupe requests by default', async () => {
const fetcher = jest.fn(
() => new Promise(res => setTimeout(() => res('SWR'), 200))
)
const fetcher = jest.fn(() => createResponse('SWR'))

function Page() {
const { data: v1 } = useSWR('constant-4', fetcher)
Expand All @@ -99,36 +91,27 @@ describe('useSWR', () => {
</div>
)
}
const { container } = render(<Page />)

expect(container.firstChild.textContent).toMatchInlineSnapshot(`", "`)

await act(() => sleep(210))
render(<Page />)
screen.getByText(',')

await screen.findByText('SWR, SWR')
expect(fetcher).toBeCalledTimes(1)

expect(container.firstChild.textContent).toMatchInlineSnapshot(`"SWR, SWR"`)
})

it('should trigger the onSuccess event', async () => {
let SWRData = null
function Page() {
const { data } = useSWR(
'constant-5',
() => new Promise(res => setTimeout(() => res('SWR'), 200)),
{ onSuccess: _data => (SWRData = _data) }
)
const { data } = useSWR('constant-5', () => createResponse('SWR'), {
onSuccess: _data => (SWRData = _data)
})
return <div>hello, {data}</div>
}
const { container } = render(<Page />)

expect(container.firstChild.textContent).toMatchInlineSnapshot(`"hello, "`)

await act(() => sleep(210))
render(<Page />)
screen.getByText('hello,')

expect(container.firstChild.textContent).toMatchInlineSnapshot(
`"hello, SWR"`
)
await screen.findByText('hello, SWR')
expect(SWRData).toEqual('SWR')
})

Expand All @@ -151,13 +134,17 @@ describe('useSWR', () => {
</>
)
}
const { container } = render(<Page />)
await act(() => sleep(10))
expect(container.textContent).toMatchInlineSnapshot(`"0 0 0"`)

render(<Page />)

await act(() => sleep(50))
screen.getByText('0 0 0')

await act(() => sleep(100))
expect(container.textContent).toMatchInlineSnapshot(`"1 1 1"`)
screen.getByText('1 1 1')

await act(() => sleep(100))
expect(container.textContent).toMatchInlineSnapshot(`"2 2 2"`)
screen.getByText('2 2 2')
})

it('should broadcast error', async () => {
Expand Down Expand Up @@ -187,13 +174,17 @@ describe('useSWR', () => {
</>
)
}
const { container } = render(<Page />)
await act(() => sleep(10))
expect(container.textContent).toMatchInlineSnapshot(`"0 0 0"`)

render(<Page />)

await act(() => sleep(50))
screen.getByText('0 0 0')

await act(() => sleep(100))
expect(container.textContent).toMatchInlineSnapshot(`"1 1 1"`)
screen.getByText('1 1 1')

await act(() => sleep(100))
expect(container.textContent).toMatchInlineSnapshot(`"err err err"`)
screen.getByText('err err err')
})

it('should broadcast isValidating', async () => {
Expand Down Expand Up @@ -232,14 +223,18 @@ describe('useSWR', () => {
</>
)
}
const { container } = render(<Page />)
expect(container.textContent).toMatchInlineSnapshot(`"true true true"`)
await act(() => sleep(100))
expect(container.textContent).toMatchInlineSnapshot(`"false false false"`)

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

await act(() => sleep(150))
screen.getByText('false false false')

await act(() => sleep(100))
expect(container.textContent).toMatchInlineSnapshot(`"true true true"`)
screen.getByText('true true true')

await act(() => sleep(100))
expect(container.textContent).toMatchInlineSnapshot(`"false false false"`)
screen.getByText('false false false')
})

it('should accept object args', async () => {
Expand Down Expand Up @@ -303,19 +298,14 @@ describe('useSWR', () => {
return <div>hello, {data}</div>
}

const { container } = render(<Page />)
render(<Page />)

await screen.findByText('hello, Initial')
expect(fetcher).not.toBeCalled()
expect(container.firstChild.textContent).toMatchInlineSnapshot(
`"hello, Initial"`
)
})

it('should revalidate even if initialData is provided', async () => {
const fetcher = async key => {
await sleep(50)
return key
}
const fetcher = key => createResponse(key, { delay: 50 })

function Page() {
const [key, setKey] = useState('initial-data-with-initial-data')
Expand All @@ -329,27 +319,25 @@ describe('useSWR', () => {
)
}

const { container } = render(<Page />)
render(<Page />)

// render with the initial data
await screen.findByText('hello, Initial')

await act(() => sleep(1))
await waitForNextTick()
fireEvent.focus(window)

await screen.findByText('hello, initial-data-with-initial-data')

// change the key
await act(() => sleep(1))
fireEvent.click(container.firstElementChild)
await waitForNextTick()
fireEvent.click(screen.getByText('hello, initial-data-with-initial-data'))

// a request is still in flight
await act(() => sleep(10))
// while validating, SWR returns the initialData
// https://github.com/vercel/swr/pull/961/files#r588928241
expect(container.firstChild.textContent).toMatchInlineSnapshot(
`"hello, Initial"`
)
screen.getByText('hello, Initial')

// render with data the fetcher returns
await screen.findByText('hello, initial-data-with-initial-data-update')
Expand All @@ -366,9 +354,8 @@ describe('useSWR', () => {
return <div>hello, {data}</div>
}

const { container } = render(<Page />)

expect(container.firstChild.textContent).toMatchInlineSnapshot(`"hello, "`)
render(<Page />)
screen.getByText('hello,')
expect(fetcher).toBeCalled()

await screen.findByText('hello, SWR')
Expand All @@ -389,9 +376,8 @@ describe('useSWR', () => {
return <div>hello, {data && data.map(u => u.name).join(' and ')}</div>
}

const { container } = render(<Users />)

expect(container.firstChild.textContent).toMatchInlineSnapshot(`"hello, "`)
render(<Users />)
screen.getByText('hello,')
expect(fn).toBeCalled()

await screen.findByText('hello, bob and sue')
Expand Down

0 comments on commit a64cd2c

Please sign in to comment.