diff --git a/.babelrc b/.babelrc deleted file mode 100644 index 4d899c70..00000000 --- a/.babelrc +++ /dev/null @@ -1,12 +0,0 @@ -{ - "presets": [ - ["@babel/env", { "loose": true, "modules": false }], - "@babel/react" - ], - "plugins": [ - "@babel/plugin-transform-runtime", - "@babel/proposal-object-rest-spread", - ["module-resolver", { "alias": { "src": "./src" } }], - "@babel/transform-modules-commonjs" - ] -} diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 00000000..4594ebf4 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,5 @@ +node_modules +coverage +lib +.docz +site diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 00000000..d6c4554f --- /dev/null +++ b/.eslintrc @@ -0,0 +1,10 @@ +{ + "extends": "./node_modules/kcd-scripts/eslint.js", + "rules": { + "max-lines-per-function": "off", + "no-constant-condition": "off", + "no-await-in-loop": "off", + "react-hooks/rules-of-hooks": "off", + "no-console": "off" + } +} diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..6313b56c --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto eol=lf diff --git a/.github/ISSUE_TEMPLATE/---feature-request.md b/.github/ISSUE_TEMPLATE/---feature-request.md index 57c512c3..5523e27b 100644 --- a/.github/ISSUE_TEMPLATE/---feature-request.md +++ b/.github/ISSUE_TEMPLATE/---feature-request.md @@ -4,7 +4,6 @@ about: "I have a suggestion (and might want to implement myself \U0001F642)!" title: '' labels: enhancement assignees: '' - --- + + +- [react-hooks-testing-library](#react-hooks-testing-library) + - [The problem](#the-problem) + - [The solution](#the-solution) + - [When to use this library](#when-to-use-this-library) + - [When not to use this library](#when-not-to-use-this-library) + - [Example](#example) + - [`useCounter.js`](#usecounterjs) + - [`useCounter.test.js`](#usecountertestjs) + - [Installation](#installation) + - [Peer Dependencies](#peer-dependencies) + - [API](#api) + - [Contributors](#contributors) + - [Issues](#issues) + - [🐛 Bugs](#-bugs) + - [💡 Feature Requests](#-feature-requests) + - [❓ Questions](#-questions) + - [LICENSE](#license) + + +

react-hooks-testing-library

@@ -6,7 +29,7 @@ height="80" width="80" alt="ram" - src="https://raw.githubusercontent.com/testing-library/react-hooks-testing-library/master/other/ram.png" + src="https://raw.githubusercontent.com/testing-library/react-hooks-testing-library/master/public/ram.png" /> diff --git a/docs/api-reference.md b/docs/api-reference.md index b04f3739..117e755f 100644 --- a/docs/api-reference.md +++ b/docs/api-reference.md @@ -236,9 +236,9 @@ function waitForValueToChange(selector: function(): any, options?: { }): Promise ``` -Returns a `Promise` that resolves if the value returned from the provided selector changes. It is -expected that the [`result` of `renderHook`](/reference/api#result) will be used to select the -value for comparison. +Returns a `Promise` that resolves if the value returned from the provided selector changes. It is +expected that the [`result` of `renderHook`](/reference/api#result) will be used to select the value +for comparison. #### `interval` diff --git a/docs/introduction.md b/docs/introduction.md index 5ee07b33..70d2f505 100644 --- a/docs/introduction.md +++ b/docs/introduction.md @@ -11,7 +11,7 @@ route: '/' height="80" width="80" alt="ram" - src="https://raw.githubusercontent.com/mpeyper/react-hooks-testing-library/master/other/ram.png" + src="https://raw.githubusercontent.com/mpeyper/react-hooks-testing-library/master/public/ram.png" /> diff --git a/doczrc.js b/doczrc.js index ab9f0c00..965cfbe2 100644 --- a/doczrc.js +++ b/doczrc.js @@ -3,7 +3,7 @@ export default { files: '**/*.{md,mdx}', src: 'docs', dest: 'site', - public: './other', + public: './public', ignore: ['CODE_OF_CONDUCT.md', 'CONTRIBUTING.md', 'LICENSE.md'], htmlContext: { favicon: '/public/ram.png' diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 00000000..c2e6a069 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,6 @@ +const { jest: jestConfig } = require('kcd-scripts/config') + +module.exports = Object.assign(jestConfig, { + roots: ['/src', '/test'], + testMatch: ['/test/*.js'] +}) diff --git a/other/MAINTAINING.md b/other/MAINTAINING.md new file mode 100644 index 00000000..7ed41143 --- /dev/null +++ b/other/MAINTAINING.md @@ -0,0 +1,78 @@ +# Maintaining + + + + +**Table of Contents** + +- [Code of Conduct](#code-of-conduct) +- [Issues](#issues) +- [Pull Requests](#pull-requests) +- [Release](#release) +- [Thanks!](#thanks) + + + +This is documentation for maintainers of this project. + +## Code of Conduct + +Please review, understand, and be an example of it. Violations of the code of conduct are taken +seriously, even (especially) for maintainers. + +## Issues + +We want to support and build the community. We do that best by helping people learn to solve their +own problems. We have an issue template and hopefully most folks follow it. If it's not clear what +the issue is, invite them to create a minimal reproduction of what they're trying to accomplish or +the bug they think they've found. + +Once it's determined that a code change is necessary, point people to +[makeapullrequest.com](https://makeapullrequest.com) and invite them to make a pull request. If +they're the one who needs the feature, they're the one who can build it. If they need some hand +holding and you have time to lend a hand, please do so. It's an investment into another human being, +and an investment into a potential maintainer. + +Remember that this is open source, so the code is not yours, it's ours. If someone needs a change in +the codebase, you don't have to make it happen yourself. Commit as much time to the project as you +want/need to. Nobody can ask any more of you than that. + +## Pull Requests + +As a maintainer, you're fine to make your branches on the main repo or on your own fork. Either way +is fine. + +When we receive a pull request, a GitHub Action is kicked off automatically (see the +`.github/workflows/validate.yml` for what runs in the Action). We avoid merging anything that breaks +the GitHub Action. + +Please review PRs and focus on the code rather than the individual. You never know when this is +someone's first ever PR and we want their experience to be as positive as possible, so be uplifting +and constructive. + +When you merge the pull request, 99% of the time you should use the +[Squash and merge](https://help.github.com/articles/merging-a-pull-request/) feature. This keeps our +git history clean, but more importantly, this allows us to make any necessary changes to the commit +message so we release what we want to release. See the next section on Releases for more about that. + +## Release + +Our releases are automatic. They happen whenever code lands into `main`. A GitHub Action gets kicked +off and if it's successful, a tool called +[`semantic-release`](https://github.com/semantic-release/semantic-release) is used to automatically +publish a new release to npm as well as a changelog to GitHub. It is only able to determine the +version and whether a release is necessary by the git commit messages. With this in mind, **please +brush up on [the commit message convention][commit] which drives our releases.** + +> One important note about this: Please make sure that commit messages do NOT contain the words +> "BREAKING CHANGE" in them unless we want to push a major version. I've been burned by this more +> than once where someone will include "BREAKING CHANGE: None" and it will end up releasing a new +> major version. Not a huge deal honestly, but kind of annoying... + +## Thanks! + +Thank you so much for helping to maintain this project! + + +[commit]: https://github.com/conventional-changelog-archived-repos/conventional-changelog-angular/blob/ed32559941719a130bb0327f886d6a32a8cbc2ba/convention.md + diff --git a/other/manual-releases.md b/other/manual-releases.md new file mode 100644 index 00000000..44dcbaf3 --- /dev/null +++ b/other/manual-releases.md @@ -0,0 +1,43 @@ +# manual-releases + +This project has an automated release set up. So things are only released when there are useful +changes in the code that justify a release. But sometimes things get messed up one way or another +and we need to trigger the release ourselves. When this happens, simply bump the number below and +commit that with the following commit message based on your needs: + +**Major** + +``` +fix(release): manually release a major version + +There was an issue with a major release, so this manual-releases.md +change is to release a new major version. + +Reference: # + +BREAKING CHANGE: +``` + +**Minor** + +``` +feat(release): manually release a minor version + +There was an issue with a minor release, so this manual-releases.md +change is to release a new minor version. + +Reference: # +``` + +**Patch** + +``` +fix(release): manually release a patch version + +There was an issue with a patch release, so this manual-releases.md +change is to release a new patch version. + +Reference: # +``` + +The number of times we've had to do a manual release is: 0 diff --git a/package.json b/package.json index c6962a3a..4424672e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@testing-library/react-hooks", - "version": "3.4.2", + "version": "0.0.0-semantically-released", "description": "Simple and complete React hooks testing utilities that encourage good testing practices.", "main": "lib/index.js", "keywords": [ @@ -23,80 +23,35 @@ }, "license": "MIT", "scripts": { + "setup": "npm install && npm run validate -s", + "validate": "kcd-scripts validate", "prepare": "npm run build", - "build": "babel --out-dir lib src", - "format": "prettier-eslint --write \"**/*.{js,ts,json,yml,md,mdx}\"", + "build": "kcd-scripts build --out-dir lib", + "lint": "kcd-scripts lint", + "format": "kcd-scripts format", "coverage": "codecov", - "test": "jest", - "test:ci": "npm run test && npm run coverage", + "test": "kcd-scripts test", "docs:dev": "docz dev", "docs:build": "docz build", "contributors:add": "all-contributors add" }, "dependencies": { - "@babel/runtime": "^7.5.4", + "@babel/runtime": "^7.12.5", "@types/testing-library__react-hooks": "^3.4.0" }, "devDependencies": { - "@babel/cli": "7.12.8", - "@babel/core": "7.12.9", - "@babel/plugin-proposal-object-rest-spread": "7.12.1", - "@babel/plugin-transform-modules-commonjs": "7.12.1", - "@babel/plugin-transform-runtime": "7.12.1", - "@babel/preset-env": "7.12.7", - "@babel/preset-react": "7.12.7", "all-contributors-cli": "6.19.0", - "babel-eslint": "10.1.0", - "babel-plugin-module-resolver": "4.0.0", "codecov": "3.8.1", "docz": "2.3.1", + "docz-utils": "2.3.0", "docz-theme-default": "1.2.0", - "eslint": "7.14.0", - "eslint-config-prettier": "6.15.0", - "eslint-plugin-prettier": "3.2.0", - "husky": "4.3.0", - "jest": "26.6.3", - "lint-staged": "10.5.2", - "prettier": "2.2.1", - "prettier-eslint": "12.0.0", - "prettier-eslint-cli": "5.0.0", + "kcd-scripts": "^7.2.0", "react": "17.0.1", - "react-test-renderer": "17.0.1" + "react-test-renderer": "17.0.1", + "typescript": "^4.1.2" }, "peerDependencies": { "react": ">=16.9.0", "react-test-renderer": ">=16.9.0" - }, - "jest": { - "collectCoverage": true, - "coverageDirectory": "./coverage/", - "collectCoverageFrom": [ - "**/src/**" - ], - "testURL": "http://localhost/" - }, - "prettier": { - "printWidth": 100, - "semi": false, - "singleQuote": true, - "arrowParens": "always", - "proseWrap": "always", - "trailingComma": "none" - }, - "eslintConfig": { - "extends": [ - "plugin:prettier/recommended" - ], - "parser": "babel-eslint" - }, - "husky": { - "hooks": { - "pre-commit": "lint-staged" - } - }, - "lint-staged": { - "*.{js,ts,json,yml,md,mdx}": [ - "prettier-eslint --write" - ] } } diff --git a/other/ram.png b/public/ram.png similarity index 100% rename from other/ram.png rename to public/ram.png diff --git a/src/asyncUtils.js b/src/asyncUtils.js index 260d13f0..afb5ac7e 100644 --- a/src/asyncUtils.js +++ b/src/asyncUtils.js @@ -39,6 +39,7 @@ function asyncUtils(addResolver) { } const waitFor = async (callback, { interval, timeout, suppressErrors = true } = {}) => { + // eslint-disable-next-line consistent-return const checkResult = () => { try { const callbackResult = callback() diff --git a/test/asyncHook.test.js b/test/asyncHook.js similarity index 98% rename from test/asyncHook.test.js rename to test/asyncHook.js index 2ba12b4b..74d321a6 100644 --- a/test/asyncHook.test.js +++ b/test/asyncHook.js @@ -1,5 +1,5 @@ import { useState, useRef, useEffect } from 'react' -import { renderHook } from 'src' +import { renderHook } from '../src' describe('async hook tests', () => { const useSequence = (...values) => { @@ -17,7 +17,7 @@ describe('async hook tests', () => { return () => { clearInterval(interval) } - }, [...values]) + }, [otherValues]) return value } @@ -83,7 +83,7 @@ describe('async hook tests', () => { const { waitFor } = renderHook(() => null) let actual = 0 - let expected = 1 + const expected = 1 setTimeout(() => { actual = expected @@ -165,7 +165,7 @@ describe('async hook tests', () => { const { waitFor } = renderHook(() => null) let actual = 0 - let expected = 1 + const expected = 1 setTimeout(() => { actual = expected @@ -207,7 +207,7 @@ describe('async hook tests', () => { const { waitForValueToChange } = renderHook(() => null) let actual = 0 - let expected = 1 + const expected = 1 setTimeout(() => { actual = expected diff --git a/test/autoCleanup.disabled.test.js b/test/autoCleanup.disabled.js similarity index 92% rename from test/autoCleanup.disabled.test.js rename to test/autoCleanup.disabled.js index 7da342d5..d11f9314 100644 --- a/test/autoCleanup.disabled.test.js +++ b/test/autoCleanup.disabled.js @@ -8,7 +8,7 @@ describe('skip auto cleanup (disabled) tests', () => { beforeAll(() => { process.env.RHTL_SKIP_AUTO_CLEANUP = 'true' - renderHook = require('src').renderHook + renderHook = require('../src').renderHook }) test('first', () => { diff --git a/test/autoCleanup.test.js b/test/autoCleanup.js similarity index 93% rename from test/autoCleanup.test.js rename to test/autoCleanup.js index d644fe79..5dcdc1d1 100644 --- a/test/autoCleanup.test.js +++ b/test/autoCleanup.js @@ -1,5 +1,5 @@ import { useEffect } from 'react' -import { renderHook } from 'src' +import { renderHook } from '../src' // This verifies that by importing RHTL in an // environment which supports afterEach (like Jest) diff --git a/test/autoCleanup.noAfterEach.test.js b/test/autoCleanup.noAfterEach.js similarity index 86% rename from test/autoCleanup.noAfterEach.test.js rename to test/autoCleanup.noAfterEach.js index c1f51eea..9b894e00 100644 --- a/test/autoCleanup.noAfterEach.test.js +++ b/test/autoCleanup.noAfterEach.js @@ -7,8 +7,9 @@ describe('skip auto cleanup (no afterEach) tests', () => { let renderHook beforeAll(() => { + // eslint-disable-next-line no-global-assign afterEach = false - renderHook = require('src').renderHook + renderHook = require('../').renderHook }) test('first', () => { diff --git a/test/cleanup.test.js b/test/cleanup.js similarity index 95% rename from test/cleanup.test.js rename to test/cleanup.js index 8e7a44b0..05dba6dc 100644 --- a/test/cleanup.test.js +++ b/test/cleanup.js @@ -1,5 +1,5 @@ import { useEffect } from 'react' -import { renderHook, cleanup, addCleanup, removeCleanup } from 'src/pure' +import { renderHook, cleanup, addCleanup, removeCleanup } from '../src/pure' describe('cleanup tests', () => { test('should flush effects on cleanup', async () => { @@ -21,7 +21,7 @@ describe('cleanup tests', () => { }) test('should cleanup all rendered hooks', async () => { - let cleanupCalled = [] + const cleanupCalled = [] const hookWithCleanup = (id) => { useEffect(() => { return () => { @@ -40,7 +40,7 @@ describe('cleanup tests', () => { }) test('should call cleanups in reverse order', async () => { - let callSequence = [] + const callSequence = [] addCleanup(() => { callSequence.push('cleanup') }) @@ -62,7 +62,7 @@ describe('cleanup tests', () => { }) test('should wait for async cleanup', async () => { - let callSequence = [] + const callSequence = [] addCleanup(() => { callSequence.push('cleanup') }) @@ -85,7 +85,7 @@ describe('cleanup tests', () => { }) test('should remove cleanup using removeCleanup', async () => { - let callSequence = [] + const callSequence = [] addCleanup(() => { callSequence.push('cleanup') }) @@ -110,7 +110,7 @@ describe('cleanup tests', () => { }) test('should remove cleanup using returned handler', async () => { - let callSequence = [] + const callSequence = [] addCleanup(() => { callSequence.push('cleanup') }) diff --git a/test/customHook.test.js b/test/customHook.js similarity index 94% rename from test/customHook.test.js rename to test/customHook.js index 72dd1bac..871c5619 100644 --- a/test/customHook.test.js +++ b/test/customHook.js @@ -1,5 +1,5 @@ import { useState, useCallback } from 'react' -import { renderHook, act } from 'src' +import { renderHook, act } from '../src' describe('custom hook tests', () => { function useCounter() { diff --git a/test/errorHook.test.js b/test/errorHook.js similarity index 94% rename from test/errorHook.test.js rename to test/errorHook.js index dbfb21fa..55e425e2 100644 --- a/test/errorHook.test.js +++ b/test/errorHook.js @@ -1,5 +1,5 @@ import { useState, useEffect } from 'react' -import { renderHook } from 'src' +import { renderHook } from '../src' describe('error hook tests', () => { function useError(throwError) { @@ -21,7 +21,7 @@ describe('error hook tests', () => { function useEffectError(throwError) { useEffect(() => { useError(throwError) - }, []) + }, [throwError]) return true } @@ -115,6 +115,7 @@ describe('error hook tests', () => { Refer to https://github.com/testing-library/react-hooks-testing-library/issues/308 for more details. */ + // eslint-disable-next-line jest/no-disabled-tests describe.skip('effect', () => { test('should raise effect error', () => { const { result } = renderHook(() => useEffectError(true)) @@ -137,12 +138,9 @@ describe('error hook tests', () => { }) test('should reset effect error', () => { - const { result, waitForNextUpdate, rerender } = renderHook( - (throwError) => useEffectError(throwError), - { - initialProps: true - } - ) + const { result, rerender } = renderHook((throwError) => useEffectError(throwError), { + initialProps: true + }) expect(result.error).not.toBe(undefined) diff --git a/test/suspenseHook.test.js b/test/suspenseHook.js similarity index 97% rename from test/suspenseHook.test.js rename to test/suspenseHook.js index f7ece119..6dcfdeae 100644 --- a/test/suspenseHook.test.js +++ b/test/suspenseHook.js @@ -1,4 +1,4 @@ -import { renderHook } from 'src' +import { renderHook } from '../src' describe('suspense hook tests', () => { const cache = {} diff --git a/test/useContext.test.js b/test/useContext.js similarity index 97% rename from test/useContext.test.js rename to test/useContext.js index 2c22caca..4bcbe774 100644 --- a/test/useContext.test.js +++ b/test/useContext.js @@ -1,5 +1,5 @@ import React, { createContext, useContext } from 'react' -import { renderHook } from 'src' +import { renderHook } from '../src' describe('useContext tests', () => { test('should get default value from context', () => { diff --git a/test/useEffect.test.js b/test/useEffect.js similarity index 90% rename from test/useEffect.test.js rename to test/useEffect.js index d5c96d2f..9e120e07 100644 --- a/test/useEffect.test.js +++ b/test/useEffect.js @@ -1,9 +1,9 @@ import { useEffect, useLayoutEffect } from 'react' -import { renderHook } from 'src' +import { renderHook } from '../src' describe('useEffect tests', () => { test('should handle useEffect hook', () => { - const sideEffect = { [1]: false, [2]: false } + const sideEffect = { 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 = { 1: false, 2: false } const { rerender, unmount } = renderHook( ({ id }) => { diff --git a/test/useMemo.test.js b/test/useMemo.js similarity index 97% rename from test/useMemo.test.js rename to test/useMemo.js index efbf49d6..b2c452ab 100644 --- a/test/useMemo.test.js +++ b/test/useMemo.js @@ -1,5 +1,5 @@ import { useMemo, useCallback } from 'react' -import { renderHook } from 'src' +import { renderHook } from '../src' describe('useCallback tests', () => { test('should handle useMemo hook', () => { diff --git a/test/useReducer.test.js b/test/useReducer.js similarity index 91% rename from test/useReducer.test.js rename to test/useReducer.js index 092d585d..114f579b 100644 --- a/test/useReducer.test.js +++ b/test/useReducer.js @@ -1,5 +1,5 @@ import { useReducer } from 'react' -import { renderHook, act } from 'src' +import { renderHook, act } from '../src' describe('useReducer tests', () => { test('should handle useReducer hook', () => { diff --git a/test/useRef.test.js b/test/useRef.js similarity index 95% rename from test/useRef.test.js rename to test/useRef.js index 63dd241d..b9dbefe3 100644 --- a/test/useRef.test.js +++ b/test/useRef.js @@ -1,5 +1,5 @@ import { useRef, useImperativeHandle } from 'react' -import { renderHook } from 'src' +import { renderHook } from '../src' describe('useHook tests', () => { test('should handle useRef hook', () => { diff --git a/test/useState.test.js b/test/useState.js similarity index 83% rename from test/useState.test.js rename to test/useState.js index ebb943f8..42f3f8b0 100644 --- a/test/useState.test.js +++ b/test/useState.js @@ -1,5 +1,5 @@ import { useState } from 'react' -import { renderHook, act } from 'src' +import { renderHook, act } from '../src' describe('useState tests', () => { test('should use setState value', () => { @@ -13,7 +13,7 @@ describe('useState tests', () => { test('should update setState value using setter', () => { const { result } = renderHook(() => useState('foo')) - const [_, setValue] = result.current + const [ignoredValue, setValue] = result.current act(() => setValue('bar'))