Skip to content

Commit 348ad75

Browse files
Pinpickledai-shi
authored andcommitted
add more test
1 parent d5e955f commit 348ad75

1 file changed

Lines changed: 66 additions & 2 deletions

File tree

tests/utils/loadable.test.tsx

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { Suspense, useEffect } from 'react'
12
import { fireEvent, render } from '@testing-library/react'
23
import { Atom, atom } from 'jotai'
34
import { loadable, useAtomValue, useUpdateAtom } from 'jotai/utils'
@@ -130,13 +131,76 @@ it('loadable can recover from error', async () => {
130131
await findByText('Data: 6')
131132
})
132133

134+
it('loadable immediately resolves sync values', async () => {
135+
const syncAtom = atom(5)
136+
const effectCallback = jest.fn()
137+
138+
const { getByText } = render(
139+
<Provider>
140+
<LoadableComponent effectCallback={effectCallback} asyncAtom={syncAtom} />
141+
</Provider>
142+
)
143+
144+
getByText('Data: 5')
145+
expect(effectCallback.mock.calls).not.toContain(
146+
expect.objectContaining({ state: 'loading' })
147+
)
148+
expect(effectCallback).toHaveBeenLastCalledWith({ state: 'hasData', data: 5 })
149+
})
150+
151+
it('loadable can use resolved promises syncronously', async () => {
152+
const asyncAtom = atom(Promise.resolve(5))
153+
const effectCallback = jest.fn()
154+
155+
const ResolveAtomComponent = () => {
156+
useAtomValue(asyncAtom)
157+
158+
return <div>Ready</div>
159+
}
160+
161+
const { getByText, findByText, rerender } = render(
162+
<Provider>
163+
<Suspense fallback={null}>
164+
<ResolveAtomComponent />
165+
</Suspense>
166+
</Provider>
167+
)
168+
169+
await findByText('Ready')
170+
171+
rerender(
172+
<Provider>
173+
<LoadableComponent
174+
effectCallback={effectCallback}
175+
asyncAtom={asyncAtom}
176+
/>
177+
</Provider>
178+
)
179+
getByText('Data: 5')
180+
181+
expect(effectCallback.mock.calls).not.toContain(
182+
expect.objectContaining({ state: 'loading' })
183+
)
184+
expect(effectCallback).toHaveBeenLastCalledWith({ state: 'hasData', data: 5 })
185+
})
186+
133187
interface LoadableComponentProps {
134-
asyncAtom: Atom<Promise<number> | Promise<string>>
188+
asyncAtom: Atom<Promise<number> | Promise<string> | string | number>
189+
effectCallback?: (loadableValue: any) => void
135190
}
136191

137-
const LoadableComponent = ({ asyncAtom }: LoadableComponentProps) => {
192+
const LoadableComponent = ({
193+
asyncAtom,
194+
effectCallback,
195+
}: LoadableComponentProps) => {
138196
const value = useAtomValue(loadable(asyncAtom))
139197

198+
useEffect(() => {
199+
if (effectCallback) {
200+
effectCallback(value)
201+
}
202+
}, [value, effectCallback])
203+
140204
if (value.state === 'loading') {
141205
return <>Loading...</>
142206
}

0 commit comments

Comments
 (0)