Skip to content

Commit c3fab96

Browse files
committed
test(dom): improve batchUpdates tests
1 parent 562890f commit c3fab96

File tree

1 file changed

+39
-27
lines changed

1 file changed

+39
-27
lines changed

packages/dom/src/batchUpdates.test.tsx

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,25 @@
11
import React, { Component, ErrorInfo, useEffect } from "react"
2-
import { Observable, from, throwError } from "rxjs"
3-
import { delay, startWith } from "rxjs/operators"
2+
import { Observable, throwError, concat, Subject } from "rxjs"
3+
import { mergeMapTo, take, filter } from "rxjs/operators"
44
import { bind, Subscribe } from "@react-rxjs/core"
55
import { batchUpdates } from "./"
6-
import { render, screen } from "@testing-library/react"
6+
import { act, render, screen } from "@testing-library/react"
77

88
const wait = (ms: number) => new Promise((res) => setTimeout(res, ms))
99

10-
const [useLatestNumber, latestNumber$] = bind((id: string, batched: boolean) =>
11-
(id === "error"
12-
? throwError("controlled error")
13-
: from([1, 2, 3, 4, 5])
14-
).pipe(
15-
delay(5),
16-
batched ? batchUpdates() : (x: Observable<number>) => x,
17-
startWith(0),
18-
),
10+
const next$ = new Subject<{ batched: boolean; error: boolean }>()
11+
const [useLatestNumber, latestNumber$] = bind(
12+
(batched: boolean, error: boolean) => {
13+
return concat(
14+
[0],
15+
next$.pipe(
16+
filter((x) => x.batched === batched && x.error === error),
17+
take(1),
18+
mergeMapTo(error ? throwError("controlled error") : [1, 2, 3, 4, 5]),
19+
batched ? batchUpdates() : (x: Observable<number>) => x,
20+
),
21+
)
22+
},
1923
)
2024

2125
class TestErrorBoundary extends Component<
@@ -49,17 +53,17 @@ class TestErrorBoundary extends Component<
4953

5054
interface Props {
5155
onRender: () => void
52-
batched: boolean
53-
id: string
56+
batched?: boolean
57+
error?: boolean
5458
}
55-
const Grandson: React.FC<Props> = ({ onRender, batched, id }) => {
56-
const latestNumber = useLatestNumber(id, batched)
59+
const Grandson: React.FC<Props> = ({ onRender, batched, error }) => {
60+
const latestNumber = useLatestNumber(!!batched, !!error)
5761
useEffect(onRender)
5862
return <div>Grandson {latestNumber}</div>
5963
}
6064

6165
const Son: React.FC<Props> = (props) => {
62-
const latestNumber = useLatestNumber(props.id, props.batched)
66+
const latestNumber = useLatestNumber(!!props.batched, !!props.error)
6367
useEffect(props.onRender)
6468
return (
6569
<div>
@@ -70,7 +74,7 @@ const Son: React.FC<Props> = (props) => {
7074
}
7175

7276
const Father: React.FC<Props> = (props) => {
73-
const latestNumber = useLatestNumber(props.id, props.batched)
77+
const latestNumber = useLatestNumber(!!props.batched, !!props.error)
7478
useEffect(props.onRender)
7579
return (
7680
<div>
@@ -98,16 +102,19 @@ describe("batchUpdates", () => {
98102
test("it triggers nested updates when batchUpdates is not used", async () => {
99103
const mockFn = jest.fn()
100104
render(
101-
<Subscribe source$={latestNumber$("noBatching", false)}>
102-
<Father id="noBatching" batched={false} onRender={mockFn} />
105+
<Subscribe source$={latestNumber$(false, false)}>
106+
<Father onRender={mockFn} />
103107
</Subscribe>,
104108
)
105109
expect(screen.queryByText("Father 0")).not.toBeNull()
106110
expect(screen.queryByText("Son 0")).not.toBeNull()
107111
expect(screen.queryByText("Grandson 0")).not.toBeNull()
108112
expect(mockFn).toHaveBeenCalledTimes(3)
109113

110-
await wait(10)
114+
await act(async () => {
115+
await wait(100)
116+
next$.next({ batched: false, error: false })
117+
})
111118

112119
expect(screen.queryByText("Father 5")).not.toBeNull()
113120
expect(screen.queryByText("Son 5")).not.toBeNull()
@@ -118,8 +125,8 @@ describe("batchUpdates", () => {
118125
test("batchUpdates prevents unnecessary updates", async () => {
119126
const mockFn = jest.fn()
120127
render(
121-
<Subscribe source$={latestNumber$("batchingAndComplete", true)}>
122-
<Father id="batchingAndComplete" batched onRender={mockFn} />
128+
<Subscribe source$={latestNumber$(true, false)}>
129+
<Father batched onRender={mockFn} />
123130
</Subscribe>,
124131
)
125132

@@ -128,7 +135,10 @@ describe("batchUpdates", () => {
128135
expect(screen.queryByText("Grandson 0")).not.toBeNull()
129136
expect(mockFn).toHaveBeenCalledTimes(3)
130137

131-
await wait(10)
138+
await act(async () => {
139+
await wait(100)
140+
next$.next({ batched: true, error: false })
141+
})
132142

133143
expect(screen.queryByText("Father 5")).not.toBeNull()
134144
expect(screen.queryByText("Son 5")).not.toBeNull()
@@ -141,20 +151,22 @@ describe("batchUpdates", () => {
141151
const errorCallback = jest.fn()
142152
render(
143153
<TestErrorBoundary onError={errorCallback}>
144-
<Father id="error" batched={true} onRender={mockFn} />
154+
<Father batched error onRender={mockFn} />
145155
</TestErrorBoundary>,
146156
)
147157
expect(screen.queryByText("Father 0")).not.toBeNull()
148158
expect(screen.queryByText("Son 0")).not.toBeNull()
149159
expect(screen.queryByText("Grandson 0")).not.toBeNull()
150160
expect(mockFn).toHaveBeenCalledTimes(3)
151161

152-
await wait(10)
162+
await act(async () => {
163+
next$.next({ batched: true, error: true })
164+
})
153165

154-
expect(mockFn).toHaveBeenCalledTimes(3)
155166
expect(errorCallback).toHaveBeenCalledWith(
156167
"controlled error",
157168
expect.any(Object),
158169
)
170+
expect(mockFn).toHaveBeenCalledTimes(3)
159171
})
160172
})

0 commit comments

Comments
 (0)