import React from 'react' import { Text, View } from 'react-native' import { render, screen, fireEvent } from '@testing-library/react-native' import moduleIndex from '../index' import ErrorBoundary from '../ErrorBoundary' describe('ErrorBoundary', () => { let consoleErrorSpy: jest.SpyInstance const ComponentWithError = () => ( {/* @ts-expect-error - We are rendering an error to trigger the ErrorBoundary component, even though it's not a valid React children. */} {new Error('This is a test error!')} ) beforeAll(() => { consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(jest.fn()) }) afterAll(() => { consoleErrorSpy.mockRestore() }) describe('Module index', () => { it('should default export ErrorBoundary', () => { expect(moduleIndex).toBeInstanceOf(Function) }) }) describe('when there are no errors', () => { it('should render the children', () => { const screen = render( Hey! , ) expect(screen).toMatchInlineSnapshot(` Hey! `) }) }) describe('when there is an error', () => { describe('when FallbackComponent is not defined as a prop', () => { it('should catch the error and render the default FallbackComponent', () => { const screen = render( , ) expect(screen).toMatchSnapshot() }) }) describe('when FallbackComponent is defined as a prop', () => { it('should catch the error and render the props.FallbackComponent', () => { const fallbackComponent = 'FallbackComponent' render( {fallbackComponent}} > , ) expect(screen.getByText(fallbackComponent)).toBeOnTheScreen() }) }) describe('when onError is defined as a prop', () => { it('should catch the error and call props.onError', () => { const onError = jest.fn() render( , ) expect(onError).toHaveBeenCalledWith( expect.any(Error), expect.any(String), ) }) }) describe('when FallbackComponent resetError prop is called', () => { it('should clear the error state', () => { const { rerender } = render(, { wrapper: ErrorBoundary, }) const tryAgainButton = screen.getByText('Try again') const children = 'Children' expect(tryAgainButton).toBeOnTheScreen() rerender({children}) fireEvent.press(tryAgainButton) expect(screen.getByText(children)).toBeOnTheScreen() expect(tryAgainButton).not.toBeOnTheScreen() }) }) }) })