Skip to content

Commit c02cbae

Browse files
committed
Merge branch 'main' into chore/update-dev-deps
2 parents 54cc4da + 08d0a85 commit c02cbae

34 files changed

+2134
-2122
lines changed

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,6 @@
140140
"@testing-library/dom": "^10.4.1",
141141
"@testing-library/jest-dom": "^6.9.1",
142142
"@testing-library/react": "^16.3.0",
143-
"@testing-library/user-event": "^14.6.1",
144143
"@types/babel__core": "^7.20.5",
145144
"@types/babel__template": "^7.4.4",
146145
"@types/node": "^24.10.1",

tests/react/abortable.test.tsx

Lines changed: 75 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,24 @@
11
import { StrictMode, Suspense, useState } from 'react'
2-
import { act, render, screen, waitFor } from '@testing-library/react'
3-
import userEventOrig from '@testing-library/user-event'
4-
import { describe, expect, it } from 'vitest'
2+
import { act, fireEvent, render, screen } from '@testing-library/react'
3+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
54
import { useAtomValue, useSetAtom } from 'jotai/react'
65
import { atom } from 'jotai/vanilla'
76

8-
const userEvent = {
9-
click: (element: Element) => act(() => userEventOrig.click(element)),
10-
}
7+
beforeEach(() => {
8+
vi.useFakeTimers()
9+
})
10+
11+
afterEach(() => {
12+
vi.useRealTimers()
13+
})
1114

