Skip to content

Commit

Permalink
refactor tests
Browse files Browse the repository at this point in the history
  • Loading branch information
dai-shi committed Oct 23, 2023
1 parent 9e10342 commit 0d82733
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 63 deletions.
121 changes: 63 additions & 58 deletions tests/react/async2.test.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { StrictMode, Suspense } from 'react'
import { act, fireEvent, render, waitFor } from '@testing-library/react'
import { fireEvent, render, waitFor } from '@testing-library/react'
import { assert, describe, expect, it } from 'vitest'
import { Provider, useAtom, useAtomValue, useSetAtom } from 'jotai/react'
import { SetStateAction, atom, createStore } from 'jotai/vanilla'
import { useAtom, useAtomValue, useSetAtom } from 'jotai/react'
import { atom } from 'jotai/vanilla'

describe('useAtom delay option test', () => {
it('suspend for Promise.resovle without delay option', async () => {
Expand Down Expand Up @@ -142,71 +142,76 @@ describe('atom read function setSelf option test', () => {
})
})

it('resolves dependencies reliably after a delay', async () => {
expect.assertions(1)
const countAtom = atom(0)

let result: number | null = null
const resolve: (() => void)[] = []
const asyncAtom = atom(async (get) => {
const count = get(countAtom)
await new Promise<void>((r: { (): void; count?: number }) => {
r.count = count
resolve.push(r)
describe('timing issue with setSelf', () => {
it('resolves dependencies reliably after a delay (#2192)', async () => {
expect.assertions(1)
const countAtom = atom(0)

let result: number | null = null
const resolve: (() => void)[] = []
const asyncAtom = atom(async (get) => {
const count = get(countAtom)
await new Promise<void>((r) => resolve.push(r))
return count
})
return count
})

const derivedAtom = atom(
async (get, { setSelf }) => {
get(countAtom)
await Promise.resolve()
const resultCount = await get(asyncAtom)
result = resultCount
if (resultCount === 2) setSelf() // <-- necessary
},
() => {}
)

const derivedSyncAtom = atom((get) => {
get(derivedAtom)
})
const derivedAtom = atom(
async (get, { setSelf }) => {
get(countAtom)
await Promise.resolve()
const resultCount = await get(asyncAtom)
result = resultCount
if (resultCount === 2) setSelf() // <-- necessary
},
() => {}
)

function useTest() {
useAtom(derivedSyncAtom)
useAtom(countAtom)
}
function TestComponent() {
useTest()
return null
}
const store = createStore()
const derivedSyncAtom = atom((get) => {
get(derivedAtom)
})

const Wrapper = ({ children }: React.PropsWithChildren) => (
<Provider store={store}>{children}</Provider>
)
render(<TestComponent />, { wrapper: Wrapper })
const increment = (c: number) => c + 1
function TestComponent() {
useAtom(derivedSyncAtom)
const [count, setCount] = useAtom(countAtom)
const onClick = () => {
setCount(increment)
setCount(increment)
}
return (
<>
count: {count}
<button onClick={onClick}>button</button>
</>
)
}

const setCount = (arg: SetStateAction<number>) => store.set(countAtom, arg)
const increment = (c: number) => c + 1
await waitFor(() => assert(resolve.length === 1))
const { getByText, findByText } = render(
<StrictMode>
<TestComponent />
</StrictMode>
)

resolve[0]!()
await waitFor(() => assert(resolve.length === 1))
resolve[0]!()

await act(() => setCount(increment))
await act(() => setCount(increment))
// The use of fireEvent is required to reproduce the issue
fireEvent.click(getByText('button'))

resolve[1]!()
resolve[2]!()
await waitFor(() => assert(resolve.length === 3))
resolve[1]!()
resolve[2]!()

await waitFor(() => assert(result === 2))
await waitFor(() => assert(result === 2))

await act(() => setCount(increment))
await act(() => setCount(increment))
// The use of fireEvent is required to reproduce the issue
fireEvent.click(getByText('button'))

resolve[3]!()
resolve[4]!()
await waitFor(() => assert(resolve.length === 5))
resolve[3]!()
resolve[4]!()

await waitFor(() => assert(store.get(countAtom) === 4))
expect(result).toBe(4) // 3
await findByText('count: 4')
expect(result).toBe(4) // 3
})
})
7 changes: 2 additions & 5 deletions tests/vanilla/store.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -425,18 +425,15 @@ it('should update derived atoms during write (#2107)', async () => {
expect(store.get(countAtom)).toBe(2)
})

it.only('resolves dependencies reliably after a delay', async () => {
it('resolves dependencies reliably after a delay (#2192)', async () => {
expect.assertions(1)
const countAtom = atom(0)
let result: number | null = null

const resolve: (() => void)[] = []
const asyncAtom = atom(async (get) => {
const count = get(countAtom)
await new Promise<void>((r: { (): void; count?: number }) => {
r.count = count
resolve.push(r)
})
await new Promise<void>((r) => resolve.push(r))
return count
})

Expand Down

0 comments on commit 0d82733

Please sign in to comment.