From ecf4f59c044fa61c077b4961da83d99e3a0c0077 Mon Sep 17 00:00:00 2001 From: Scotty Waggoner Date: Thu, 16 May 2019 18:00:05 -0700 Subject: [PATCH 1/6] Add wrapper option to render --- docs/API.md | 2 ++ src/__tests__/render.test.js | 55 +++++++++++++++++++++++++++++++++++- src/render.js | 31 +++++++++++++++----- 3 files changed, 80 insertions(+), 8 deletions(-) diff --git a/docs/API.md b/docs/API.md index c76ef8dc1..4acb0c3eb 100644 --- a/docs/API.md +++ b/docs/API.md @@ -15,6 +15,8 @@ Defined as: function render( component: React.Element, options?: { + /* Provide a React Component to have it rendered around the inner element on initial render and on rerender/update */ + 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..ffceb7037 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..7526f7f0a 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, }; @@ -18,9 +22,19 @@ type Options = { */ export default function render( component: React.Element, - options?: Options + { wrapper: WrapperComponent, createNodeMock }: Options = {} ) { - const renderer = renderWithAct(component, options); + const wrapUiIfNeeded = (innerElement: React.Element) => + WrapperComponent ? ( + {innerElement} + ) : ( + innerElement + ); + + const renderer = renderWithAct( + wrapUiIfNeeded(component), + createNodeMock ? { createNodeMock } : undefined + ); const instance = renderer.root; @@ -28,8 +42,8 @@ export default function render( ...getByAPI(instance), ...queryByAPI(instance), ...a11yAPI(instance), - update: updateWithAct(renderer), - rerender: updateWithAct(renderer), // alias for `update` + update: updateWithAct(renderer, wrapUiIfNeeded), + rerender: updateWithAct(renderer, wrapUiIfNeeded), // alias for `update` unmount: renderer.unmount, toJSON: renderer.toJSON, debug: debug(instance, renderer), @@ -38,7 +52,7 @@ export default function render( function renderWithAct( component: React.Element, - options?: Options + options?: TestRendererOptions ): ReactTestRenderer { let renderer: ReactTestRenderer; @@ -49,10 +63,13 @@ function renderWithAct( return ((renderer: any): ReactTestRenderer); } -function updateWithAct(renderer: ReactTestRenderer) { +function updateWithAct( + renderer: ReactTestRenderer, + wrapUiIfNeeded: (innerElement: React.Element) => React.Element +) { return function(component: React.Element) { act(() => { - renderer.update(component); + renderer.update(wrapUiIfNeeded(component)); }); }; } From 05548f633e823ac667670c266d41472b4b4e89fd Mon Sep 17 00:00:00 2001 From: Scotty Waggoner Date: Mon, 20 May 2019 12:36:13 -0700 Subject: [PATCH 2/6] Update TS types and call updateWithAct only once --- src/render.js | 6 ++++-- typings/index.d.ts | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/render.js b/src/render.js index 7526f7f0a..fc8fa4c1d 100644 --- a/src/render.js +++ b/src/render.js @@ -38,12 +38,14 @@ export default function render( const instance = renderer.root; + const update = updateWithAct(renderer, wrapUiIfNeeded); + return { ...getByAPI(instance), ...queryByAPI(instance), ...a11yAPI(instance), - update: updateWithAct(renderer, wrapUiIfNeeded), - rerender: updateWithAct(renderer, wrapUiIfNeeded), // alias for `update` + update, + rerender: update, // alias for `update` unmount: renderer.unmount, toJSON: renderer.toJSON, debug: debug(instance, renderer), 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 { From 1ce49e3220d8ee52f275c4ff0dc0625bba0a7489 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Tue, 28 May 2019 21:58:32 +0200 Subject: [PATCH 3/6] wrapUiIfNeeded -> wrap --- src/render.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/render.js b/src/render.js index fc8fa4c1d..afd990271 100644 --- a/src/render.js +++ b/src/render.js @@ -24,7 +24,7 @@ export default function render( component: React.Element, { wrapper: WrapperComponent, createNodeMock }: Options = {} ) { - const wrapUiIfNeeded = (innerElement: React.Element) => + const wrap = (innerElement: React.Element) => WrapperComponent ? ( {innerElement} ) : ( @@ -32,13 +32,13 @@ export default function render( ); const renderer = renderWithAct( - wrapUiIfNeeded(component), + wrap(component), createNodeMock ? { createNodeMock } : undefined ); const instance = renderer.root; - const update = updateWithAct(renderer, wrapUiIfNeeded); + const update = updateWithAct(renderer, wrap); return { ...getByAPI(instance), From acb15bb5f06f4fe207a0bbf50e53fae439888691 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Tue, 28 May 2019 22:03:12 +0200 Subject: [PATCH 4/6] reindent snapshots --- src/__tests__/render.test.js | 38 ++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/__tests__/render.test.js b/src/__tests__/render.test.js index ffceb7037..62f3fe62a 100644 --- a/src/__tests__/render.test.js +++ b/src/__tests__/render.test.js @@ -309,15 +309,15 @@ test('renders options.wrapper around node', () => { expect(getByTestId('wrapper')).toBeTruthy(); expect(toJSON()).toMatchInlineSnapshot(` - - - - `); + + + + `); }); test('renders options.wrapper around updated node', () => { @@ -333,14 +333,14 @@ test('renders options.wrapper around updated node', () => { expect(getByTestId('wrapper')).toBeTruthy(); expect(toJSON()).toMatchInlineSnapshot(` - - - - `); + + + + `); }); From c69c7496342f565b77c8e0528dac4ec18fedceb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Tue, 28 May 2019 22:25:00 +0200 Subject: [PATCH 5/6] adjustments --- docs/API.md | 2 +- src/render.js | 16 +++++----------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/docs/API.md b/docs/API.md index 4acb0c3eb..9a5d6dcea 100644 --- a/docs/API.md +++ b/docs/API.md @@ -15,7 +15,7 @@ Defined as: function render( component: React.Element, options?: { - /* Provide a React Component to have it rendered around the inner element on initial render and on rerender/update */ + /* 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/render.js b/src/render.js index afd990271..800b803a9 100644 --- a/src/render.js +++ b/src/render.js @@ -20,25 +20,19 @@ type TestRendererOptions = { * Renders test component deeply using react-test-renderer and exposes helpers * to assert on the output. */ -export default function render( - component: React.Element, - { wrapper: WrapperComponent, createNodeMock }: Options = {} +export default function render( + component: React.Element, + { wrapper: Wrapper, createNodeMock }: Options = {} ) { const wrap = (innerElement: React.Element) => - WrapperComponent ? ( - {innerElement} - ) : ( - innerElement - ); + Wrapper ? {innerElement} : innerElement; const renderer = renderWithAct( wrap(component), createNodeMock ? { createNodeMock } : undefined ); - - const instance = renderer.root; - const update = updateWithAct(renderer, wrap); + const instance = renderer.root; return { ...getByAPI(instance), From f7de82fd2c02bfe6601394eb09cdf3d163a47dcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Tue, 28 May 2019 22:30:07 +0200 Subject: [PATCH 6/6] change name --- src/render.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/render.js b/src/render.js index 800b803a9..c560dedc8 100644 --- a/src/render.js +++ b/src/render.js @@ -61,11 +61,11 @@ function renderWithAct( function updateWithAct( renderer: ReactTestRenderer, - wrapUiIfNeeded: (innerElement: React.Element) => React.Element + wrap: (innerElement: React.Element) => React.Element ) { return function(component: React.Element) { act(() => { - renderer.update(wrapUiIfNeeded(component)); + renderer.update(wrap(component)); }); }; }