diff --git a/docs/API.md b/docs/API.md index c76ef8dc1..9a5d6dcea 100644 --- a/docs/API.md +++ b/docs/API.md @@ -15,6 +15,8 @@ Defined as: function render( component: React.Element, options?: { + /* A React Component that renders `component` as children */ + wrapper?: React.ComponentType, /* You won't often use this, but it's helpful when testing refs */ createNodeMock: (element: React.Element) => any, } diff --git a/src/__tests__/render.test.js b/src/__tests__/render.test.js index 829446306..62f3fe62a 100644 --- a/src/__tests__/render.test.js +++ b/src/__tests__/render.test.js @@ -1,7 +1,13 @@ // @flow /* eslint-disable react/no-multi-comp */ import React from 'react'; -import { View, Text, TextInput, TouchableOpacity } from 'react-native'; +import { + View, + Text, + TextInput, + TouchableOpacity, + SafeAreaView, +} from 'react-native'; import stripAnsi from 'strip-ansi'; import { render, fireEvent } from '..'; @@ -291,3 +297,50 @@ test('debug changing component', () => { 'bananaFresh button message should now be "fresh"' ); }); + +test('renders options.wrapper around node', () => { + const WrapperComponent = ({ children }) => ( + {children} + ); + + const { toJSON, getByTestId } = render(, { + wrapper: WrapperComponent, + }); + + expect(getByTestId('wrapper')).toBeTruthy(); + expect(toJSON()).toMatchInlineSnapshot(` + + + + `); +}); + +test('renders options.wrapper around updated node', () => { + const WrapperComponent = ({ children }) => ( + {children} + ); + + const { toJSON, getByTestId, rerender } = render(, { + wrapper: WrapperComponent, + }); + + rerender(); + + expect(getByTestId('wrapper')).toBeTruthy(); + expect(toJSON()).toMatchInlineSnapshot(` + + + + `); +}); diff --git a/src/render.js b/src/render.js index 91a62fac8..c560dedc8 100644 --- a/src/render.js +++ b/src/render.js @@ -9,6 +9,10 @@ import debugShallow from './helpers/debugShallow'; import debugDeep from './helpers/debugDeep'; type Options = { + wrapper?: React.ComponentType, + createNodeMock?: (element: React.Element) => any, +}; +type TestRendererOptions = { createNodeMock: (element: React.Element) => any, }; @@ -16,20 +20,26 @@ type Options = { * Renders test component deeply using react-test-renderer and exposes helpers * to assert on the output. */ -export default function render( - component: React.Element, - options?: Options +export default function render( + component: React.Element, + { wrapper: Wrapper, createNodeMock }: Options = {} ) { - const renderer = renderWithAct(component, options); + const wrap = (innerElement: React.Element) => + Wrapper ? {innerElement} : innerElement; + const renderer = renderWithAct( + wrap(component), + createNodeMock ? { createNodeMock } : undefined + ); + const update = updateWithAct(renderer, wrap); const instance = renderer.root; return { ...getByAPI(instance), ...queryByAPI(instance), ...a11yAPI(instance), - update: updateWithAct(renderer), - rerender: updateWithAct(renderer), // alias for `update` + update, + rerender: update, // alias for `update` unmount: renderer.unmount, toJSON: renderer.toJSON, debug: debug(instance, renderer), @@ -38,7 +48,7 @@ export default function render( function renderWithAct( component: React.Element, - options?: Options + options?: TestRendererOptions ): ReactTestRenderer { let renderer: ReactTestRenderer; @@ -49,10 +59,13 @@ function renderWithAct( return ((renderer: any): ReactTestRenderer); } -function updateWithAct(renderer: ReactTestRenderer) { +function updateWithAct( + renderer: ReactTestRenderer, + wrap: (innerElement: React.Element) => React.Element +) { return function(component: React.Element) { act(() => { - renderer.update(component); + renderer.update(wrap(component)); }); }; } diff --git a/typings/index.d.ts b/typings/index.d.ts index af96bf17c..c2f805337 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -74,7 +74,8 @@ export interface Thenable { } export interface RenderOptions { - createNodeMock: (element: React.ReactElement) => any; + wrapper?: React.ComponentType; + createNodeMock?: (element: React.ReactElement) => any; } export interface RenderAPI extends GetByAPI, QueryByAPI, A11yAPI {