diff --git a/.all-contributorsrc b/.all-contributorsrc
index 9edfc26a..dea90e11 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -657,6 +657,17 @@
"bug",
"code"
]
+ },
+ {
+ "login": "Andrewmat",
+ "name": "AndrΓ© Matulionis dos Santos",
+ "avatar_url": "https://avatars0.githubusercontent.com/u/5133846?v=4",
+ "profile": "https://twitter.com/Andrewmat",
+ "contributions": [
+ "code",
+ "example",
+ "test"
+ ]
}
]
}
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index 5114fdbd..724a7df6 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -59,7 +59,8 @@ What happened:
-Reproduction repository: https://github.com/alexkrolick/dom-testing-library-template
+Reproduction repository:
+https://github.com/alexkrolick/dom-testing-library-template
diff --git a/examples/__tests__/mock.react-transition-group.js b/examples/__tests__/mock.react-transition-group.js
index ef22636f..83894534 100644
--- a/examples/__tests__/mock.react-transition-group.js
+++ b/examples/__tests__/mock.react-transition-group.js
@@ -31,9 +31,8 @@ afterEach(cleanup)
jest.mock('react-transition-group', () => {
const FakeTransition = jest.fn(({children}) => children)
- const FakeCSSTransition = jest.fn(
- props =>
- props.in ? {props.children} : null,
+ const FakeCSSTransition = jest.fn(props =>
+ props.in ? {props.children} : null,
)
return {CSSTransition: FakeCSSTransition, Transition: FakeTransition}
})
diff --git a/examples/__tests__/react-hooks.js b/examples/__tests__/react-hooks.js
index 5e001a37..fe616eb7 100644
--- a/examples/__tests__/react-hooks.js
+++ b/examples/__tests__/react-hooks.js
@@ -6,53 +6,114 @@
*/
import {testHook, act, cleanup} from 'react-testing-library'
-import useCounter from '../react-hooks'
+import {useCounter, useDocumentTitle, useCall} from '../react-hooks'
afterEach(cleanup)
-test('accepts default initial values', () => {
- let count
- testHook(() => ({count} = useCounter()))
+describe('useCounter', () => {
+ test('accepts default initial values', () => {
+ let count
+ testHook(() => ({count} = useCounter()))
- expect(count).toBe(0)
-})
+ expect(count).toBe(0)
+ })
-test('accepts a default initial value for `count`', () => {
- let count
- testHook(() => ({count} = useCounter({})))
+ test('accepts a default initial value for `count`', () => {
+ let count
+ testHook(() => ({count} = useCounter({})))
- expect(count).toBe(0)
-})
+ expect(count).toBe(0)
+ })
+
+ test('provides an `increment` function', () => {
+ let count, increment
+ testHook(() => ({count, increment} = useCounter({step: 2})))
+
+ expect(count).toBe(0)
+ act(() => {
+ increment()
+ })
+ expect(count).toBe(2)
+ })
+
+ test('provides an `decrement` function', () => {
+ let count, decrement
+ testHook(() => ({count, decrement} = useCounter({step: 2})))
+
+ expect(count).toBe(0)
+ act(() => {
+ decrement()
+ })
+ expect(count).toBe(-2)
+ })
-test('provides an `increment` function', () => {
- let count, increment
- testHook(() => ({count, increment} = useCounter({step: 2})))
+ test('accepts a default initial value for `step`', () => {
+ let count, increment
+ testHook(() => ({count, increment} = useCounter({})))
- expect(count).toBe(0)
- act(() => {
- increment()
+ expect(count).toBe(0)
+ act(() => {
+ increment()
+ })
+ expect(count).toBe(1)
})
- expect(count).toBe(2)
})
-test('provides an `decrement` function', () => {
- let count, decrement
- testHook(() => ({count, decrement} = useCounter({step: 2})))
+// using unmount function to check useEffect behavior when unmounting
+describe('useDocumentTitle', () => {
+ test('sets a title', () => {
+ document.title = 'original title'
+ testHook(() => {
+ useDocumentTitle('modified title')
+ })
- expect(count).toBe(0)
- act(() => {
- decrement()
+ expect(document.title).toBe('modified title')
+ })
+
+ test('returns to original title when component is unmounted', () => {
+ document.title = 'original title'
+ const {unmount} = testHook(() => {
+ useDocumentTitle('modified title')
+ })
+
+ unmount()
+ expect(document.title).toBe('original title')
})
- expect(count).toBe(-2)
})
-test('accepts a default initial value for `step`', () => {
- let count, increment
- testHook(() => ({count, increment} = useCounter({})))
+// using rerender function to test calling useEffect multiple times
+describe('useCall', () => {
+ test('calls once on render', () => {
+ const spy = jest.fn()
+ testHook(() => {
+ useCall(spy, [])
+ })
+ expect(spy).toHaveBeenCalledTimes(1)
+ })
+
+ test('calls again if deps change', () => {
+ let deps = [false]
+ const spy = jest.fn()
+ const {rerender} = testHook(() => {
+ useCall(spy, deps)
+ })
+ expect(spy).toHaveBeenCalledTimes(1)
+
+ deps = [true]
+ rerender()
+ expect(spy).toHaveBeenCalledTimes(2)
+ })
+
+ test('does not call again if deps are the same', () => {
+ let deps = [false]
+ const spy = jest.fn()
+ const {rerender} = testHook(() => {
+ useCall(spy, deps)
+ })
+ expect(spy).toHaveBeenCalledTimes(1)
- expect(count).toBe(0)
- act(() => {
- increment()
+ deps = [false]
+ rerender()
+ expect(spy).toHaveBeenCalledTimes(1)
})
- expect(count).toBe(1)
})
diff --git a/examples/react-hooks.js b/examples/react-hooks.js
index fad0de4c..251644cd 100644
--- a/examples/react-hooks.js
+++ b/examples/react-hooks.js
@@ -1,10 +1,25 @@
-import {useState} from 'react'
+import {useState, useEffect} from 'react'
-function useCounter({initialCount = 0, step = 1} = {}) {
+export function useCounter({initialCount = 0, step = 1} = {}) {
const [count, setCount] = useState(initialCount)
const increment = () => setCount(c => c + step)
const decrement = () => setCount(c => c - step)
return {count, increment, decrement}
}
-export default useCounter
+export function useDocumentTitle(title) {
+ const [originalTitle, setOriginalTitle] = useState(document.title)
+ useEffect(() => {
+ setOriginalTitle(document.title)
+ document.title = title
+ return () => {
+ document.title = originalTitle
+ }
+ }, [title])
+}
+
+export function useCall(callback, deps) {
+ useEffect(() => {
+ callback()
+ }, deps)
+}
diff --git a/src/__tests__/test-hook.js b/src/__tests__/test-hook.js
index f6bce9bd..673e9497 100644
--- a/src/__tests__/test-hook.js
+++ b/src/__tests__/test-hook.js
@@ -1,4 +1,4 @@
-import {useState} from 'react'
+import {useState, useEffect} from 'react'
import 'jest-dom/extend-expect'
import {testHook, cleanup} from '../'
@@ -12,3 +12,29 @@ test('testHook calls the callback', () => {
test('confirm we can safely call a React Hook from within the callback', () => {
testHook(() => useState())
})
+test('returns a function to unmount component', () => {
+ let isMounted
+ const {unmount} = testHook(() => {
+ useEffect(() => {
+ isMounted = true
+ return () => {
+ isMounted = false
+ }
+ })
+ })
+ expect(isMounted).toBe(true)
+ unmount()
+ expect(isMounted).toBe(false)
+})
+test('returns a function to rerender component', () => {
+ let renderCount = 0
+ const {rerender} = testHook(() => {
+ useEffect(() => {
+ renderCount++
+ })
+ })
+
+ expect(renderCount).toBe(1)
+ rerender()
+ expect(renderCount).toBe(2)
+})
diff --git a/src/index.js b/src/index.js
index 0f4c7d47..78b5ffae 100644
--- a/src/index.js
+++ b/src/index.js
@@ -67,7 +67,15 @@ function TestHook({callback}) {
}
function testHook(callback) {
- render()
+ const {unmount, rerender: rerenderComponent} = render(
+ ,
+ )
+ return {
+ unmount,
+ rerender: () => {
+ rerenderComponent()
+ },
+ }
}
function cleanup() {