Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for TypeScript #8

Merged
merged 10 commits into from
Mar 3, 2019
9 changes: 9 additions & 0 deletions .all-contributorsrc
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@
"test",
"tool"
]
},
{
"login": "otofu-square",
"name": "otofu-square",
"avatar_url": "https://avatars0.githubusercontent.com/u/10118235?v=4",
"profile": "https://github.com/otofu-square",
"contributions": [
"code"
]
}
]
}
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Simple component wrapper and utilities for testing React hooks.
[![downloads](https://img.shields.io/npm/dm/react-hooks-testing-library.svg?style=flat-square)](http://www.npmtrends.com/react-hooks-testing-library)
[![MIT License](https://img.shields.io/npm/l/react-hooks-testing-library.svg?style=flat-square)](https://github.com/mpeyper/react-hooks-testing-library/blob/master/LICENSE.md)

[![All Contributors](https://img.shields.io/badge/all_contributors-1-orange.svg?style=flat-square)](#contributors)
[![All Contributors](https://img.shields.io/badge/all_contributors-2-orange.svg?style=flat-square)](#contributors)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)
[![Code of Conduct](https://img.shields.io/badge/code%20of-conduct-ff69b4.svg?style=flat-square)](https://github.com/mpeyper/react-hooks-testing-library/blob/master/CODE_OF_CONDUCT.md)

Expand Down Expand Up @@ -156,8 +156,7 @@ Thanks goes to these wonderful people ([emoji key](https://github.com/kentcdodds

<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore -->
| [<img src="https://avatars0.githubusercontent.com/u/23029903?v=4" width="100px;"/><br /><sub><b>Michael Peyper</b></sub>](https://github.com/mpeyper)<br />[💻](https://github.com/mpeyper/react-hooks-testing-library/commits?author=mpeyper "Code") [🎨](#design-mpeyper "Design") [📖](https://github.com/mpeyper/react-hooks-testing-library/commits?author=mpeyper "Documentation") [🤔](#ideas-mpeyper "Ideas, Planning, & Feedback") [🚇](#infra-mpeyper "Infrastructure (Hosting, Build-Tools, etc)") [📦](#platform-mpeyper "Packaging/porting to new platform") [⚠️](https://github.com/mpeyper/react-hooks-testing-library/commits?author=mpeyper "Tests") [🔧](#tool-mpeyper "Tools") |
| :---: |
<table><tr><td align="center"><a href="https://github.com/mpeyper"><img src="https://avatars0.githubusercontent.com/u/23029903?v=4" width="100px;" alt="Michael Peyper"/><br /><sub><b>Michael Peyper</b></sub></a><br /><a href="https://github.com/mpeyper/react-hooks-testing-library/commits?author=mpeyper" title="Code">💻</a> <a href="#design-mpeyper" title="Design">🎨</a> <a href="https://github.com/mpeyper/react-hooks-testing-library/commits?author=mpeyper" title="Documentation">📖</a> <a href="#ideas-mpeyper" title="Ideas, Planning, & Feedback">🤔</a> <a href="#infra-mpeyper" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="#platform-mpeyper" title="Packaging/porting to new platform">📦</a> <a href="https://github.com/mpeyper/react-hooks-testing-library/commits?author=mpeyper" title="Tests">⚠️</a> <a href="#tool-mpeyper" title="Tools">🔧</a></td><td align="center"><a href="https://github.com/otofu-square"><img src="https://avatars0.githubusercontent.com/u/10118235?v=4" width="100px;" alt="otofu-square"/><br /><sub><b>otofu-square</b></sub></a><br /><a href="https://github.com/mpeyper/react-hooks-testing-library/commits?author=otofu-square" title="Code">💻</a></td></tr></table>

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

Expand Down
18 changes: 18 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { cleanup, act, RenderOptions, RenderResult } from 'react-testing-library'

export function renderHook<P, R>(
callback: (props: P) => R,
options?: {
initialProps?: P
} & RenderOptions
): {
readonly result: {
current: R
}
readonly unmount: RenderResult['unmount']
readonly rerender: (hookProps?: P) => void
Copy link
Contributor

@danielkcz danielkcz Mar 2, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feels unnecessary to have ? here. If the P is inferred as undefined, it should be ok. Otherwise, it should be required to pass the props if there were some initially to avoid surprising results.

Suggested change
readonly rerender: (hookProps?: P) => void
readonly rerender: (hookProps: P) => void

Copy link
Contributor Author

@otofu-square otofu-square Mar 3, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the implementation of the rerender function, it seems that hookProps.current is assigned as a default value. (hookProps.current is the same as initialProps)
https://github.com/mpeyper/react-hooks-testing-library/blob/f7cd61035d8fb08cbfac376a5a8da1780708a64e/src/index.js#L26

As long as I see this, we can call rerender function with no argument or initialProps.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, so it will use initialProps if none are passed. Makes sense I guess although it feels less explicit and might be confusing for tests.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct. Subsequent rerenders will use the previously supplied props until new props are supplied.

The idea is that the props don't change until the hook is rendered with new props, so hooks that use a conditional array (i.e. useEffect, useLayoutEffect, useMemo and useCallback) can be reliably tested.

}

export const testHook: typeof renderHook
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'll be unnecessary someday, but it 's so smart 👍


export { cleanup, act }
43 changes: 40 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"version": "0.3.4",
"description": "Simple component wrapper for testing React hooks",
"main": "lib/index.js",
"typings": "./index.d.ts",
"author": "Michael Peyper",
"repository": {
"type": "git",
Expand All @@ -26,6 +27,7 @@
"@babel/plugin-transform-modules-commonjs": "^7.2.0",
"@babel/preset-env": "^7.3.4",
"@babel/preset-react": "^7.0.0",
"@types/react": "^16.8.5",
Copy link
Contributor

@danielkcz danielkcz Mar 2, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where does it depend on React types actually? I don't see any reference to it.

Suggested change
"@types/react": "^16.8.5",

Copy link
Contributor Author

@otofu-square otofu-square Mar 3, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"all-contributors-cli": "^6.1.2",
"babel-eslint": "^10.0.1",
"babel-plugin-module-resolver": "^3.2.0",
Expand All @@ -39,7 +41,9 @@
"prettier-eslint": "^8.8.2",
"prettier-eslint-cli": "^4.7.1",
"react": "^16.8.3",
"react-dom": "^16.8.3"
"react-dom": "^16.8.3",
"typescript": "^3.3.3333",
"typings-tester": "^0.3.2"
},
"peerDependencies": {
"react": "^16.8.0",
Expand Down
7 changes: 7 additions & 0 deletions test/typescript.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { checkDirectory } from 'typings-tester'

describe('TypeScript definitions', function() {
it('should compile against index.d.ts', () => {
checkDirectory(__dirname + '/typescript')
})
})
66 changes: 66 additions & 0 deletions test/typescript/renderHook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { useState, useCallback, useEffect } from 'react'
import { renderHook } from 'react-hooks-testing-library'

const useCounter = (initialCount: number = 0) => {
const [count, setCount] = useState(initialCount)
const incrementBy = useCallback(
(n: number) => {
setCount(count + n)
},
[count]
)
const decrementBy = useCallback(
(n: number) => {
setCount(count - n)
},
[count]
)
return {
count,
incrementBy,
decrementBy
}
}

function checkTypesWithNoInitialProps() {
const { result, unmount, rerender } = renderHook(() => useCounter())

// check types
const _result: {
current: {
count: number
incrementBy: (_: number) => void
decrementBy: (_: number) => void
}
} = result
const _unmount: () => boolean = unmount
const _rerender: () => void = rerender
}

function checkTypesWithInitialProps() {
const { result, unmount, rerender } = renderHook(({ count }) => useCounter(count), {
initialProps: { count: 10 }
})

// check types
const _result: {
current: {
count: number
incrementBy: (_: number) => void
decrementBy: (_: number) => void
}
} = result
const _unmount: () => boolean = unmount
const _rerender: (_?: { count: number }) => void = rerender
}

function checkTypesWhenHookReturnsVoid() {
const { result, unmount, rerender } = renderHook(() => useEffect(() => {}))

// check types
const _result: {
current: void
} = result
const _unmount: () => boolean = unmount
const _rerender: () => void = rerender
}
10 changes: 10 additions & 0 deletions test/typescript/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"compilerOptions": {
"lib": ["es2015", "dom"],
"strict": true,
"baseUrl": "../../",
"paths": {
"react-hooks-testing-library": ["index.d.ts"]
}
}
}