Skip to content

Commit ef93302

Browse files
committed
test: render multiple components on loaded data
1 parent 2f22c3c commit ef93302

File tree

3 files changed

+54
-2
lines changed

3 files changed

+54
-2
lines changed

test/methods/_.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import { clear, createStore, setMany } from 'idb-keyval';
22
import { createApi } from '../../src/methods';
33
import { cachedObj, reactCache, reactCacheEntry } from '../../src/shared';
44

5-
export async function setupApi({cacheEntries, cacheObjects, cacheValues, idbObjects, idbValues}: {
5+
export async function setupApi({cache: reactCache, cacheEntries, cacheObjects, cacheValues, idbObjects, idbValues}: {
6+
cache?: reactCache,
67
cacheEntries?: Record<string, reactCacheEntry>,
78
cacheObjects?: Record<string, cachedObj>,
89
cacheValues?: Record<string, unknown>,
@@ -14,7 +15,7 @@ export async function setupApi({cacheEntries, cacheObjects, cacheValues, idbObje
1415
rerender: jest.Mock<() => void>,
1516
api: ReturnType<typeof createApi>,
1617
}> {
17-
const cache: reactCache = {}
18+
const cache: reactCache = reactCache ?? {}
1819
Object.entries(cacheEntries ?? {}).forEach(([key, entry]) => {
1920
cache[key] = entry
2021
})

test/methods/get.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { waitFor } from '@testing-library/react'
12
import { setupApi } from './_'
23

34
it('get value from cache', async () => {
@@ -152,3 +153,24 @@ it('skip fetching object when a promise is pending', async () => {
152153
await new Promise(r => setTimeout(r, 1))
153154
expect(loader).toBeCalledTimes(2)
154155
})
156+
157+
it('rerender when pending promise is resolved', async () => {
158+
const compA = await setupApi()
159+
const compB = await setupApi({cache: compA.cache})
160+
let resolveLoader: () => void = () => { return }
161+
const loader = jest.fn(() => new Promise<void>(r => { resolveLoader = r }))
162+
163+
expect(compA.api.get('foo', loader)).toBe(undefined)
164+
expect(compB.api.get('foo', loader)).toBe(undefined)
165+
166+
await waitFor(() => expect(resolveLoader).toBeTruthy())
167+
expect(loader).toHaveBeenCalledTimes(1)
168+
169+
resolveLoader()
170+
await new Promise(r => setTimeout(r, 1))
171+
172+
expect(compA.rerender).toBeCalledTimes(1)
173+
expect(compA.api.get('foo')).toBe('foo')
174+
expect(compB.rerender).toBeCalledTimes(1)
175+
expect(compB.api.get('foo')).toBe('foo')
176+
})

test/useCached.tsx

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,32 @@ it('rerender component on updated cache', async () => {
109109
expect(render).toReturnTimes(2)
110110
expect(render).toHaveNthReturnedWith(2, 'bar')
111111
})
112+
113+
it('rerender multiple components waiting for the same value', async () => {
114+
let loadingResolve: (() => void) | undefined = undefined
115+
const loading = jest.fn((api: ReturnType<typeof useCached>) => new Promise<void>(res => {
116+
api.set('foo', 'bar')
117+
loadingResolve = res
118+
}))
119+
const renderA = jest.fn((api: ReturnType<typeof useCached>) => {
120+
return api.get('foo', () => loading(api))
121+
})
122+
const renderB = jest.fn((api: ReturnType<typeof useCached>) => {
123+
return api.get('foo', () => loading(api))
124+
})
125+
await setup([undefined, undefined], [renderA, renderB])
126+
127+
expect(renderA).toHaveBeenCalledTimes(1)
128+
expect(renderB).toHaveBeenCalledTimes(1)
129+
130+
await waitFor(() => expect(loadingResolve).toBeTruthy())
131+
expect(loading).toHaveBeenCalledTimes(1)
132+
act(() => {
133+
loadingResolve && loadingResolve()
134+
})
135+
136+
expect(renderA).toReturnTimes(2)
137+
expect(renderA).toHaveNthReturnedWith(2, 'bar')
138+
expect(renderB).toReturnTimes(2)
139+
expect(renderB).toHaveNthReturnedWith(2, 'bar')
140+
})

0 commit comments

Comments
 (0)