1215
describe('abortable atom test', () => {
1316
it('can abort with signal.aborted', async () => {
1417
const countAtom = atom(0)
1518
let abortedCount = 0
16-
const resolve: (() => void)[] = []
1719
const derivedAtom = atom(async (get, { signal }) => {
1820
const count = get(countAtom)
19-
await new Promise<void>((r) => resolve.push(r))
21+
await new Promise((resolve) => setTimeout(resolve, 100))
2022
if (signal.aborted) {
2123
++abortedCount
2224
}
@@ -37,47 +39,51 @@ describe('abortable atom test', () => {
3739
)
3840
}
3941

40-
await act(async () => {
42+
await act(() =>
4143
render(
4244
<StrictMode>
4345
<Suspense fallback="loading">
4446
<Component />
4547
<Controls />
4648
</Suspense>
4749
</StrictMode>,
48-
)
49-
})
50+
),
51+
)
5052

51-
expect(await screen.findByText('loading')).toBeInTheDocument()
53+
expect(screen.getByText('loading')).toBeInTheDocument()
54+
55+
await act(() => vi.advanceTimersByTimeAsync(100))
56+
expect(screen.getByText('count: 0')).toBeInTheDocument()
5257

53-
resolve.splice(0).forEach((fn) => fn())
54-
expect(await screen.findByText('count: 0')).toBeInTheDocument()
5558
expect(abortedCount).toBe(0)
5659

57-
await userEvent.click(screen.getByText('button'))
58-
await userEvent.click(screen.getByText('button'))
59-
resolve.splice(0).forEach((fn) => fn())
60-
expect(await screen.findByText('count: 2')).toBeInTheDocument()
60+
await act(() => fireEvent.click(screen.getByText('button')))
61+
expect(screen.getByText('loading')).toBeInTheDocument()
62+
await act(() => fireEvent.click(screen.getByText('button')))
63+
expect(screen.getByText('loading')).toBeInTheDocument()
64+
await act(() => vi.advanceTimersByTimeAsync(100))
65+
expect(screen.getByText('count: 2')).toBeInTheDocument()
6166

6267
expect(abortedCount).toBe(1)
6368

64-
await userEvent.click(screen.getByText('button'))
65-
resolve.splice(0).forEach((fn) => fn())
66-
expect(await screen.findByText('count: 3')).toBeInTheDocument()
69+
await act(() => fireEvent.click(screen.getByText('button')))
70+
expect(screen.getByText('loading')).toBeInTheDocument()
71+
await act(() => vi.advanceTimersByTimeAsync(100))
72+
expect(screen.getByText('count: 3')).toBeInTheDocument()
73+
6774
expect(abortedCount).toBe(1)
6875
})
6976

7077
it('can abort with event listener', async () => {
7178
const countAtom = atom(0)
7279
let abortedCount = 0
73-
const resolve: (() => void)[] = []
7480
const derivedAtom = atom(async (get, { signal }) => {
7581
const count = get(countAtom)
7682
const callback = () => {
7783
++abortedCount
7884
}
7985
signal.addEventListener('abort', callback)
80-
await new Promise<void>((r) => resolve.push(r))
86+
await new Promise((resolve) => setTimeout(resolve, 100))
8187
signal.removeEventListener('abort', callback)
8288
return count
8389
})
@@ -96,44 +102,47 @@ describe('abortable atom test', () => {
96102
)
97103
}
98104

99-
await act(async () => {
105+
await act(() =>
100106
render(
101107
<StrictMode>
102108
<Suspense fallback="loading">
103109
<Component />
104110
<Controls />
105111
</Suspense>
106112
</StrictMode>,
107-
)
108-
})
113+
),
114+
)
109115

110-
expect(await screen.findByText('loading')).toBeInTheDocument()
111-
resolve.splice(0).forEach((fn) => fn())
112-
expect(await screen.findByText('count: 0')).toBeInTheDocument()
116+
expect(screen.getByText('loading')).toBeInTheDocument()
117+
118+
await act(() => vi.advanceTimersByTimeAsync(100))
119+
expect(screen.getByText('count: 0')).toBeInTheDocument()
113120

114121
expect(abortedCount).toBe(0)
115122

116-
await userEvent.click(screen.getByText('button'))
117-
await userEvent.click(screen.getByText('button'))
118-
resolve.splice(0).forEach((fn) => fn())
119-
expect(await screen.findByText('count: 2')).toBeInTheDocument()
123+
await act(() => fireEvent.click(screen.getByText('button')))
124+
expect(screen.getByText('loading')).toBeInTheDocument()
125+
await act(() => fireEvent.click(screen.getByText('button')))
126+
expect(screen.getByText('loading')).toBeInTheDocument()
127+
await act(() => vi.advanceTimersByTimeAsync(100))
128+
expect(screen.getByText('count: 2')).toBeInTheDocument()
120129

121130
expect(abortedCount).toBe(1)
122131

123-
await userEvent.click(screen.getByText('button'))
124-
resolve.splice(0).forEach((fn) => fn())
125-
expect(await screen.findByText('count: 3')).toBeInTheDocument()
132+
await act(() => fireEvent.click(screen.getByText('button')))
133+
expect(screen.getByText('loading')).toBeInTheDocument()
134+
await act(() => vi.advanceTimersByTimeAsync(100))
135+
expect(screen.getByText('count: 3')).toBeInTheDocument()
126136

127137
expect(abortedCount).toBe(1)
128138
})
129139

130140
it('does not abort on unmount', async () => {
131141
const countAtom = atom(0)
132142
let abortedCount = 0
133-
const resolve: (() => void)[] = []
134143
const derivedAtom = atom(async (get, { signal }) => {
135144
const count = get(countAtom)
136-
await new Promise<void>((r) => resolve.push(r))
145+
await new Promise((resolve) => setTimeout(resolve, 100))
137146
if (signal.aborted) {
138147
++abortedCount
139148
}
@@ -157,37 +166,33 @@ describe('abortable atom test', () => {
157166
)
158167
}
159168

160-
await act(async () => {
169+
await act(() =>
161170
render(
162171
<StrictMode>
163172
<Suspense fallback="loading">
164173
<Parent />
165174
</Suspense>
166175
</StrictMode>,
167-
)
168-
})
176+
),
177+
)
169178

170-
expect(await screen.findByText('loading')).toBeInTheDocument()
171-
172-
resolve.splice(0).forEach((fn) => fn())
173-
expect(await screen.findByText('count: 0')).toBeInTheDocument()
174-
expect(abortedCount).toBe(0)
179+
expect(screen.getByText('loading')).toBeInTheDocument()
180+
await act(() => vi.advanceTimersByTimeAsync(100))
181+
expect(screen.getByText('count: 0')).toBeInTheDocument()
175182

176-
await userEvent.click(screen.getByText('button'))
177-
await userEvent.click(screen.getByText('toggle'))
183+
await act(() => fireEvent.click(screen.getByText('button')))
184+
expect(screen.getByText('loading')).toBeInTheDocument()
185+
await act(() => fireEvent.click(screen.getByText('toggle')))
186+
expect(screen.getByText('hidden')).toBeInTheDocument()
178187

179-
expect(await screen.findByText('hidden')).toBeInTheDocument()
180-
181-
resolve.splice(0).forEach((fn) => fn())
182-
await waitFor(() => expect(abortedCount).toBe(0))
188+
expect(abortedCount).toBe(0)
183189
})
184190

185191
it('throws aborted error (like fetch)', async () => {
186192
const countAtom = atom(0)
187-
const resolve: (() => void)[] = []
188193
const derivedAtom = atom(async (get, { signal }) => {
189194
const count = get(countAtom)
190-
await new Promise<void>((r) => resolve.push(r))
195+
await new Promise((resolve) => setTimeout(resolve, 100))
191196
if (signal.aborted) {
192197
throw new Error('aborted')
193198
}
@@ -208,29 +213,32 @@ describe('abortable atom test', () => {
208213
)
209214
}
210215

211-
await act(async () => {
216+
await act(() =>
212217
render(
213218
<StrictMode>
214219
<Suspense fallback="loading">
215220
<Component />
216221
<Controls />
217222
</Suspense>
218223
</StrictMode>,
219-
)
220-
})
224+
),
225+
)
221226

222-
expect(await screen.findByText('loading')).toBeInTheDocument()
227+
expect(screen.getByText('loading')).toBeInTheDocument()
223228

224-
resolve.splice(0).forEach((fn) => fn())
225-
expect(await screen.findByText('count: 0')).toBeInTheDocument()
229+
await act(() => vi.advanceTimersByTimeAsync(100))
230+
expect(screen.getByText('count: 0')).toBeInTheDocument()
226231

227-
await userEvent.click(screen.getByText('button'))
228-
await userEvent.click(screen.getByText('button'))
229-
resolve.splice(0).forEach((fn) => fn())
230-
expect(await screen.findByText('count: 2')).toBeInTheDocument()
232+
await act(() => fireEvent.click(screen.getByText('button')))
233+
expect(screen.getByText('loading')).toBeInTheDocument()
234+
await act(() => fireEvent.click(screen.getByText('button')))
235+
expect(screen.getByText('loading')).toBeInTheDocument()
236+
await act(() => vi.advanceTimersByTimeAsync(100))
237+
expect(screen.getByText('count: 2')).toBeInTheDocument()
231238

232-
await userEvent.click(screen.getByText('button'))
233-
resolve.splice(0).forEach((fn) => fn())
234-
expect(await screen.findByText('count: 3')).toBeInTheDocument()
239+
await act(() => fireEvent.click(screen.getByText('button')))
240+
expect(screen.getByText('loading')).toBeInTheDocument()
241+
await act(() => vi.advanceTimersByTimeAsync(100))
242+
expect(screen.getByText('count: 3')).toBeInTheDocument()
235243
})
236244
})

0 commit comments

Comments
 (0)