From d602a2266686b65ba00cdab872f9799536955998 Mon Sep 17 00:00:00 2001 From: Jason Quense Date: Mon, 9 Jul 2018 09:52:45 -0400 Subject: [PATCH 1/2] [enzyme-adapter-react-16]: [fix] portals and roots may render fragments --- .../src/ReactSixteenAdapter.js | 11 +++-- .../test/ReactWrapper-spec.jsx | 44 ++++++++++++++++++- .../enzyme-test-suite/test/_helpers/index.jsx | 8 ++++ 3 files changed, 58 insertions(+), 5 deletions(-) diff --git a/packages/enzyme-adapter-react-16/src/ReactSixteenAdapter.js b/packages/enzyme-adapter-react-16/src/ReactSixteenAdapter.js index 6b9576517..79ede478f 100644 --- a/packages/enzyme-adapter-react-16/src/ReactSixteenAdapter.js +++ b/packages/enzyme-adapter-react-16/src/ReactSixteenAdapter.js @@ -86,9 +86,10 @@ function toTree(vnode) { const node = findCurrentFiberUsingSlowPath(vnode); switch (node.tag) { case HostRoot: // 3 - return toTree(node.child); - case HostPortal: // 4 - return toTree(node.child); + return childrenToTree(node.child); + case HostPortal: { // 4 + return childrenToTree(node.child); + } case ClassComponent: return { nodeType: 'class', @@ -251,11 +252,13 @@ class ReactSixteenAdapter extends EnzymeAdapter { } else { isDOM = false; const { type: Component } = el; + const isStateful = Component.prototype && ( Component.prototype.isReactComponent || Array.isArray(Component.__reactAutoBindPairs) // fallback for createClass components ); - if (!isStateful) { + + if (!isStateful && typeof Component === 'function') { const wrappedEl = Object.assign( (...args) => Component(...args), // eslint-disable-line new-cap Component, diff --git a/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx b/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx index 12af2e7d0..5ed4d022c 100644 --- a/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx +++ b/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx @@ -16,7 +16,12 @@ import { } from 'enzyme/build/Utils'; import './_helpers/setupAdapters'; -import { createClass, createContext, createPortal } from './_helpers/react-compat'; +import { + createClass, + createContext, + createPortal, + Fragment, +} from './_helpers/react-compat'; import { describeWithDOM, describeIf, @@ -776,6 +781,43 @@ describeWithDOM('mount', () => { expect(wrapper.find('button')).to.have.lengthOf(1); }); + itIf(is('>= 16.2'), 'should support fragments', () => { + const wrapper = mount(( + +

hello

+ boo +
+ )); + + expect(wrapper).to.have.lengthOf(2); + }); + + itIf(is('>= 16'), 'should find elements through portals', () => { + const containerDiv = global.document.createElement('div'); + class FooPortal extends React.Component { + render() { + return createPortal( + this.props.children, + containerDiv, + ); + } + } + + + const wrapper = mount(( + +

Successful Portal!

+ +
+ )); + + expect(wrapper.find('h1')).to.have.lengthOf(1); + + expect(wrapper.find('span')).to.have.lengthOf(1); + + expect(containerDiv.querySelectorAll('h1')).to.have.lengthOf(1); + }); + it('should support object property selectors', () => { const wrapper = mount((
diff --git a/packages/enzyme-test-suite/test/_helpers/index.jsx b/packages/enzyme-test-suite/test/_helpers/index.jsx index 52274d910..b16c4f37f 100644 --- a/packages/enzyme-test-suite/test/_helpers/index.jsx +++ b/packages/enzyme-test-suite/test/_helpers/index.jsx @@ -26,6 +26,14 @@ export function itIf(test, a, b) { } } +itIf.only = (test, a, b) => { + if (test) { + it.only(a, b); + } else { + it.skip(a, b); + } +}; + /** * Simple wrapper around mocha it which allows an array of possible values to test against. * Each test will be wrapped in a try/catch block to handle any errors. From 30b797075cf061c6ebebdf0f9b61c6873dd6e135 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Fri, 27 Jul 2018 14:33:52 -0700 Subject: [PATCH 2/2] [Tests] fail early if `describeIf`/`itIf` receives a non-boolean --- packages/enzyme-test-suite/test/ReactWrapper-spec.jsx | 2 +- packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx | 2 +- packages/enzyme-test-suite/test/_helpers/index.jsx | 8 ++++++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx b/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx index 5ed4d022c..5251147d2 100644 --- a/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx +++ b/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx @@ -4235,7 +4235,7 @@ describeWithDOM('mount', () => { }); }); - describeIf(ITERATOR_SYMBOL, '@@iterator', () => { + describeIf(!!ITERATOR_SYMBOL, '@@iterator', () => { it('should be iterable', () => { class Foo extends React.Component { render() { diff --git a/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx b/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx index ca1c3647a..20279b4d3 100644 --- a/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx +++ b/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx @@ -5173,7 +5173,7 @@ describe('shallow', () => { }); }); - describeIf(ITERATOR_SYMBOL, '@@iterator', () => { + describeIf(!!ITERATOR_SYMBOL, '@@iterator', () => { it('should be iterable', () => { class Foo extends React.Component { render() { diff --git a/packages/enzyme-test-suite/test/_helpers/index.jsx b/packages/enzyme-test-suite/test/_helpers/index.jsx index b16c4f37f..c3c9e7bbc 100644 --- a/packages/enzyme-test-suite/test/_helpers/index.jsx +++ b/packages/enzyme-test-suite/test/_helpers/index.jsx @@ -7,6 +7,10 @@ import React from 'react'; * determines whether or not the test will be run */ export function describeIf(test, a, b) { + if (typeof test !== 'boolean') { + throw new TypeError(`a boolean is required, you passed a ${typeof test}`); + } + if (test) { describe(a, b); } else { @@ -19,6 +23,10 @@ export function describeIf(test, a, b) { * determines whether or not the test will be run */ export function itIf(test, a, b) { + if (typeof test !== 'boolean') { + throw new TypeError(`a boolean is required, you passed a ${typeof test}`); + } + if (test) { it(a, b); } else {