Skip to content

Commit c09b997

Browse files
committed
update README
1 parent 262ceba commit c09b997

File tree

1 file changed

+61
-39
lines changed

1 file changed

+61
-39
lines changed

README.md

+61-39
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
## What is this library?
44

5-
This library allows you to make render-per-render assertions on your React
6-
components and hooks. This is usually not necessary, but can be highly
7-
beneficial when testing hot code paths.
5+
This library allows you to make committed-render-to-committed-render assertions
6+
on your React components and hooks. This is usually not necessary, but can be
7+
highly beneficial when testing hot code paths.
88

99
## Who is this library for?
1010

@@ -36,7 +36,7 @@ test('iterate through renders with DOM snapshots', async () => {
3636
const {takeRender, render} = createRenderStream({
3737
snapshotDOM: true,
3838
})
39-
const utils = render(<Counter />)
39+
const utils = await render(<Counter />)
4040
const incrementButton = utils.getByText('Increment')
4141
await userEvent.click(incrementButton)
4242
await userEvent.click(incrementButton)
@@ -63,31 +63,27 @@ test('iterate through renders with DOM snapshots', async () => {
6363
In every place you would call
6464

6565
```js
66-
const renderStream = createRenderStream(options)
67-
const utils = renderStream.render(<Component />, options)
66+
const {takeRender, render} = createRenderStream(options)
67+
const utils = await render(<Component />, options)
6868
```
6969

7070
you can also call
7171

7272
```js
73-
const renderStream = renderToRenderStream(<Component />, combinedOptions)
74-
// if required
75-
const utils = await renderStream.renderResultPromise
73+
const {takeRender, utils} = await renderToRenderStream(
74+
<Component />,
75+
combinedOptions,
76+
)
7677
```
7778

78-
This might be shorter (especially in cases where you don't need to access
79-
`utils`), but keep in mind that the render is executed **asynchronously** after
80-
calling `renderToRenderStream`, and that you need to `await renderResultPromise`
81-
if you need access to `utils` as returned by `render`.
82-
8379
### `renderHookToSnapshotStream`
8480

8581
Usage is very similar to RTL's `renderHook`, but you get a `snapshotStream`
8682
object back that you can iterate with `takeSnapshot` calls.
8783

8884
```jsx
8985
test('`useQuery` with `skip`', async () => {
90-
const {takeSnapshot, rerender} = renderHookToSnapshotStream(
86+
const {takeSnapshot, rerender} = await renderHookToSnapshotStream(
9187
({skip}) => useQuery(query, {skip}),
9288
{
9389
wrapper: ({children}) => <Provider client={client}>{children}</Provider>,
@@ -105,7 +101,7 @@ test('`useQuery` with `skip`', async () => {
105101
expect(result.data).toEqual({hello: 'world 1'})
106102
}
107103

108-
rerender({skip: true})
104+
await rerender({skip: true})
109105
{
110106
const snapshot = await takeSnapshot()
111107
expect(snapshot.loading).toBe(false)
@@ -146,7 +142,7 @@ test('`useTrackRenders` with suspense', async () => {
146142
}
147143

148144
const {takeRender, render} = createRenderStream()
149-
render(<App />)
145+
await render(<App />)
150146
{
151147
const {renderedComponents} = await takeRender()
152148
expect(renderedComponents).toEqual([App, LoadingComponent])
@@ -179,7 +175,7 @@ test('custom snapshots with `replaceSnapshot`', async () => {
179175
const {takeRender, replaceSnapshot, render} = createRenderStream<{
180176
value: number
181177
}>()
182-
const utils = render(<Counter />)
178+
const utils = await render(<Counter />)
183179
const incrementButton = utils.getByText('Increment')
184180
await userEvent.click(incrementButton)
185181
{
@@ -215,16 +211,14 @@ test('assertions in `onRender`', async () => {
215211
)
216212
}
217213

218-
const {takeRender, replaceSnapshot, renderResultPromise} =
219-
renderToRenderStream<{
220-
value: number
221-
}>({
222-
onRender(info) {
223-
// you can use `expect` here
224-
expect(info.count).toBe(info.snapshot.value + 1)
225-
},
226-
})
227-
const utils = await renderResultPromise
214+
const {takeRender, replaceSnapshot, utils} = await renderToRenderStream<{
215+
value: number
216+
}>({
217+
onRender(info) {
218+
// you can use `expect` here
219+
expect(info.count).toBe(info.snapshot.value + 1)
220+
},
221+
})
228222
const incrementButton = utils.getByText('Increment')
229223
await userEvent.click(incrementButton)
230224
await userEvent.click(incrementButton)
@@ -247,7 +241,7 @@ This library adds to matchers to `expect` that can be used like
247241

248242
```tsx
249243
test('basic functionality', async () => {
250-
const {takeRender} = renderToRenderStream(<RerenderingComponent />)
244+
const {takeRender} = await renderToRenderStream(<RerenderingComponent />)
251245

252246
await expect(takeRender).toRerender()
253247
await takeRender()
@@ -285,17 +279,45 @@ await expect(snapshotStream).toRerender()
285279
> [!TIP]
286280
>
287281
> If you don't want these matchers not to be automatically installed, you can
288-
> import from `@testing-library/react-render-stream` instead.
282+
> import from `@testing-library/react-render-stream/pure` instead.
283+
> Keep in mind that if you use the `/pure` import, you have to call the
284+
> `cleanup` export manually after each test.
285+
286+
## Usage side-by side with `@testing-library/react` or other tools that set `IS_REACT_ACT_ENVIRONMENT` or use `act`
287+
288+
This library is written in a way if should not be used with `act`, and it will
289+
throw an error if `IS_REACT_ACT_ENVIRONMENT` is `true`.
290+
291+
React Testing Library usually sets `IS_REACT_ACT_ENVIRONMENT` to `true`
292+
globally, and wraps some helpers like `userEvent.click` in `act` calls.
293+
294+
To use this library side-by-side with React Testing Library, we ship the
295+
`disableActEnvironment` helper to undo these changes temporarily.
296+
297+
It returns a `Disposable` and can be used together with the `using` keyword to
298+
automatically clean up once the scope is left:
289299
290-
## A note on `act`.
300+
```ts
301+
test('my test', () => {
302+
using _disabledAct = disableActEnvironment()
291303
292-
You might want to avoid using this library with `act`, as `act`
293-
[can end up batching multiple renders](https://github.com/facebook/react/issues/30031#issuecomment-2183951296)
294-
into one in a way that would not happen in a production application.
304+
// your test code here
295305
296-
While that is convenient in a normal test suite, it defeats the purpose of this
297-
library.
306+
// as soon as this scope is left, the environment will be cleaned up
307+
})
308+
```
298309
299-
Keep in mind that tools like `userEvent.click` use `act` internally. Many of
300-
those calls would only trigger one render anyways, so it can be okay to use
301-
them, but avoid this for longer-running actions inside of `act` calls.
310+
If you cannot use `using`, you can also manually call the returned `cleanup`
311+
function:
312+
313+
```ts
314+
test('my test', () => {
315+
const {cleanup} = disableActEnvironment()
316+
317+
try {
318+
// your test code here
319+
} finally {
320+
cleanup()
321+
}
322+
})
323+
```

0 commit comments

Comments
 (0)