UNPKG

react-native-use-modal-hooks

Version:

React hooks for displaying a modal window in React Native

176 lines (175 loc) 8.48 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); const React = __importStar(require("react")); const react_1 = require("react"); const react_2 = require("@testing-library/react"); const ModalProvider_1 = require("../ModalProvider"); const useModal_1 = require("../useModal"); // Helper to render components in modal context const renderWithProvider = (ui, options) => { const result = react_2.render(React.createElement(ModalProvider_1.ModalProvider, null, ui), options); return Object.assign(Object.assign({}, result), { // Override rerender to only update children of the provider rerender: (ui) => renderWithProvider(ui, { container: result.container }) }); }; describe("simple usage", () => { const App = () => { const [showModal, hideModal] = useModal_1.useModal(() => (React.createElement("div", null, React.createElement("p", null, "Modal content"), React.createElement("button", { onClick: hideModal }, "Hide modal")))); return React.createElement("button", { onClick: showModal }, "Show modal"); }; it("should show the modal", () => { const { getByText, queryByText } = renderWithProvider(React.createElement(App, null)); react_2.fireEvent.click(getByText("Show modal")); expect(queryByText("Modal content")).toBeTruthy(); }); it("should hide the modal", () => { const { getByText, queryByText } = renderWithProvider(React.createElement(App, null)); react_2.fireEvent.click(getByText("Show modal")); react_2.fireEvent.click(getByText("Hide modal")); expect(queryByText("Modal content")).not.toBeTruthy(); }); it("should hide the modal when parent component unmounts", () => { const { getByText, queryByText, rerender } = renderWithProvider(React.createElement("div", null, React.createElement(App, null))); react_2.fireEvent.click(getByText("Show modal")); rerender(React.createElement("div", null)); expect(queryByText("Modal content")).not.toBeTruthy(); }); }); describe("updating modal", () => { it("should work with internal state", () => { const App = () => { const [showModal] = useModal_1.useModal(() => { const [count, setCount] = react_1.useState(0); return (React.createElement("div", null, React.createElement("span", null, "The count is ", count), React.createElement("button", { onClick: () => setCount(count + 1) }, "Increment"))); }); return React.createElement("button", { onClick: showModal }, "Show modal"); }; const { getByText, queryByText } = renderWithProvider(React.createElement(App, null)); react_2.fireEvent.click(getByText("Show modal")); expect(queryByText("The count is 0")).toBeTruthy(); react_2.fireEvent.click(getByText("Increment")); expect(queryByText("The count is 1")).toBeTruthy(); }); it("should work with external state", () => { const App = () => { const [count, setCount] = react_1.useState(0); const [showModal] = useModal_1.useModal(() => (React.createElement("div", null, React.createElement("span", null, "The count is ", count), React.createElement("button", { onClick: () => setCount(count + 1) }, "Increment"))), [count]); return React.createElement("button", { onClick: showModal }, "Show modal"); }; const { getByText, queryByText } = renderWithProvider(React.createElement(App, null)); react_2.fireEvent.click(getByText("Show modal")); expect(queryByText("The count is 0")).toBeTruthy(); react_2.fireEvent.click(getByText("Increment")); expect(queryByText("The count is 1")).toBeTruthy(); }); it("should not rerender when external state changes", () => { const mountCounter = jest.fn(); class MountSpy extends React.Component { componentDidMount() { mountCounter(); } render() { return null; } } const App = () => { const [count, setCount] = react_1.useState(0); const [showModal] = useModal_1.useModal(() => (React.createElement("div", null, React.createElement(MountSpy, null), React.createElement("span", null, "The count is ", count), React.createElement("button", { onClick: () => setCount(count + 1) }, "Increment"))), [count]); return React.createElement("button", { onClick: showModal }, "Show modal"); }; const { getByText } = renderWithProvider(React.createElement(App, null)); react_2.fireEvent.click(getByText("Show modal")); react_2.fireEvent.click(getByText("Increment")); expect(mountCounter).toHaveBeenCalledTimes(1); }); }); describe("multiple modals", () => { it("should show multiple modals at the same time", () => { const App = () => { const [showFirstModal] = useModal_1.useModal(() => React.createElement("div", null, "First modal content")); const [showSecondModal] = useModal_1.useModal(() => React.createElement("div", null, "Second modal content")); return (React.createElement("div", null, React.createElement("button", { onClick: showFirstModal }, "Show first modal"), React.createElement("button", { onClick: showSecondModal }, "Show second modal"))); }; const { getByText, queryByText } = renderWithProvider(React.createElement(App, null)); react_2.fireEvent.click(getByText("Show first modal")); react_2.fireEvent.click(getByText("Show second modal")); expect(queryByText("First modal content")).toBeTruthy(); expect(queryByText("Second modal content")).toBeTruthy(); }); }); describe("calling useModal without ModalProvider", () => { const App = () => { useModal_1.useModal(() => React.createElement("div", null, "Modal content")); return null; }; it("should throw an error", () => { const consoleError = jest.fn(); jest.spyOn(console, 'error').mockImplementation(consoleError); expect(() => react_2.render(React.createElement(App, null))).toThrow(new Error("Attempted to call useModal outside of modal context. Make sure your app is rendered inside ModalProvider.")); expect(consoleError).toHaveBeenCalled(); }); }); describe("calling useModal with class component", () => { class Modal extends React.Component { render() { return React.createElement("div", null, "Modal content"); } } const App = () => { useModal_1.useModal(Modal); return null; }; beforeEach(() => { jest.spyOn(console, "error"); global.console.error.mockImplementation(() => { }); }); afterEach(() => { global.console.error.mockRestore(); }); it("should throw an error", () => { const catchError = jest.fn((e) => e.preventDefault()); window.addEventListener("error", catchError); expect(() => { renderWithProvider(React.createElement(App, null)); }).toThrowError(expect.objectContaining({ message: expect.stringMatching(/Only stateless components can be used as an argument to useModal/) })); }); });