diff --git a/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx b/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx index 8d0a8fe85..19473ba15 100644 --- a/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx +++ b/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx @@ -85,6 +85,48 @@ describeWithDOM('mount', () => { expect(spy).to.have.property('callCount', 1); }); + describe('wrapping invalid elements', () => { + itIf(is('>= 16'), 'should throw when mounting Portals', () => { + const portal = createPortal( +
, + { nodeType: 1 }, + ); + + expect(() => mount(portal)).to.throw( + Error, + 'ReactWrapper can only wrap valid elements', + ); + }); + + it('should throw when mounting plain text', () => { + expect(() => mount('Foo')).to.throw( + Error, + 'ReactWrapper can only wrap valid elements', + ); + }); + + it('should throw when mounting multiple elements', () => { + expect(() => mount([
])).to.throw( + TypeError, + 'ReactWrapper can only wrap valid elements', + ); + }); + }); + + it('should mount built in components', () => { + expect(() => mount(
)).not.to.throw(); + }); + + it('should mount composite components', () => { + class Foo extends React.Component { + render() { + return
; + } + } + + expect(() => mount()).not.to.throw(); + }); + describeIf(is('>= 16.3'), 'uses the isValidElementType from the Adapter to validate the prop type of Component', () => { const Foo = () => null; const Bar = () => null; diff --git a/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx b/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx index 0d74d92bc..d4286d9eb 100644 --- a/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx +++ b/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx @@ -20,6 +20,7 @@ import './_helpers/setupAdapters'; import { createClass, createContext, + createPortal, createRef, Fragment, forwardRef, @@ -77,6 +78,48 @@ describe('shallow', () => { expect(wrapper.children().type()).to.equal('div'); expect(wrapper.children().props().bam).to.equal(undefined); }); + + describe('wrapping invalid elements', () => { + itIf(is('>= 16'), 'should throw when shallow rendering Portals', () => { + const portal = createPortal( +
, + { nodeType: 1 }, + ); + + expect(() => shallow(portal)).to.throw( + Error, + 'ShallowWrapper can only wrap valid elements', + ); + }); + + it('should throw when shallow rendering plain text', () => { + expect(() => shallow('Foo')).to.throw( + Error, + 'ShallowWrapper can only wrap valid elements', + ); + }); + + it('should throw when shallow rendering multiple elements', () => { + expect(() => shallow([
])).to.throw( + TypeError, + 'ShallowWrapper can only wrap valid elements', + ); + }); + }); + + it('should shallow render built in components', () => { + expect(() => shallow(
)).not.to.throw(); + }); + + it('should shallow render composite components', () => { + class Foo extends React.Component { + render() { + return
; + } + } + + expect(() => shallow()).not.to.throw(); + }); }); describe('context', () => { diff --git a/packages/enzyme/src/ReactWrapper.js b/packages/enzyme/src/ReactWrapper.js index b7129320a..d40e8c17a 100644 --- a/packages/enzyme/src/ReactWrapper.js +++ b/packages/enzyme/src/ReactWrapper.js @@ -85,8 +85,13 @@ class ReactWrapper { const options = makeOptions(passedOptions); if (!root) { + const adapter = getAdapter(options); + if (!adapter.isValidElement(nodes)) { + throw new TypeError('ReactWrapper can only wrap valid elements'); + } + privateSet(this, UNRENDERED, nodes); - const renderer = getAdapter(options).createRenderer({ mode: 'mount', ...options }); + const renderer = adapter.createRenderer({ mode: 'mount', ...options }); privateSet(this, RENDERER, renderer); renderer.render(nodes, options.context); privateSet(this, ROOT, this); diff --git a/packages/enzyme/src/ShallowWrapper.js b/packages/enzyme/src/ShallowWrapper.js index ff1c5e40b..4c1801952 100644 --- a/packages/enzyme/src/ShallowWrapper.js +++ b/packages/enzyme/src/ShallowWrapper.js @@ -170,6 +170,10 @@ class ShallowWrapper { // mounting a ShallowRender component if (!root) { + if (!adapter.isValidElement(nodes)) { + throw new TypeError('ShallowWrapper can only wrap valid elements'); + } + privateSet(this, ROOT, this); privateSet(this, UNRENDERED, nodes); const renderer = adapter.createRenderer({ mode: 'shallow', ...options });