Skip to content

Commit 01918d9

Browse files
committed
feat: add addCleanup
1 parent 91734c5 commit 01918d9

File tree

6 files changed

+84
-12
lines changed

6 files changed

+84
-12
lines changed

.all-contributorsrc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,17 @@
183183
"contributions": [
184184
"test"
185185
]
186+
},
187+
{
188+
"login": "huchenme",
189+
"name": "Hu Chen",
190+
"avatar_url": "https://avatars3.githubusercontent.com/u/2078389?v=4",
191+
"profile": "https://huchen.dev/",
192+
"contributions": [
193+
"code",
194+
"doc",
195+
"example"
196+
]
186197
}
187198
],
188199
"commitConvention": "none"

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,11 +164,13 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
164164
<td align="center"><a href="https://github.com/102"><img src="https://avatars1.githubusercontent.com/u/5839225?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Roman Gusev</b></sub></a><br /><a href="https://github.com/testing-library/react-hooks-testing-library/commits?author=102" title="Documentation">📖</a></td>
165165
<td align="center"><a href="https://github.com/hemlok"><img src="https://avatars2.githubusercontent.com/u/9043345?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Adam Seckel</b></sub></a><br /><a href="https://github.com/testing-library/react-hooks-testing-library/commits?author=hemlok" title="Code">💻</a></td>
166166
<td align="center"><a href="https://keiya01.github.io/portfolio"><img src="https://avatars1.githubusercontent.com/u/34934510?v=4?s=100" width="100px;" alt=""/><br /><sub><b>keiya sasaki</b></sub></a><br /><a href="https://github.com/testing-library/react-hooks-testing-library/commits?author=keiya01" title="Tests">⚠️</a></td>
167+
<td align="center"><a href="https://huchen.dev/"><img src="https://avatars3.githubusercontent.com/u/2078389?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Hu Chen</b></sub></a><br /><a href="https://github.com/testing-library/react-hooks-testing-library/commits?author=huchenme" title="Code">💻</a> <a href="https://github.com/testing-library/react-hooks-testing-library/commits?author=huchenme" title="Documentation">📖</a> <a href="#example-huchenme" title="Examples">💡</a></td>
167168
</tr>
168169
</table>
169170

170-
<!-- markdownlint-enable -->
171+
<!-- markdownlint-restore -->
171172
<!-- prettier-ignore-end -->
173+
172174
<!-- ALL-CONTRIBUTORS-LIST:END -->
173175

174176
This project follows the [all-contributors](https://allcontributors.org/) specification.

docs/api-reference.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ route: '/reference/api'
1010
- [`renderHook`](/reference/api#renderhook)
1111
- [`act`](/reference/api#act)
1212
- [`cleanup`](/reference/api#cleanup)
13+
- [`addCleanup`](/reference/api#addcleanup)
1314

1415
---
1516

@@ -147,6 +148,31 @@ variable to `true` before importing `@testing-library/react-hooks` will also dis
147148
148149
---
149150
151+
## `addCleanup`
152+
153+
```js
154+
function addCleanup(
155+
callback: function(props?: any): any
156+
): void
157+
```
158+
159+
Callback to be called after `cleanup`.
160+
161+
In some cases you might want to run some callback after internal `cleanup` happen, especially after
162+
`unmount` happens in `cleanup`. If the sequence matters to you, you could use `addCleanup`.
163+
164+
```js
165+
import { addCleanup } from '@testing-library/react-hooks'
166+
167+
jest.useFakeTimers()
168+
169+
addCleanup(() => {
170+
jest.runOnlyPendingTimers()
171+
})
172+
```
173+
174+
---
175+
150176
## Async Utilities
151177
152178
### `waitForNextUpdate`

src/cleanup.js

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,25 @@
11
import flushMicroTasks from './flush-microtasks'
22

3-
let cleanupCallbacks = []
3+
let internalCleanupCbs = []
4+
let cleanupCbs = []
45

56
async function cleanup() {
67
await flushMicroTasks()
7-
cleanupCallbacks.forEach((cb) => cb())
8-
cleanupCallbacks = []
8+
internalCleanupCbs.forEach((cb) => cb())
9+
internalCleanupCbs = []
10+
cleanupCbs.forEach((cb) => cb())
11+
}
12+
13+
function addInternalCleanup(callback) {
14+
internalCleanupCbs.push(callback)
915
}
1016

1117
function addCleanup(callback) {
12-
cleanupCallbacks.push(callback)
18+
cleanupCbs.push(callback)
1319
}
1420

15-
function removeCleanup(callback) {
16-
cleanupCallbacks = cleanupCallbacks.filter((cb) => cb !== callback)
21+
function removeInternalCleanup(callback) {
22+
internalCleanupCbs = internalCleanupCbs.filter((cb) => cb !== callback)
1723
}
1824

19-
export { cleanup, addCleanup, removeCleanup }
25+
export { cleanup, addCleanup, addInternalCleanup, removeInternalCleanup }

src/pure.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React, { Suspense } from 'react'
22
import { act, create } from 'react-test-renderer'
33
import asyncUtils from './asyncUtils'
4-
import { cleanup, addCleanup, removeCleanup } from './cleanup'
4+
import { cleanup, addCleanup, addInternalCleanup, removeInternalCleanup } from './cleanup'
55

66
function TestHook({ callback, hookProps, onError, children }) {
77
try {
@@ -84,12 +84,12 @@ function renderHook(callback, { initialProps, wrapper } = {}) {
8484

8585
function unmountHook() {
8686
act(() => {
87-
removeCleanup(unmountHook)
87+
removeInternalCleanup(unmountHook)
8888
unmount()
8989
})
9090
}
9191

92-
addCleanup(unmountHook)
92+
addInternalCleanup(unmountHook)
9393

9494
return {
9595
result,
@@ -99,4 +99,4 @@ function renderHook(callback, { initialProps, wrapper } = {}) {
9999
}
100100
}
101101

102-
export { renderHook, cleanup, act }
102+
export { renderHook, cleanup, act, addCleanup }

test/addCleanup.test.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { useEffect } from 'react'
2+
import { renderHook, addCleanup } from 'src'
3+
4+
let callSequence = []
5+
addCleanup(() => {
6+
callSequence.push('cleanup')
7+
})
8+
addCleanup(() => {
9+
callSequence.push('another cleanup')
10+
})
11+
12+
describe('addCleanup tests', () => {
13+
test('first', () => {
14+
const hookWithCleanup = () => {
15+
useEffect(() => {
16+
return () => {
17+
callSequence.push('unmount')
18+
}
19+
})
20+
}
21+
renderHook(() => hookWithCleanup())
22+
})
23+
24+
test('second', () => {
25+
expect(callSequence).toEqual(['unmount', 'cleanup', 'another cleanup'])
26+
})
27+
})

0 commit comments

Comments
 (0)