} = {}
+) {
+ const { result, setValue, setError, addResolver } = resultContainer()
+ const hookProps = { current: initialProps }
+
+ const wrapUiIfNeeded = (innerElement: ReactNode) =>
+ wrapper ? React.createElement(wrapper, hookProps.current, innerElement) : innerElement
+
+ const toRender = () =>
+ wrapUiIfNeeded(
+ }>
+
+ {setValue}
+
+
+ ) as ReactElement
+
+ let testRenderer: ReactTestRenderer
+ act(() => {
+ testRenderer = create(toRender())
+ })
+
+ function rerenderHook(newProps: typeof initialProps = hookProps.current) {
+ hookProps.current = newProps
+ act(() => {
+ testRenderer.update(toRender())
+ })
+ }
+
+ function unmountHook() {
+ act(() => {
+ removeCleanup(unmountHook)
+ testRenderer.unmount()
+ })
+ }
+
+ addCleanup(unmountHook)
+
+ return {
+ result,
+ rerender: rerenderHook,
+ unmount: unmountHook,
+ ...asyncUtils(addResolver)
+ }
+}
+
+export { renderHook, cleanup, addCleanup, removeCleanup, act }
diff --git a/test/asyncHook.js b/test/asyncHook.ts
similarity index 74%
rename from test/asyncHook.js
rename to test/asyncHook.ts
index 74d321a6..5479db82 100644
--- a/test/asyncHook.js
+++ b/test/asyncHook.ts
@@ -2,7 +2,7 @@ import { useState, useRef, useEffect } from 'react'
import { renderHook } from '../src'
describe('async hook tests', () => {
- const useSequence = (...values) => {
+ const useSequence = (...values: string[]) => {
const [first, ...otherValues] = values
const [value, setValue] = useState(first)
const index = useRef(0)
@@ -266,92 +266,4 @@ describe('async hook tests', () => {
expect(result.current).toBe('third')
})
-
- test('should wait for expectation to pass (deprecated)', async () => {
- const { result, wait } = renderHook(() => useSequence('first', 'second', 'third'))
-
- expect(result.current).toBe('first')
-
- let complete = false
- await wait(() => {
- expect(result.current).toBe('third')
- complete = true
- })
- expect(complete).toBe(true)
- })
-
- test('should not hang if expectation is already passing (deprecated)', async () => {
- const { result, wait } = renderHook(() => useSequence('first', 'second'))
-
- expect(result.current).toBe('first')
-
- let complete = false
- await wait(() => {
- expect(result.current).toBe('first')
- complete = true
- })
- expect(complete).toBe(true)
- })
-
- test('should reject if callback throws error (deprecated)', async () => {
- const { result, wait } = renderHook(() => useSequence('first', 'second', 'third'))
-
- expect(result.current).toBe('first')
-
- await expect(
- wait(
- () => {
- if (result.current === 'second') {
- throw new Error('Something Unexpected')
- }
- return result.current === 'third'
- },
- {
- suppressErrors: false
- }
- )
- ).rejects.toThrow(Error('Something Unexpected'))
- })
-
- test('should reject if callback immediately throws error (deprecated)', async () => {
- const { result, wait } = renderHook(() => useSequence('first', 'second', 'third'))
-
- expect(result.current).toBe('first')
-
- await expect(
- wait(
- () => {
- throw new Error('Something Unexpected')
- },
- {
- suppressErrors: false
- }
- )
- ).rejects.toThrow(Error('Something Unexpected'))
- })
-
- test('should wait for truthy value (deprecated)', async () => {
- const { result, wait } = renderHook(() => useSequence('first', 'second', 'third'))
-
- expect(result.current).toBe('first')
-
- await wait(() => result.current === 'third')
-
- expect(result.current).toBe('third')
- })
-
- test('should reject if timeout exceeded when waiting for expectation to pass (deprecated)', async () => {
- const { result, wait } = renderHook(() => useSequence('first', 'second', 'third'))
-
- expect(result.current).toBe('first')
-
- await expect(
- wait(
- () => {
- expect(result.current).toBe('third')
- },
- { timeout: 75 }
- )
- ).rejects.toThrow(Error('Timed out in wait after 75ms.'))
- })
})
diff --git a/test/autoCleanup.disabled.js b/test/autoCleanup.disabled.ts
similarity index 89%
rename from test/autoCleanup.disabled.js
rename to test/autoCleanup.disabled.ts
index d11f9314..35cbf91a 100644
--- a/test/autoCleanup.disabled.js
+++ b/test/autoCleanup.disabled.ts
@@ -4,10 +4,11 @@ import { useEffect } from 'react'
// then we DON'T auto-wire up the afterEach for folks
describe('skip auto cleanup (disabled) tests', () => {
let cleanupCalled = false
- let renderHook
+ let renderHook: (arg0: () => void) => void
beforeAll(() => {
process.env.RHTL_SKIP_AUTO_CLEANUP = 'true'
+ // eslint-disable-next-line
renderHook = require('../src').renderHook
})
diff --git a/test/autoCleanup.noAfterEach.js b/test/autoCleanup.noAfterEach.ts
similarity index 80%
rename from test/autoCleanup.noAfterEach.js
rename to test/autoCleanup.noAfterEach.ts
index 9b894e00..cd30a841 100644
--- a/test/autoCleanup.noAfterEach.js
+++ b/test/autoCleanup.noAfterEach.ts
@@ -4,11 +4,13 @@ import { useEffect } from 'react'
// then we DON'T auto-wire up the afterEach for folks
describe('skip auto cleanup (no afterEach) tests', () => {
let cleanupCalled = false
- let renderHook
+ let renderHook: (arg0: () => void) => void
beforeAll(() => {
+ // @ts-expect-error Turning off AfterEach -- ignore Jest LifeCycle Type
// eslint-disable-next-line no-global-assign
afterEach = false
+ // eslint-disable-next-line
renderHook = require('../').renderHook
})
diff --git a/test/autoCleanup.js b/test/autoCleanup.ts
similarity index 100%
rename from test/autoCleanup.js
rename to test/autoCleanup.ts
diff --git a/test/cleanup.js b/test/cleanup.ts
similarity index 92%
rename from test/cleanup.js
rename to test/cleanup.ts
index 05dba6dc..1eafffbf 100644
--- a/test/cleanup.js
+++ b/test/cleanup.ts
@@ -21,8 +21,8 @@ describe('cleanup tests', () => {
})
test('should cleanup all rendered hooks', async () => {
- const cleanupCalled = []
- const hookWithCleanup = (id) => {
+ const cleanupCalled: boolean[] = []
+ const hookWithCleanup = (id: number) => {
useEffect(() => {
return () => {
cleanupCalled[id] = true
@@ -40,7 +40,7 @@ describe('cleanup tests', () => {
})
test('should call cleanups in reverse order', async () => {
- const callSequence = []
+ const callSequence: string[] = []
addCleanup(() => {
callSequence.push('cleanup')
})
@@ -62,7 +62,7 @@ describe('cleanup tests', () => {
})
test('should wait for async cleanup', async () => {
- const callSequence = []
+ const callSequence: string[] = []
addCleanup(() => {
callSequence.push('cleanup')
})
@@ -85,7 +85,7 @@ describe('cleanup tests', () => {
})
test('should remove cleanup using removeCleanup', async () => {
- const callSequence = []
+ const callSequence: string[] = []
addCleanup(() => {
callSequence.push('cleanup')
})
@@ -110,7 +110,7 @@ describe('cleanup tests', () => {
})
test('should remove cleanup using returned handler', async () => {
- const callSequence = []
+ const callSequence: string[] = []
addCleanup(() => {
callSequence.push('cleanup')
})
diff --git a/test/customHook.js b/test/customHook.ts
similarity index 100%
rename from test/customHook.js
rename to test/customHook.ts
diff --git a/test/errorHook.js b/test/errorHook.ts
similarity index 95%
rename from test/errorHook.js
rename to test/errorHook.ts
index 55e425e2..e507bb92 100644
--- a/test/errorHook.js
+++ b/test/errorHook.ts
@@ -2,15 +2,15 @@ import { useState, useEffect } from 'react'
import { renderHook } from '../src'
describe('error hook tests', () => {
- function useError(throwError) {
+ function useError(throwError: boolean) {
if (throwError) {
throw new Error('expected')
}
return true
}
- function useAsyncError(throwError) {
- const [value, setValue] = useState()
+ function useAsyncError(throwError: boolean) {
+ const [value, setValue] = useState()
useEffect(() => {
const timeout = setTimeout(() => setValue(throwError), 100)
return () => clearTimeout(timeout)
@@ -18,7 +18,7 @@ describe('error hook tests', () => {
return useError(value)
}
- function useEffectError(throwError) {
+ function useEffectError(throwError: boolean) {
useEffect(() => {
useError(throwError)
}, [throwError])
diff --git a/test/resultHistory.js b/test/resultHistory.ts
similarity index 100%
rename from test/resultHistory.js
rename to test/resultHistory.ts
diff --git a/test/suspenseHook.js b/test/suspenseHook.ts
similarity index 76%
rename from test/suspenseHook.js
rename to test/suspenseHook.ts
index 6dcfdeae..8d696927 100644
--- a/test/suspenseHook.js
+++ b/test/suspenseHook.ts
@@ -1,10 +1,10 @@
import { renderHook } from '../src'
describe('suspense hook tests', () => {
- const cache = {}
- const fetchName = (isSuccessful) => {
+ const cache: { value?: Promise | string | Error } = {}
+ const fetchName = (isSuccessful: boolean) => {
if (!cache.value) {
- cache.value = new Promise((resolve, reject) => {
+ cache.value = new Promise((resolve, reject) => {
setTimeout(() => {
if (isSuccessful) {
resolve('Bob')
@@ -14,15 +14,15 @@ describe('suspense hook tests', () => {
}, 50)
})
.then((value) => (cache.value = value))
- .catch((e) => (cache.value = e))
+ .catch((e: Error) => (cache.value = e))
}
return cache.value
}
const useFetchName = (isSuccessful = true) => {
const name = fetchName(isSuccessful)
- if (typeof name.then === 'function' || name instanceof Error) {
- throw name
+ if (name instanceof Promise || name instanceof Error) {
+ throw name as unknown
}
return name
}
diff --git a/test/tsconfig.json b/test/tsconfig.json
new file mode 100644
index 00000000..48209b56
--- /dev/null
+++ b/test/tsconfig.json
@@ -0,0 +1,8 @@
+{
+ "extends": "../tsconfig.json",
+ "compilerOptions": {
+ "declaration": false
+ },
+ "exclude": [],
+ "include": ["."]
+}
diff --git a/test/useContext.js b/test/useContext.tsx
similarity index 89%
rename from test/useContext.js
rename to test/useContext.tsx
index 4bcbe774..03bc19f4 100644
--- a/test/useContext.js
+++ b/test/useContext.tsx
@@ -15,7 +15,7 @@ describe('useContext tests', () => {
test('should get value from context provider', () => {
const TestContext = createContext('foo')
- const wrapper = ({ children }) => (
+ const wrapper: React.FC = ({ children } ) => (
{children}
)
@@ -29,7 +29,7 @@ describe('useContext tests', () => {
const value = { current: 'bar' }
- const wrapper = ({ children }) => (
+ const wrapper: React.FC = ({ children }) => (
{children}
)
@@ -45,7 +45,8 @@ describe('useContext tests', () => {
test('should update value in context when props are updated', () => {
const TestContext = createContext('foo')
- const wrapper = ({ current, children }) => (
+
+ const wrapper: React.FC<{current: string}> = ({ current, children }) => (
{children}
)
diff --git a/test/useEffect.js b/test/useEffect.ts
similarity index 89%
rename from test/useEffect.js
rename to test/useEffect.ts
index 9e120e07..cad9d0f3 100644
--- a/test/useEffect.js
+++ b/test/useEffect.ts
@@ -3,7 +3,7 @@ import { renderHook } from '../src'
describe('useEffect tests', () => {
test('should handle useEffect hook', () => {
- const sideEffect = { 1: false, 2: false }
+ const sideEffect: { [key: number]: boolean } = { 1: false, 2: false }
const { rerender, unmount } = renderHook(
({ id }) => {
@@ -32,7 +32,7 @@ describe('useEffect tests', () => {
})
test('should handle useLayoutEffect hook', () => {
- const sideEffect = { 1: false, 2: false }
+ const sideEffect: { [key: number]: boolean } = { 1: false, 2: false }
const { rerender, unmount } = renderHook(
({ id }) => {
diff --git a/test/useMemo.js b/test/useMemo.ts
similarity index 100%
rename from test/useMemo.js
rename to test/useMemo.ts
diff --git a/test/useReducer.js b/test/useReducer.ts
similarity index 79%
rename from test/useReducer.js
rename to test/useReducer.ts
index 114f579b..7b98431a 100644
--- a/test/useReducer.js
+++ b/test/useReducer.ts
@@ -3,7 +3,8 @@ import { renderHook, act } from '../src'
describe('useReducer tests', () => {
test('should handle useReducer hook', () => {
- const reducer = (state, action) => (action.type === 'inc' ? state + 1 : state)
+ const reducer = (state: number, action: { type: string }) =>
+ action.type === 'inc' ? state + 1 : state
const { result } = renderHook(() => useReducer(reducer, 0))
const [initialState, dispatch] = result.current
diff --git a/test/useRef.js b/test/useRef.ts
similarity index 92%
rename from test/useRef.js
rename to test/useRef.ts
index b9dbefe3..9d3851ff 100644
--- a/test/useRef.js
+++ b/test/useRef.ts
@@ -13,7 +13,7 @@ describe('useHook tests', () => {
test('should handle useImperativeHandle hook', () => {
const { result } = renderHook(() => {
- const ref = useRef()
+ const ref = useRef boolean>>({})
useImperativeHandle(ref, () => ({
fakeImperativeMethod: () => true
}))
diff --git a/test/useState.js b/test/useState.ts
similarity index 100%
rename from test/useState.js
rename to test/useState.ts
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 00000000..1337ac30
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,8 @@
+{
+ "extends": "./node_modules/kcd-scripts/shared-tsconfig.json",
+ "compilerOptions": {
+ "allowJs": true,
+ "target": "ES6"
+ },
+ "exclude": ["./test"]
+}