From d1820241d0b4948c93e05cd7338c991cc3122c3f Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Tue, 20 Sep 2016 23:30:41 -0700 Subject: [PATCH] [New] `shallow`: add `.dive()` --- docs/api/ShallowWrapper/dive.md | 52 +++++++++++++++++++++++++++++++++ docs/api/shallow.md | 3 ++ src/ShallowWrapper.js | 24 ++++++++++++++- 3 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 docs/api/ShallowWrapper/dive.md diff --git a/docs/api/ShallowWrapper/dive.md b/docs/api/ShallowWrapper/dive.md new file mode 100644 index 000000000..c1453823e --- /dev/null +++ b/docs/api/ShallowWrapper/dive.md @@ -0,0 +1,52 @@ +# `.dive([options]) => ShallowWrapper` + +Throws unless the wrapper contains only one non-DOM Component child; otherwise, returns a shallow wrapper around it. + +NOTE: can only be called on wrapper of a single non-DOM component element node. + + +#### Arguments + +1. `options` (`Object` [optional]): +- `options.context`: (`Object` [optional]): Context to be passed into the component + + + +#### Returns + +`ShallowWrapper`: A new wrapper that wraps the current node after it's been shallow rendered. + + + +#### Examples + +```jsx +class Bar extends React.Component { + render() { + return ( +
+
+
+ ); + } +} +``` + +```jsx +class Foo extends React.Component { + render() { + return ( +
+ +
+ ); + } +} +``` + +```jsx +const wrapper = shallow(); +expect(wrapper.find('.in-bar')).to.have.length(0); +expect(wrapper.find(Bar)).to.have.length(1); +expect(wrapper.dive().find('.in-bar')).to.have.length(1); +``` diff --git a/docs/api/shallow.md b/docs/api/shallow.md index f9468739d..fb7fa4a3c 100644 --- a/docs/api/shallow.md +++ b/docs/api/shallow.md @@ -207,3 +207,6 @@ Returns whether or not all of the nodes in the wrapper match the provided select #### [`.everyWhere(predicate) => Boolean`](ShallowWrapper/everyWhere.md) Returns whether or not all of the nodes in the wrapper pass the provided predicate function. + +#### [`.dive([options]) => ShallowWrapper`](ShallowWrapper/dive.md) +Throws unless the wrapper contains only one non-DOM Component child; otherwise, returns a shallow wrapper around it. diff --git a/src/ShallowWrapper.js b/src/ShallowWrapper.js index fe0284643..f4c29593e 100644 --- a/src/ShallowWrapper.js +++ b/src/ShallowWrapper.js @@ -15,6 +15,7 @@ import { isReactElementAlike, displayNameOfNode, isFunctionalComponent, + isCustomComponentElement, } from './Utils'; import { debugNodes, @@ -31,6 +32,7 @@ import { createShallowRenderer, renderToStaticMarkup, batchedUpdates, + isDOMComponentElement, } from './react-compat'; /** @@ -698,7 +700,7 @@ export default class ShallowWrapper { /** * Returns the type of the current node of this wrapper. If it's a composite component, this will - * be the component constructor. If it's native DOM node, it will be a string. + * be the component constructor. If it's a native DOM node, it will be a string. * * @returns {String|Function} */ @@ -959,4 +961,24 @@ export default class ShallowWrapper { intercepter(this); return this; } + + /** + * Primarily useful for HOCs (higher-order components), this method may only be + * run on a single, non-DOM node, and will return the node, shallow-rendered. + * + * @param options object + * @returns {ShallowWrapper} + */ + dive(options) { + const name = 'dive'; + return this.single(name, n => { + if (isDOMComponentElement(n)) { + throw new TypeError(`ShallowWrapper::${name}() can not be called on DOM components`); + } + if (!isCustomComponentElement(n)) { + throw new TypeError(`ShallowWrapper::${name}() can only be called on components`); + } + return new ShallowWrapper(n, null, options); + }); + } }