Skip to content

Commit f760018

Browse files
committed
clear nextRenderTimeout in resetNextRender
1 parent d6bff60 commit f760018

2 files changed

Lines changed: 53 additions & 5 deletions

File tree

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import {expect, jest, test} from '@jest/globals'
2+
import {createRenderStream} from '@testing-library/react-render-stream'
3+
import * as React from 'react'
4+
import {flushSync} from 'react-dom'
5+
6+
test.each([false, true])(
7+
'a completed wait cannot clear a later waiter (snapshot error: %s)',
8+
async snapshotError => {
9+
const error = new Error('snapshot failed')
10+
const stream = createRenderStream<{value: number}>({
11+
onRender({snapshot}) {
12+
if (snapshotError && snapshot.value === 1) throw error
13+
},
14+
})
15+
let update: React.Dispatch<React.SetStateAction<number>>
16+
function Component() {
17+
const [value, setValue] = React.useState(0)
18+
update = setValue
19+
stream.replaceSnapshot({value})
20+
return null
21+
}
22+
await stream.render(<Component />)
23+
await stream.takeRender()
24+
25+
jest.useFakeTimers()
26+
try {
27+
const first = stream.takeRender({timeout: 100}).then(
28+
() => undefined,
29+
failure => failure,
30+
)
31+
flushSync(() => update!(1))
32+
await jest.advanceTimersByTimeAsync(0)
33+
expect(await first).toBe(snapshotError ? error : undefined)
34+
35+
const second = stream.takeRender({timeout: 200}).catch(failure => failure)
36+
// Cross the first wait's original deadline while the second is pending.
37+
await jest.advanceTimersByTimeAsync(100)
38+
flushSync(() => update!(2))
39+
await jest.advanceTimersByTimeAsync(100)
40+
expect(await second).toMatchObject({snapshot: {value: 2}})
41+
} finally {
42+
jest.useRealTimers()
43+
}
44+
},
45+
)

‎src/renderStream/createRenderStream.tsx‎

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,11 @@ export function createRenderStream<
142142

143143
let nextRender: Promise<Render<Snapshot, Q>> | undefined,
144144
resolveNextRender: ((render: Render<Snapshot, Q>) => void) | undefined,
145-
rejectNextRender: ((error: unknown) => void) | undefined
145+
rejectNextRender: ((error: unknown) => void) | undefined,
146+
nextRenderTimeout: ReturnType<typeof setTimeout> | undefined
146147
function resetNextRender() {
148+
clearTimeout(nextRenderTimeout)
149+
nextRenderTimeout = undefined
147150
nextRender = undefined
148151
resolveNextRender = undefined
149152
rejectNextRender = undefined
@@ -396,14 +399,14 @@ export function createRenderStream<
396399
resolveNextRender = resolve
397400
rejectNextRender = reject
398401
}),
399-
new Promise<Render<Snapshot, Q>>((_, reject) =>
400-
setTimeout(() => {
402+
new Promise<Render<Snapshot, Q>>((_, reject) => {
403+
nextRenderTimeout = setTimeout(() => {
401404
const error = new WaitForRenderTimeoutError()
402405
Error.captureStackTrace(error, stream.waitForNextRender)
403406
reject(error)
404407
resetNextRender()
405-
}, timeout),
406-
),
408+
}, timeout)
409+
}),
407410
])
408411
}
409412
return nextRender

0 commit comments

Comments
 (0)