From bb28d93016d67457822b31b97ee69b733161da0d Mon Sep 17 00:00:00 2001 From: Sergey Krylov Date: Thu, 18 Apr 2024 06:33:30 +0300 Subject: [PATCH] feat(hoc): add withProvider HOC --- src/shared/hoc/withProvider/index.js | 1 + .../hoc/withProvider/ui/withProvider.spec.jsx | 99 +++++++++++++++++++ .../hoc/withProvider/ui/withProvider.ui.jsx | 9 ++ 3 files changed, 109 insertions(+) create mode 100644 src/shared/hoc/withProvider/index.js create mode 100644 src/shared/hoc/withProvider/ui/withProvider.spec.jsx create mode 100644 src/shared/hoc/withProvider/ui/withProvider.ui.jsx diff --git a/src/shared/hoc/withProvider/index.js b/src/shared/hoc/withProvider/index.js new file mode 100644 index 0000000..ee102a5 --- /dev/null +++ b/src/shared/hoc/withProvider/index.js @@ -0,0 +1 @@ +export { default as withProvider } from './ui/withProvider.ui'; diff --git a/src/shared/hoc/withProvider/ui/withProvider.spec.jsx b/src/shared/hoc/withProvider/ui/withProvider.spec.jsx new file mode 100644 index 0000000..65b10c6 --- /dev/null +++ b/src/shared/hoc/withProvider/ui/withProvider.spec.jsx @@ -0,0 +1,99 @@ +import { fireEvent, render, screen } from '@testing-library/react'; +import PropTypes from 'prop-types'; +import React, { useContext, useMemo, useState } from 'react'; + +import { withProvider } from 'shared/hoc/withProvider/index'; + +describe('Test withProvider', () => { + const renderCounter = () => { + const TestContext = React.createContext({}); + + const TestProvider = (props) => { + const { children } = props; + + const [testState, setTestState] = useState(100); + + const contextValue = useMemo(() => ({ + testState, + setTestState, + }), [testState]); + + return ( + + {children} + + ); + }; + + TestProvider.propTypes = { + children: PropTypes.node.isRequired, + }; + + const Counter = () => { + const { + testState, + setTestState, + } = useContext(TestContext); + + return ( + <> + + + + {testState} + + + + + + ); + }; + + const CounterWithTestProvider = withProvider(TestProvider)(Counter); + + render(); + }; + + test('initial state', () => { + renderCounter(); + + const counterElem = screen.getByTestId('counter'); + expect(counterElem).toHaveTextContent(100); + }); + + test('change state - increment', () => { + renderCounter(); + + const plusBtn = screen.getByTestId('plus-btn'); + fireEvent.click(plusBtn); + + const counterElem = screen.getByTestId('counter'); + expect(counterElem).toHaveTextContent(101); + }); + + test('change state - decrement', () => { + renderCounter(); + + const minusBtn = screen.getByTestId('minus-btn'); + fireEvent.click(minusBtn); + + const counterElem = screen.getByTestId('counter'); + expect(counterElem).toHaveTextContent(99); + }); +}); diff --git a/src/shared/hoc/withProvider/ui/withProvider.ui.jsx b/src/shared/hoc/withProvider/ui/withProvider.ui.jsx new file mode 100644 index 0000000..3f3b48f --- /dev/null +++ b/src/shared/hoc/withProvider/ui/withProvider.ui.jsx @@ -0,0 +1,9 @@ +// todo fix eslint +// eslint-disable-next-line react/function-component-definition +const withProvider = (Provider) => (Component) => (...params) => ( + + + +); + +export default withProvider;