Skip to content

Commit

Permalink
feat: add addCleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
huchenme committed Aug 19, 2020
1 parent 91734c5 commit 01918d9
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 12 deletions.
11 changes: 11 additions & 0 deletions .all-contributorsrc
Expand Up @@ -183,6 +183,17 @@
"contributions": [
"test"
]
},
{
"login": "huchenme",
"name": "Hu Chen",
"avatar_url": "https://avatars3.githubusercontent.com/u/2078389?v=4",
"profile": "https://huchen.dev/",
"contributions": [
"code",
"doc",
"example"
]
}
],
"commitConvention": "none"
Expand Down
4 changes: 3 additions & 1 deletion README.md
Expand Up @@ -164,11 +164,13 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
<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>
<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>
<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>
<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>
</tr>
</table>

<!-- markdownlint-enable -->
<!-- markdownlint-restore -->
<!-- prettier-ignore-end -->

<!-- ALL-CONTRIBUTORS-LIST:END -->

This project follows the [all-contributors](https://allcontributors.org/) specification.
Expand Down
26 changes: 26 additions & 0 deletions docs/api-reference.md
Expand Up @@ -10,6 +10,7 @@ route: '/reference/api'
- [`renderHook`](/reference/api#renderhook)
- [`act`](/reference/api#act)
- [`cleanup`](/reference/api#cleanup)
- [`addCleanup`](/reference/api#addcleanup)

---

Expand Down Expand Up @@ -147,6 +148,31 @@ variable to `true` before importing `@testing-library/react-hooks` will also dis
---
## `addCleanup`
```js
function addCleanup(
callback: function(props?: any): any
): void
```

Callback to be called after `cleanup`.

In some cases you might want to run some callback after internal `cleanup` happen, especially after
`unmount` happens in `cleanup`. If the sequence matters to you, you could use `addCleanup`.

```js
import { addCleanup } from '@testing-library/react-hooks'

jest.useFakeTimers()

addCleanup(() => {
jest.runOnlyPendingTimers()
})
```
---
## Async Utilities
### `waitForNextUpdate`
Expand Down
20 changes: 13 additions & 7 deletions src/cleanup.js
@@ -1,19 +1,25 @@
import flushMicroTasks from './flush-microtasks'

let cleanupCallbacks = []
let internalCleanupCbs = []
let cleanupCbs = []

async function cleanup() {
await flushMicroTasks()
cleanupCallbacks.forEach((cb) => cb())
cleanupCallbacks = []
internalCleanupCbs.forEach((cb) => cb())
internalCleanupCbs = []
cleanupCbs.forEach((cb) => cb())
}

function addInternalCleanup(callback) {
internalCleanupCbs.push(callback)
}

function addCleanup(callback) {
cleanupCallbacks.push(callback)
cleanupCbs.push(callback)
}

function removeCleanup(callback) {
cleanupCallbacks = cleanupCallbacks.filter((cb) => cb !== callback)
function removeInternalCleanup(callback) {
internalCleanupCbs = internalCleanupCbs.filter((cb) => cb !== callback)
}

export { cleanup, addCleanup, removeCleanup }
export { cleanup, addCleanup, addInternalCleanup, removeInternalCleanup }
8 changes: 4 additions & 4 deletions src/pure.js
@@ -1,7 +1,7 @@
import React, { Suspense } from 'react'
import { act, create } from 'react-test-renderer'
import asyncUtils from './asyncUtils'
import { cleanup, addCleanup, removeCleanup } from './cleanup'
import { cleanup, addCleanup, addInternalCleanup, removeInternalCleanup } from './cleanup'

function TestHook({ callback, hookProps, onError, children }) {
try {
Expand Down Expand Up @@ -84,12 +84,12 @@ function renderHook(callback, { initialProps, wrapper } = {}) {

function unmountHook() {
act(() => {
removeCleanup(unmountHook)
removeInternalCleanup(unmountHook)
unmount()
})
}

addCleanup(unmountHook)
addInternalCleanup(unmountHook)

return {
result,
Expand All @@ -99,4 +99,4 @@ function renderHook(callback, { initialProps, wrapper } = {}) {
}
}

export { renderHook, cleanup, act }
export { renderHook, cleanup, act, addCleanup }
27 changes: 27 additions & 0 deletions test/addCleanup.test.js
@@ -0,0 +1,27 @@
import { useEffect } from 'react'
import { renderHook, addCleanup } from 'src'

let callSequence = []
addCleanup(() => {
callSequence.push('cleanup')
})
addCleanup(() => {
callSequence.push('another cleanup')
})

describe('addCleanup tests', () => {
test('first', () => {
const hookWithCleanup = () => {
useEffect(() => {
return () => {
callSequence.push('unmount')
}
})
}
renderHook(() => hookWithCleanup())
})

test('second', () => {
expect(callSequence).toEqual(['unmount', 'cleanup', 'another cleanup'])
})
})

0 comments on commit 01918d9

Please sign in to comment.