From e675ca99ea7cac818d0be6424ceae88c91f1970d Mon Sep 17 00:00:00 2001 From: Josh Minzner Date: Fri, 4 Jan 2019 11:25:02 -0500 Subject: [PATCH] Add documentation --- SUMMARY.md | 2 +- docs/api/ReactWrapper/getWrappingComponent.md | 44 +++++++++++++ docs/api/ReactWrapper/setProviders.md | 65 ------------------- docs/api/mount.md | 8 +-- .../enzyme-adapter-utils/src/RootFinder.jsx | 4 ++ .../src/createMountWrapper.jsx | 3 + packages/enzyme/src/ReactWrapper.js | 7 ++ 7 files changed, 63 insertions(+), 70 deletions(-) create mode 100644 docs/api/ReactWrapper/getWrappingComponent.md delete mode 100644 docs/api/ReactWrapper/setProviders.md diff --git a/SUMMARY.md b/SUMMARY.md index f712915de..e5faf3904 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -100,6 +100,7 @@ * [forEach(fn)](/docs/api/ReactWrapper/forEach.md) * [get(index)](/docs/api/ReactWrapper/get.md) * [getDOMNode()](/docs/api/ReactWrapper/getDOMNode.md) + * [getWrappingComponent()](/docs/api/ReactWrapper/getWrappingComponent.md) * [hasClass(className)](/docs/api/ReactWrapper/hasClass.md) * [hostNodes()](/docs/api/ReactWrapper/hostNodes.md) * [html()](/docs/api/ReactWrapper/html.md) @@ -124,7 +125,6 @@ * [render()](/docs/api/ReactWrapper/render.md) * [setContext(context)](/docs/api/ReactWrapper/setContext.md) * [setProps(nextProps[, callback])](/docs/api/ReactWrapper/setProps.md) - * [setProviders(providers)](/docs/api/ReactWrapper/setProviders.md) * [setState(nextState[, callback])](/docs/api/ReactWrapper/setState.md) * [simulate(event[, data])](/docs/api/ReactWrapper/simulate.md) * [simulateError(error)](/docs/api/ReactWrapper/simulateError.md) diff --git a/docs/api/ReactWrapper/getWrappingComponent.md b/docs/api/ReactWrapper/getWrappingComponent.md new file mode 100644 index 000000000..df4b2bd08 --- /dev/null +++ b/docs/api/ReactWrapper/getWrappingComponent.md @@ -0,0 +1,44 @@ +# `.getWrappingComponent() => ReactWrapper` + +If a `wrappingComponent` was passed in `options`, this methods returns a `ReactWrapper` around the rendered `wrappingComponent`. This `ReactWrapper` can be used to update the `wrappingComponent`'s props, state, etc. + + +#### Returns + +`ReactWrapper`: A `ReactWrapper` around the rendered `wrappingComponent` + + + +#### Examples + +```jsx +import { Provider } from 'react-redux'; +import { Router } from 'react-router'; +import store from './my/app/store'; +import mockStore from './my/app/mockStore'; + +function MyProvider(props) { + const { children, customStore } = props; + + return ( + + + {children} + + + ); +} + +const wrapper = mount(, { + wrappingComponent: MyProvider, +}); +const provider = wrapper.getWrappingComponent(); +provider.setProps({ customStore: mockStore }); +wrapper.update(); // update root wrapper after wrappingComponent props changed +``` + + + +#### Common Gotchas + +- Your root wrapper _will not_ automatically `update()` when the state/props of your `wrappingComponent` are changed. If you expect your component to render differently after calling `.setState()`/`.setProps()` on your `wrappingComponent`, you'll need to manually call `update()` on your root wrapper. diff --git a/docs/api/ReactWrapper/setProviders.md b/docs/api/ReactWrapper/setProviders.md deleted file mode 100644 index 2e111cccb..000000000 --- a/docs/api/ReactWrapper/setProviders.md +++ /dev/null @@ -1,65 +0,0 @@ -# `.setProviders(providers) => Self` - -Can be used to update the values provided by React's new context API. A subset of current -providers can be passed to update just those values without removing the unspecified providers. - -NOTE: can only be called on a wrapper instance that is also the root instance. - - -#### Arguments - -1. `providers` (`Array`): An array of Provider elements to merge in with the current context - - - -#### Returns - -`ReactWrapper`: Returns itself. - - - -#### Example - -```jsx -const ContextA = createContext(null); -const ContextB = createContext(null); -const ContextC = createContext(null); - -function MyComponent() { - return ( -
- - {value =>
{value}
} -
- - {value =>
{value}
} -
- - {value =>
{value}
} -
-
- ); -} -``` -```jsx -const wrapper = mount(, { - providers: [ - , - , - , - ], -}); -wrapper.text(); // I Love Enzyme - -wrapper.setProviders([ - , - , -]); -wrapper.text(); // We Love React -``` - -#### Common Gotchas - -- `.setProviders()` can only be used on a wrapper that was initially created with a call to `mount()` -- `.setProviders()` requires `enzyme-adapter-react-16` or `enzyme-adapter-react-16.3` -- Only `Provider`s created with `React.createContext()` can be passed to `.setProviders()` diff --git a/docs/api/mount.md b/docs/api/mount.md index 2037050db..6005a4a2e 100644 --- a/docs/api/mount.md +++ b/docs/api/mount.md @@ -49,7 +49,7 @@ describe('', () => { - `options.context`: (`Object` [optional]): Context to be passed into the component - `options.attachTo`: (`DOMElement` [optional]): DOM Element to attach the component to. - `options.childContextTypes`: (`Object` [optional]): Merged contextTypes for all children of the wrapper. -- `options.providers`: (`Array` [optional]): Provider elements (from React's new context API) that will provide context to the mounted node +- `options.wrappingComponent`: (`ComponentType` [optional]): A component that will render as a parent of the `node`. It can be used to provide context to the `node`, among other things. See the [`getWrappingComponent()` docs](ReactWrapper/getWrappingComponent.md) for an example. **Note**: `wrappingComponent` _must_ render its children. #### Returns @@ -172,12 +172,12 @@ Manually sets props of the root component. #### [`.setContext(context) => ReactWrapper`](ReactWrapper/setContext.md) Manually sets context of the root component. -#### [`.setProviders(providers) => ReactWrapper`](ReactWrapper/setProviders.md) -Manually sets values of React's new context API. - #### [`.instance() => ReactComponent|DOMComponent`](ReactWrapper/instance.md) Returns the wrapper's underlying instance. +#### [`.getWrappingComponent() => ReactWrapper`](ReactWrapper/getWrappingComponent.md) +Returns a wrapper representing the `wrappingComponent`, if one was passed. + #### [`.unmount() => ReactWrapper`](ReactWrapper/unmount.md) A method that un-mounts the component. diff --git a/packages/enzyme-adapter-utils/src/RootFinder.jsx b/packages/enzyme-adapter-utils/src/RootFinder.jsx index 05b0d4c2e..2e1478a8d 100644 --- a/packages/enzyme-adapter-utils/src/RootFinder.jsx +++ b/packages/enzyme-adapter-utils/src/RootFinder.jsx @@ -1,6 +1,10 @@ import React from 'react'; import PropTypes from 'prop-types'; +/** + * This component is a utility to assist in the finding of the root component + * when the component is mounted in a wrappingComponent. + */ export default class RootFinder extends React.Component { render() { const { children } = this.props; diff --git a/packages/enzyme-adapter-utils/src/createMountWrapper.jsx b/packages/enzyme-adapter-utils/src/createMountWrapper.jsx index d0341b379..373872de3 100644 --- a/packages/enzyme-adapter-utils/src/createMountWrapper.jsx +++ b/packages/enzyme-adapter-utils/src/createMountWrapper.jsx @@ -92,6 +92,8 @@ export default function createMountWrapper(node, options = {}) { } getComponentParentInstance() { + // If a wrappingComponent was provided, the root node's parent will be the + // RootFinder component (see render()). if (WrappingComponent) { if (!this.rootFinderInstance) { throw new Error('`wrappingComponent` must render its children!'); @@ -100,6 +102,7 @@ export default function createMountWrapper(node, options = {}) { return this.rootFinderInstance; } + // Otherwise, this component is the root node's parent! return this; } diff --git a/packages/enzyme/src/ReactWrapper.js b/packages/enzyme/src/ReactWrapper.js index c0f8938cd..662efcaee 100644 --- a/packages/enzyme/src/ReactWrapper.js +++ b/packages/enzyme/src/ReactWrapper.js @@ -227,6 +227,13 @@ class ReactWrapper { return this.single('instance', () => this[NODE].instance); } + /** + * If a `wrappingComponent` was passed in `options`, this methods returns a `ReactWrapper` around + * the rendered `wrappingComponent`. This `ReactWrapper` can be used to update the + * `wrappingComponent`'s props, state, etc. + * + * @returns ReactWrapper + */ getWrappingComponent() { if (this[ROOT] !== this || this[RENDERER] === this[WRAPPING_COMPONENT_RENDERER]) { throw new Error('ReactWrapper::getWrappingComponent() can only be called on the root');