jest-react-hooks-shallow
Advanced tools
Comparing version 1.3.0 to 1.4.0
module.exports = { | ||
preset: 'ts-jest', | ||
testPathIgnorePatterns: ['sample-tests-and-e2e-tests'] | ||
testPathIgnorePatterns: ['samples-and-e2e-tests'] | ||
}; |
interface Jest { | ||
requireActual: (module: string) => object; | ||
mock: (module: string, mock: object) => void; | ||
mock: (module: string, factory?: () => unknown, options?: { | ||
virtual?: boolean; | ||
}) => unknown; | ||
} | ||
declare const enableHooks: (jestInstance: Jest) => void; | ||
interface EnableHooksOptions { | ||
dontMockByDefault: boolean; | ||
} | ||
declare const enableHooks: (jestInstance: Jest, { dontMockByDefault }?: EnableHooksOptions) => void; | ||
declare const withHooks: (testFn: () => void) => void; | ||
declare const withoutHooks: (testFn: () => void) => void; | ||
/** | ||
* @deprecated | ||
*/ | ||
declare const disableHooks: () => void; | ||
declare const reenableHooks: () => void; | ||
export default enableHooks; | ||
export { disableHooks, reenableHooks }; | ||
export { disableHooks, reenableHooks, withHooks, withoutHooks }; |
@@ -6,11 +6,50 @@ "use strict"; | ||
let originalUseLayoutEffect; | ||
const useEffectMock = jest.fn().mockImplementation(mock_use_effect_1.default()); | ||
const useLayoutEffectMock = jest.fn().mockImplementation(mock_use_effect_1.default()); | ||
const enableHooks = (jestInstance) => { | ||
const useEffectMock = jest.fn(); | ||
const useLayoutEffectMock = jest.fn(); | ||
const enableHooks = (jestInstance, { dontMockByDefault } = { dontMockByDefault: false }) => { | ||
const react = jestInstance.requireActual('react'); | ||
originalUseEffect = react.useEffect; | ||
originalUseLayoutEffect = react.useLayoutEffect; | ||
if (dontMockByDefault) { | ||
useEffectMock.mockImplementation(originalUseEffect); | ||
useLayoutEffectMock.mockImplementation(originalUseLayoutEffect); | ||
} | ||
else { | ||
useEffectMock.mockImplementation(mock_use_effect_1.default()); | ||
useLayoutEffectMock.mockImplementation(mock_use_effect_1.default()); | ||
} | ||
jestInstance.mock('react', () => (Object.assign(Object.assign({}, react), { useEffect: useEffectMock, useLayoutEffect: useLayoutEffectMock }))); | ||
}; | ||
const withHooks = (testFn) => { | ||
useEffectMock.mockImplementation(mock_use_effect_1.default()); | ||
useLayoutEffectMock.mockImplementation(mock_use_effect_1.default()); | ||
try { | ||
testFn(); | ||
} | ||
finally { | ||
useEffectMock.mockImplementation(originalUseEffect); | ||
useLayoutEffectMock.mockImplementation(originalUseLayoutEffect); | ||
} | ||
}; | ||
exports.withHooks = withHooks; | ||
const withoutHooks = (testFn) => { | ||
if (!originalUseEffect) { | ||
throw new Error('Cannot call `disableHooks()` if `enableHooks()` has not been invoked'); | ||
} | ||
useEffectMock.mockImplementation(originalUseEffect); | ||
useLayoutEffectMock.mockImplementation(originalUseLayoutEffect); | ||
try { | ||
testFn(); | ||
} | ||
finally { | ||
useEffectMock.mockImplementation(mock_use_effect_1.default()); | ||
useLayoutEffectMock.mockImplementation(mock_use_effect_1.default()); | ||
} | ||
}; | ||
exports.withoutHooks = withoutHooks; | ||
/** | ||
* @deprecated | ||
*/ | ||
const disableHooks = () => { | ||
console.warn('`disableHooks()` is deprecated. Please, use `withoutHooks()` instead'); | ||
if (!originalUseEffect) { | ||
@@ -24,2 +63,3 @@ throw new Error('Cannot call `disableHooks()` if `enableHooks()` has not been invoked'); | ||
const reenableHooks = () => { | ||
console.warn('`reenableHooks()` is deprecated.'); | ||
useEffectMock.mockImplementation(mock_use_effect_1.default()); | ||
@@ -26,0 +66,0 @@ useLayoutEffectMock.mockImplementation(mock_use_effect_1.default()); |
{ | ||
"name": "jest-react-hooks-shallow", | ||
"version": "1.3.0", | ||
"version": "1.4.0", | ||
"description": "React Hooks for shallow rendering", | ||
@@ -14,3 +14,5 @@ "homepage": "https://github.com/mikeborozdin/jest-react-hooks-shallow", | ||
"test:unit": "jest", | ||
"test:e2e": "cd sample-tests-and-e2e-tests && npm i && npm test && cd ..", | ||
"test:e2e:with-mocking-by-default": "cd samples-and-e2e-tests/with-mocking-by-default && npm i && npm test && cd ../..", | ||
"test:e2e:without-mocking-by-default": "cd samples-and-e2e-tests/without-mocking-by-default && npm i && npm test && cd ../..", | ||
"test:e2e": "npm run test:e2e:with-mocking-by-default && npm run test:e2e:without-mocking-by-default &", | ||
"test": "npm run test:unit && npm run test:e2e", | ||
@@ -17,0 +19,0 @@ "lint": "eslint ./src/**/*.ts" |
jest-react-hooks-shallow | ||
==== | ||
![Follow me on Twitter](https://img.shields.io/twitter/follow/mikeborozdin?style=social) | ||
Short Story | ||
@@ -31,2 +33,4 @@ ==== | ||
If you have a lot tests relying on `mount()`, please check [Usage with `mount()` section](#usage-with-mount). | ||
Testing | ||
@@ -109,44 +113,63 @@ ==== | ||
There have been a few issues reporting problems when using the library on the tests that rely on `mount()`. | ||
There have been a reported problems about using the library on tests that rely on `mount()`. | ||
You don't need this library to trigger `useEffect()` and `useLayoutEffect()` when doing full rendering with `mount()`. However, you may have a mix of tests that rely both rely on `shallow()` and `mount()`. In those cases, you may run into issues with the tests that call `mount()`. | ||
Version `1.3.0` of this library provides a solution for that. | ||
Version `1.4.0` of this library provides two solutions for that: | ||
If you have a test that uses `mount()` simply call `disableHooks()` before mounting a component: | ||
* Initialise the library with `enableHooks(jest, { dontMockByDefault: true })` and wrap tests for hook components relying on `shallow()` with `withHooks()` | ||
* That's useful when you have a lot of tests with `mount()` | ||
* Wrap `mount()`-based tests for hooks components with `withoutHooks()`. | ||
Option #1 - `{ dontMockByDefault: true }` | ||
---- | ||
That will disable effect hooks mocks by default. And you can wrap tests with that rely on `shallow()` and hooks with `withHooks()`, e.g.: | ||
**setupJest.js** | ||
```js | ||
import { disableHooks } from 'jest-react-hooks-shallow'; | ||
```js | ||
import enableHooks from 'jest-react-hooks-shallow'; | ||
test('Full rendering with `mount()`', () => { | ||
disableHooks(); | ||
const component = mount(<App />); | ||
// your test code | ||
}); | ||
// pass an instance of jest to `enableHooks()` | ||
enableHooks(jest, { dontMockByDefault: true }); | ||
``` | ||
Now, that will disable hooks for the test in the same suite which rely on `shallow()`. So you need to re-enable them by calling `reenableHooks()`. | ||
**App.test.js** | ||
```js | ||
import { disableHooks, reenableHooks } from 'jest-react-hooks-shallow'; | ||
import { withHooks } from 'jest-react-hooks-shallow'; | ||
test('Full rendering with `mount()`', () => { | ||
disableHooks(); | ||
test('Shallow rendering of component with hooks', () => { | ||
withHooks(() => { | ||
const component = mount(<App />); | ||
// your test code | ||
const component = shallow(<App />); | ||
// your test code | ||
}); | ||
}); | ||
test('Back to shallow rendering with', () => { | ||
reenableHooks(); | ||
Option 21 - `withoutHook()` | ||
const component = shallow(<App />); | ||
// your test code | ||
}); | ||
``` | ||
Or you can enable hooks in shallow by default and surround tests using `mount()` with `withoutHooks()`, e.g.: | ||
```js | ||
import { withoutHooks } from 'jest-react-hooks-shallow'; | ||
test('Full rendering of component with hooks', () => { | ||
withoutHooks(() => { | ||
const component = mount(<App />); | ||
// your test code | ||
}); | ||
}); | ||
``` | ||
`disableHooks()` and `reenableHooks()` are now deprecated | ||
---- | ||
`disableHooks()` and `reenableHooks()` from version `1.3.0` are now marked deprecated. You can still use them, but it's not recommended.`. | ||
Examples | ||
---- | ||
Please, see [use-effect-component.test.jsx](sample-tests-and-e2e-tests/src/use-effect/use-effect-component.test.jsx) for the examples of that. Namely, have a look at the test called `effects mockable when used with mount() and disableHooks()` and the one that comes after it. | ||
Please, see two samples projects in the [samples-and-e2e-tests](samples-and-e2e-tests/) as an example. | ||
@@ -159,4 +182,2 @@ How does that work? | ||
``` | ||
Dependencies | ||
@@ -163,0 +184,0 @@ ==== |
@@ -5,3 +5,3 @@ import mockUseEffect from "./mock-use-effect/mock-use-effect"; | ||
requireActual: (module: string) => object; | ||
mock: (module: string, mock: object) => void; | ||
mock: (module: string, factory?: () => unknown, options?: { virtual?: boolean }) => unknown; | ||
} | ||
@@ -14,9 +14,13 @@ | ||
interface EnableHooksOptions { | ||
dontMockByDefault: boolean; | ||
} | ||
let originalUseEffect: (...args: unknown[]) => unknown; | ||
let originalUseLayoutEffect: (...args: unknown[]) => unknown; | ||
const useEffectMock = jest.fn().mockImplementation(mockUseEffect()); | ||
const useLayoutEffectMock = jest.fn().mockImplementation(mockUseEffect()); | ||
const useEffectMock = jest.fn(); | ||
const useLayoutEffectMock = jest.fn(); | ||
const enableHooks = (jestInstance: Jest): void => { | ||
const enableHooks = (jestInstance: Jest, { dontMockByDefault }: EnableHooksOptions = { dontMockByDefault: false }): void => { | ||
const react = jestInstance.requireActual('react') as React; | ||
@@ -27,2 +31,10 @@ | ||
if (dontMockByDefault) { | ||
useEffectMock.mockImplementation(originalUseEffect); | ||
useLayoutEffectMock.mockImplementation(originalUseLayoutEffect); | ||
} else { | ||
useEffectMock.mockImplementation(mockUseEffect()); | ||
useLayoutEffectMock.mockImplementation(mockUseEffect()); | ||
} | ||
jestInstance.mock('react', () => ({ | ||
@@ -35,3 +47,36 @@ ...react, | ||
const withHooks = (testFn: () => void): void => { | ||
useEffectMock.mockImplementation(mockUseEffect()); | ||
useLayoutEffectMock.mockImplementation(mockUseEffect()); | ||
try { | ||
testFn(); | ||
} finally { | ||
useEffectMock.mockImplementation(originalUseEffect); | ||
useLayoutEffectMock.mockImplementation(originalUseLayoutEffect); | ||
} | ||
}; | ||
const withoutHooks = (testFn: () => void): void => { | ||
if (!originalUseEffect) { | ||
throw new Error('Cannot call `disableHooks()` if `enableHooks()` has not been invoked') | ||
} | ||
useEffectMock.mockImplementation(originalUseEffect); | ||
useLayoutEffectMock.mockImplementation(originalUseLayoutEffect); | ||
try { | ||
testFn(); | ||
} finally { | ||
useEffectMock.mockImplementation(mockUseEffect()); | ||
useLayoutEffectMock.mockImplementation(mockUseEffect()); | ||
} | ||
}; | ||
/** | ||
* @deprecated | ||
*/ | ||
const disableHooks = (): void => { | ||
console.warn('`disableHooks()` is deprecated. Please, use `withoutHooks()` instead'); | ||
if (!originalUseEffect) { | ||
@@ -46,2 +91,4 @@ throw new Error('Cannot call `disableHooks()` if `enableHooks()` has not been invoked') | ||
const reenableHooks = (): void => { | ||
console.warn('`reenableHooks()` is deprecated.'); | ||
useEffectMock.mockImplementation(mockUseEffect()); | ||
@@ -53,2 +100,2 @@ useLayoutEffectMock.mockImplementation(mockUseEffect()); | ||
export { disableHooks, reenableHooks }; | ||
export { disableHooks, reenableHooks, withHooks, withoutHooks }; |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
1265708
47
31578
229
2