From fc61100d70a73363b371105be203ade8a52f9bca Mon Sep 17 00:00:00 2001 From: Josh Minzner Date: Wed, 2 Jan 2019 16:48:14 -0500 Subject: [PATCH] [enzyme-adapter-react-{14,15.4,15,16.1,16.2,16.3,16] [new] add `wrapWithWrappingComponent` --- .../src/ReactFourteenAdapter.js | 30 ++++++++++++++++- .../src/ReactFifteenFourAdapter.js | 30 ++++++++++++++++- .../src/ReactFifteenAdapter.js | 30 ++++++++++++++++- .../src/ReactSixteenOneAdapter.js | 32 ++++++++++++++++-- .../src/ReactSixteenTwoAdapter.js | 32 ++++++++++++++++-- .../src/ReactSixteenThreeAdapter.js | 33 +++++++++++++++++-- .../src/ReactSixteenAdapter.js | 33 +++++++++++++++++-- .../enzyme-test-suite/test/Adapter-spec.jsx | 18 ++++++++++ 8 files changed, 225 insertions(+), 13 deletions(-) diff --git a/packages/enzyme-adapter-react-14/src/ReactFourteenAdapter.js b/packages/enzyme-adapter-react-14/src/ReactFourteenAdapter.js index bbecee920..4715958a4 100644 --- a/packages/enzyme-adapter-react-14/src/ReactFourteenAdapter.js +++ b/packages/enzyme-adapter-react-14/src/ReactFourteenAdapter.js @@ -19,6 +19,10 @@ import { propsWithKeysAndRef, ensureKeyOrUndefined, wrap, + RootFinder, + getNodeFromRootFinder, + wrapWithWrappingComponent, + getWrappingComponentMountRenderer, } from 'enzyme-adapter-utils'; function typeToNodeType(type) { @@ -103,6 +107,7 @@ class ReactFourteenAdapter extends EnzymeAdapter { const { type, props, ref } = el; const wrapperProps = { Component: type, + wrappingComponentProps: options.wrappingComponentProps, props, context, ...(ref && { ref }), @@ -122,7 +127,14 @@ class ReactFourteenAdapter extends EnzymeAdapter { instance = null; }, getNode() { - return instance ? instanceToTree(instance._reactInternalInstance).rendered : null; + if (!instance) { + return null; + } + return getNodeFromRootFinder( + adapter.isCustomComponent, + instanceToTree(instance._reactInternalInstance), + options, + ); }, simulateEvent(node, event, mock) { const mappedEvent = mapNativeEventNames(event); @@ -136,6 +148,15 @@ class ReactFourteenAdapter extends EnzymeAdapter { batchedUpdates(fn) { return ReactDOM.unstable_batchedUpdates(fn); }, + getWrappingComponentRenderer() { + return { + ...this, + ...getWrappingComponentMountRenderer({ + toTree: inst => instanceToTree(inst._reactInternalInstance), + getMountWrapperInstance: () => instance, + }), + }; + }, }; } @@ -259,6 +280,13 @@ class ReactFourteenAdapter extends EnzymeAdapter { createElement(...args) { return React.createElement(...args); } + + wrapWithWrappingComponent(node, options) { + return { + RootFinder, + node: wrapWithWrappingComponent(React.createElement, node, options), + }; + } } module.exports = ReactFourteenAdapter; diff --git a/packages/enzyme-adapter-react-15.4/src/ReactFifteenFourAdapter.js b/packages/enzyme-adapter-react-15.4/src/ReactFifteenFourAdapter.js index f474b07aa..e4104547e 100644 --- a/packages/enzyme-adapter-react-15.4/src/ReactFifteenFourAdapter.js +++ b/packages/enzyme-adapter-react-15.4/src/ReactFifteenFourAdapter.js @@ -19,6 +19,10 @@ import { propsWithKeysAndRef, ensureKeyOrUndefined, wrap, + RootFinder, + getNodeFromRootFinder, + wrapWithWrappingComponent, + getWrappingComponentMountRenderer, } from 'enzyme-adapter-utils'; import ifReact from 'enzyme-adapter-react-helper/build/ifReact'; @@ -138,6 +142,7 @@ class ReactFifteenFourAdapter extends EnzymeAdapter { const { type, props, ref } = el; const wrapperProps = { Component: type, + wrappingComponentProps: options.wrappingComponentProps, props, context, ...(ref && { ref }), @@ -157,7 +162,14 @@ class ReactFifteenFourAdapter extends EnzymeAdapter { instance = null; }, getNode() { - return instance ? instanceToTree(instance._reactInternalInstance).rendered : null; + if (!instance) { + return null; + } + return getNodeFromRootFinder( + adapter.isCustomComponent, + instanceToTree(instance._reactInternalInstance), + options, + ); }, simulateEvent(node, event, mock) { const mappedEvent = mapNativeEventNames(event, eventOptions); @@ -171,6 +183,15 @@ class ReactFifteenFourAdapter extends EnzymeAdapter { batchedUpdates(fn) { return ReactDOM.unstable_batchedUpdates(fn); }, + getWrappingComponentRenderer() { + return { + ...this, + ...getWrappingComponentMountRenderer({ + toTree: inst => instanceToTree(inst._reactInternalInstance), + getMountWrapperInstance: () => instance, + }), + }; + }, }; } @@ -304,6 +325,13 @@ class ReactFifteenFourAdapter extends EnzymeAdapter { ); invoke(); } + + wrapWithWrappingComponent(node, options) { + return { + RootFinder, + node: wrapWithWrappingComponent(React.createElement, node, options), + }; + } } module.exports = ReactFifteenFourAdapter; diff --git a/packages/enzyme-adapter-react-15/src/ReactFifteenAdapter.js b/packages/enzyme-adapter-react-15/src/ReactFifteenAdapter.js index 0a807fe86..50b98b8e2 100644 --- a/packages/enzyme-adapter-react-15/src/ReactFifteenAdapter.js +++ b/packages/enzyme-adapter-react-15/src/ReactFifteenAdapter.js @@ -21,6 +21,10 @@ import { propsWithKeysAndRef, ensureKeyOrUndefined, wrap, + RootFinder, + getNodeFromRootFinder, + wrapWithWrappingComponent, + getWrappingComponentMountRenderer, } from 'enzyme-adapter-utils'; function compositeTypeToNodeType(type) { @@ -138,6 +142,7 @@ class ReactFifteenAdapter extends EnzymeAdapter { const { type, props, ref } = el; const wrapperProps = { Component: type, + wrappingComponentProps: options.wrappingComponentProps, props, context, ...(ref && { ref }), @@ -157,7 +162,14 @@ class ReactFifteenAdapter extends EnzymeAdapter { instance = null; }, getNode() { - return instance ? instanceToTree(instance._reactInternalInstance).rendered : null; + if (!instance) { + return null; + } + return getNodeFromRootFinder( + adapter.isCustomComponent, + instanceToTree(instance._reactInternalInstance), + options, + ); }, simulateEvent(node, event, mock) { const mappedEvent = mapNativeEventNames(event, eventOptions); @@ -171,6 +183,15 @@ class ReactFifteenAdapter extends EnzymeAdapter { batchedUpdates(fn) { return ReactDOM.unstable_batchedUpdates(fn); }, + getWrappingComponentRenderer() { + return { + ...this, + ...getWrappingComponentMountRenderer({ + toTree: inst => instanceToTree(inst._reactInternalInstance), + getMountWrapperInstance: () => instance, + }), + }; + }, }; } @@ -299,6 +320,13 @@ class ReactFifteenAdapter extends EnzymeAdapter { // React in >= 15.4, and < 16 pass undefined to a setState callback callback.call(instance, undefined); } + + wrapWithWrappingComponent(node, options) { + return { + RootFinder, + node: wrapWithWrappingComponent(React.createElement, node, options), + }; + } } module.exports = ReactFifteenAdapter; diff --git a/packages/enzyme-adapter-react-16.1/src/ReactSixteenOneAdapter.js b/packages/enzyme-adapter-react-16.1/src/ReactSixteenOneAdapter.js index d07f46d80..8f8fdabfc 100644 --- a/packages/enzyme-adapter-react-16.1/src/ReactSixteenOneAdapter.js +++ b/packages/enzyme-adapter-react-16.1/src/ReactSixteenOneAdapter.js @@ -32,6 +32,10 @@ import { wrap, getMaskedContext, getComponentStack, + RootFinder, + getNodeFromRootFinder, + wrapWithWrappingComponent, + getWrappingComponentMountRenderer, } from 'enzyme-adapter-utils'; import { findCurrentFiberUsingSlowPath } from 'react-reconciler/reflection'; @@ -261,7 +265,7 @@ class ReactSixteenOneAdapter extends EnzymeAdapter { createMountRenderer(options) { assertDomAvailable('mount'); - const { attachTo, hydrateIn } = options; + const { attachTo, hydrateIn, wrappingComponentProps } = options; const domNode = hydrateIn || attachTo || global.document.createElement('div'); let instance = null; const adapter = this; @@ -272,6 +276,7 @@ class ReactSixteenOneAdapter extends EnzymeAdapter { const wrapperProps = { Component: type, props, + wrappingComponentProps, context, ...(ref && { ref }), }; @@ -292,7 +297,14 @@ class ReactSixteenOneAdapter extends EnzymeAdapter { instance = null; }, getNode() { - return instance ? toTree(instance._reactInternalFiber).rendered : null; + if (!instance) { + return null; + } + return getNodeFromRootFinder( + adapter.isCustomComponent, + toTree(instance._reactInternalFiber), + options, + ); }, simulateError(nodeHierarchy, rootNode, error) { const { instance: catchingInstance } = nodeHierarchy @@ -320,6 +332,15 @@ class ReactSixteenOneAdapter extends EnzymeAdapter { return fn(); // return ReactDOM.unstable_batchedUpdates(fn); }, + getWrappingComponentRenderer() { + return { + ...this, + ...getWrappingComponentMountRenderer({ + toTree: inst => toTree(inst._reactInternalFiber), + getMountWrapperInstance: () => instance, + }), + }; + }, }; } @@ -512,6 +533,13 @@ class ReactSixteenOneAdapter extends EnzymeAdapter { createElement(...args) { return React.createElement(...args); } + + wrapWithWrappingComponent(node, options) { + return { + RootFinder, + node: wrapWithWrappingComponent(React.createElement, node, options), + }; + } } module.exports = ReactSixteenOneAdapter; diff --git a/packages/enzyme-adapter-react-16.2/src/ReactSixteenTwoAdapter.js b/packages/enzyme-adapter-react-16.2/src/ReactSixteenTwoAdapter.js index 69997ffd9..bf86b1e35 100644 --- a/packages/enzyme-adapter-react-16.2/src/ReactSixteenTwoAdapter.js +++ b/packages/enzyme-adapter-react-16.2/src/ReactSixteenTwoAdapter.js @@ -33,6 +33,10 @@ import { wrap, getMaskedContext, getComponentStack, + RootFinder, + getNodeFromRootFinder, + wrapWithWrappingComponent, + getWrappingComponentMountRenderer, } from 'enzyme-adapter-utils'; import { findCurrentFiberUsingSlowPath } from 'react-reconciler/reflection'; @@ -263,7 +267,7 @@ class ReactSixteenTwoAdapter extends EnzymeAdapter { createMountRenderer(options) { assertDomAvailable('mount'); - const { attachTo, hydrateIn } = options; + const { attachTo, hydrateIn, wrappingComponentProps } = options; const domNode = hydrateIn || attachTo || global.document.createElement('div'); let instance = null; const adapter = this; @@ -274,6 +278,7 @@ class ReactSixteenTwoAdapter extends EnzymeAdapter { const wrapperProps = { Component: type, props, + wrappingComponentProps, context, ...(ref && { ref }), }; @@ -294,7 +299,14 @@ class ReactSixteenTwoAdapter extends EnzymeAdapter { instance = null; }, getNode() { - return instance ? toTree(instance._reactInternalFiber).rendered : null; + if (!instance) { + return null; + } + return getNodeFromRootFinder( + adapter.isCustomComponent, + toTree(instance._reactInternalFiber), + options, + ); }, simulateError(nodeHierarchy, rootNode, error) { const { instance: catchingInstance } = nodeHierarchy @@ -322,6 +334,15 @@ class ReactSixteenTwoAdapter extends EnzymeAdapter { return fn(); // return ReactDOM.unstable_batchedUpdates(fn); }, + getWrappingComponentRenderer() { + return { + ...this, + ...getWrappingComponentMountRenderer({ + toTree: inst => toTree(inst._reactInternalFiber), + getMountWrapperInstance: () => instance, + }), + }; + }, }; } @@ -518,6 +539,13 @@ class ReactSixteenTwoAdapter extends EnzymeAdapter { createElement(...args) { return React.createElement(...args); } + + wrapWithWrappingComponent(node, options) { + return { + RootFinder, + node: wrapWithWrappingComponent(React.createElement, node, options), + }; + } } module.exports = ReactSixteenTwoAdapter; diff --git a/packages/enzyme-adapter-react-16.3/src/ReactSixteenThreeAdapter.js b/packages/enzyme-adapter-react-16.3/src/ReactSixteenThreeAdapter.js index db8b4cf87..929299903 100644 --- a/packages/enzyme-adapter-react-16.3/src/ReactSixteenThreeAdapter.js +++ b/packages/enzyme-adapter-react-16.3/src/ReactSixteenThreeAdapter.js @@ -11,7 +11,6 @@ import checkPropTypes from 'prop-types/checkPropTypes'; import { isElement, isPortal, - isForwardRef, isValidElementType, AsyncMode, Fragment, @@ -38,6 +37,10 @@ import { simulateError, wrap, getComponentStack, + RootFinder, + getNodeFromRootFinder, + wrapWithWrappingComponent, + getWrappingComponentMountRenderer, } from 'enzyme-adapter-utils'; import { findCurrentFiberUsingSlowPath } from 'react-reconciler/reflection'; @@ -265,7 +268,7 @@ class ReactSixteenThreeAdapter extends EnzymeAdapter { createMountRenderer(options) { assertDomAvailable('mount'); - const { attachTo, hydrateIn } = options; + const { attachTo, hydrateIn, wrappingComponentProps } = options; const domNode = hydrateIn || attachTo || global.document.createElement('div'); let instance = null; const adapter = this; @@ -276,6 +279,7 @@ class ReactSixteenThreeAdapter extends EnzymeAdapter { const wrapperProps = { Component: type, props, + wrappingComponentProps, context, ...(ref && { ref }), }; @@ -296,7 +300,14 @@ class ReactSixteenThreeAdapter extends EnzymeAdapter { instance = null; }, getNode() { - return instance ? toTree(instance._reactInternalFiber).rendered : null; + if (!instance) { + return null; + } + return getNodeFromRootFinder( + adapter.isCustomComponent, + toTree(instance._reactInternalFiber), + options, + ); }, simulateError(nodeHierarchy, rootNode, error) { const { instance: catchingInstance } = nodeHierarchy @@ -324,6 +335,15 @@ class ReactSixteenThreeAdapter extends EnzymeAdapter { return fn(); // return ReactDOM.unstable_batchedUpdates(fn); }, + getWrappingComponentRenderer() { + return { + ...this, + ...getWrappingComponentMountRenderer({ + toTree: inst => toTree(inst._reactInternalFiber), + getMountWrapperInstance: () => instance, + }), + }; + }, }; } @@ -528,6 +548,13 @@ class ReactSixteenThreeAdapter extends EnzymeAdapter { createElement(...args) { return React.createElement(...args); } + + wrapWithWrappingComponent(node, options) { + return { + RootFinder, + node: wrapWithWrappingComponent(React.createElement, node, options), + }; + } } module.exports = ReactSixteenThreeAdapter; diff --git a/packages/enzyme-adapter-react-16/src/ReactSixteenAdapter.js b/packages/enzyme-adapter-react-16/src/ReactSixteenAdapter.js index 143cd4458..c80b4398d 100644 --- a/packages/enzyme-adapter-react-16/src/ReactSixteenAdapter.js +++ b/packages/enzyme-adapter-react-16/src/ReactSixteenAdapter.js @@ -11,7 +11,6 @@ import checkPropTypes from 'prop-types/checkPropTypes'; import { isElement, isPortal, - isForwardRef, isValidElementType, AsyncMode, ConcurrentMode, @@ -43,6 +42,10 @@ import { wrap, getMaskedContext, getComponentStack, + RootFinder, + getNodeFromRootFinder, + wrapWithWrappingComponent, + getWrappingComponentMountRenderer, } from 'enzyme-adapter-utils'; import findCurrentFiberUsingSlowPath from './findCurrentFiberUsingSlowPath'; import detectFiberTags from './detectFiberTags'; @@ -310,7 +313,7 @@ class ReactSixteenAdapter extends EnzymeAdapter { // Requires DOM. FiberTags = detectFiberTags(); } - const { attachTo, hydrateIn } = options; + const { attachTo, hydrateIn, wrappingComponentProps } = options; const domNode = hydrateIn || attachTo || global.document.createElement('div'); let instance = null; const adapter = this; @@ -321,6 +324,7 @@ class ReactSixteenAdapter extends EnzymeAdapter { const wrapperProps = { Component: type, props, + wrappingComponentProps, context, ...(ref && { ref }), }; @@ -341,7 +345,14 @@ class ReactSixteenAdapter extends EnzymeAdapter { instance = null; }, getNode() { - return instance ? toTree(instance._reactInternalFiber).rendered : null; + if (!instance) { + return null; + } + return getNodeFromRootFinder( + adapter.isCustomComponent, + toTree(instance._reactInternalFiber), + options, + ); }, simulateError(nodeHierarchy, rootNode, error) { const { instance: catchingInstance } = nodeHierarchy @@ -368,6 +379,15 @@ class ReactSixteenAdapter extends EnzymeAdapter { return fn(); // return ReactDOM.unstable_batchedUpdates(fn); }, + getWrappingComponentRenderer() { + return { + ...this, + ...getWrappingComponentMountRenderer({ + toTree: inst => toTree(inst._reactInternalFiber), + getMountWrapperInstance: () => instance, + }), + }; + }, }; } @@ -609,6 +629,13 @@ class ReactSixteenAdapter extends EnzymeAdapter { createElement(...args) { return React.createElement(...args); } + + wrapWithWrappingComponent(node, options) { + return { + RootFinder, + node: wrapWithWrappingComponent(React.createElement, node, options), + }; + } } module.exports = ReactSixteenAdapter; diff --git a/packages/enzyme-test-suite/test/Adapter-spec.jsx b/packages/enzyme-test-suite/test/Adapter-spec.jsx index b69933aec..0bed605a1 100644 --- a/packages/enzyme-test-suite/test/Adapter-spec.jsx +++ b/packages/enzyme-test-suite/test/Adapter-spec.jsx @@ -9,6 +9,7 @@ import { } from 'react-is'; import PropTypes from 'prop-types'; import wrap from 'mocha-wrap'; +import { wrapWithWrappingComponent, RootFinder } from 'enzyme-adapter-utils'; import './_helpers/setupAdapters'; import Adapter from './_helpers/adapter'; @@ -946,6 +947,23 @@ describe('Adapter', () => { }); }); + itIf(is('>0.13'), 'supports wrapping elements in a WrappingComponent', () => { + class WrappingComponent extends React.Component { + render() { + return null; + } + } + const node =
; + const options = { + mode: 'shallow', + wrappingComponent: WrappingComponent, + wrappingComponentProps: { foo: 'bar' }, + }; + const { RootFinder: ReturnedRootFinder, node: wrappedNode } = adapter.wrapWithWrappingComponent(node, options); + expect(ReturnedRootFinder).to.equal(RootFinder); + expect(wrappedNode).to.eql(wrapWithWrappingComponent(React.createElement, node, options)); + }); + describe('provides node displayNames', () => { const getDisplayName = el => adapter.displayNameOfNode(adapter.elementToNode(el));