diff --git a/packages/enzyme-test-suite/test/Utils-spec.jsx b/packages/enzyme-test-suite/test/Utils-spec.jsx
index c6a2a27cb..55e23aa37 100644
--- a/packages/enzyme-test-suite/test/Utils-spec.jsx
+++ b/packages/enzyme-test-suite/test/Utils-spec.jsx
@@ -2,6 +2,7 @@ import React from 'react';
import { expect } from 'chai';
import wrap from 'mocha-wrap';
import sinon from 'sinon-sandbox';
+import cheerio from 'cheerio';
import {
childrenToSimplifiedArray,
nodeEqual,
@@ -14,6 +15,7 @@ import {
isEmptyValue,
renderedDive,
isCustomComponent,
+ loadCheerioRoot,
} from 'enzyme/build/Utils';
import getAdapter from 'enzyme/build/getAdapter';
import EnzymeAdapter from 'enzyme/build/EnzymeAdapter';
@@ -1073,4 +1075,17 @@ describe('Utils', () => {
expect(() => isCustomComponent({}, {})).to.throw(Error);
});
});
+
+ describe('loadCheerioRoot', () => {
+ it('always returns a Cheerio instance', () => {
+ expect(loadCheerioRoot()).to.be.an.instanceOf(cheerio);
+ expect(loadCheerioRoot(null)).to.be.an.instanceOf(cheerio);
+ expect(loadCheerioRoot("")).to.be.an.instanceOf(cheerio);
+ expect(loadCheerioRoot("foo")).to.be.an.instanceOf(cheerio);
+ expect(loadCheerioRoot("123")).to.be.an.instanceOf(cheerio);
+ expect(loadCheerioRoot("
bar
")).to.be.an.instanceOf(cheerio);
+ expect(loadCheerioRoot("leading text")).to.be.an.instanceOf(cheerio);
+ expect(loadCheerioRoot("malformed>< {
});
const context = { name: 'foo' };
- expect(() => render(, { context })).to.not.throw(Error);
+ expect(() => render(, { context })).not.to.throw();
+ });
+ });
+
+ describe('rendering non-elements', () => {
+ it('can render strings', () => {
+ const StringComponent = createClass({
+ render() {
+ return 'foo';
+ },
+ });
+
+ const getWrapper = (options) => render(, options);
+ if (is('>= 16')) {
+ expect(getWrapper).to.not.throw();
+
+ const wrapper = getWrapper();
+ expect(wrapper.text()).to.equal('foo');
+ expect(wrapper.html()).to.equal('foo');
+ expect(String(wrapper)).to.equal('foo');
+ expect(wrapper).to.have.lengthOf(1);
+ } else {
+ expect(getWrapper).to.throw();
+ }
+ });
+
+ it('can render numbers', () => {
+ const NumberComponent = createClass({
+ render() {
+ return 42;
+ },
+ });
+
+ const getWrapper = (options) => render(, options);
+ if (is('>= 16')) {
+ expect(getWrapper).to.not.throw();
+
+ const wrapper = getWrapper();
+ expect(wrapper.text()).to.equal('42');
+ expect(wrapper.html()).to.equal('42');
+ expect(String(wrapper)).to.equal('42');
+ expect(wrapper).to.have.lengthOf(1);
+ } else {
+ expect(getWrapper).to.throw();
+ }
});
});
diff --git a/packages/enzyme/package.json b/packages/enzyme/package.json
index 7a3dc4e2a..5787f9b6f 100644
--- a/packages/enzyme/package.json
+++ b/packages/enzyme/package.json
@@ -36,7 +36,7 @@
"license": "MIT",
"dependencies": {
"array.prototype.flat": "^1.2.1",
- "cheerio": "^1.0.0-rc.2",
+ "cheerio": "^1.0.0-rc.3",
"enzyme-shallow-equal": "^1.0.0",
"function.prototype.name": "^1.1.0",
"has": "^1.0.3",
diff --git a/packages/enzyme/src/ReactWrapper.js b/packages/enzyme/src/ReactWrapper.js
index 16980eecd..1e7987df3 100644
--- a/packages/enzyme/src/ReactWrapper.js
+++ b/packages/enzyme/src/ReactWrapper.js
@@ -1,4 +1,3 @@
-import cheerio from 'cheerio';
import flat from 'array.prototype.flat';
import has from 'has';
@@ -15,6 +14,7 @@ import {
cloneElement,
renderedDive,
isCustomComponent,
+ loadCheerioRoot,
} from './Utils';
import getAdapter from './getAdapter';
import { debugNodes } from './Debug';
@@ -650,7 +650,7 @@ class ReactWrapper {
*/
render() {
const html = this.html();
- return html === null ? cheerio() : cheerio.load('')(html);
+ return loadCheerioRoot(html);
}
/**
diff --git a/packages/enzyme/src/ShallowWrapper.js b/packages/enzyme/src/ShallowWrapper.js
index 7776ec10b..7bb437223 100644
--- a/packages/enzyme/src/ShallowWrapper.js
+++ b/packages/enzyme/src/ShallowWrapper.js
@@ -1,5 +1,4 @@
import flat from 'array.prototype.flat';
-import cheerio from 'cheerio';
import has from 'has';
import shallowEqual from 'enzyme-shallow-equal';
@@ -20,6 +19,7 @@ import {
cloneElement,
spyMethod,
isEmptyValue,
+ loadCheerioRoot,
} from './Utils';
import getAdapter from './getAdapter';
import { debugNodes } from './Debug';
@@ -1103,7 +1103,8 @@ class ShallowWrapper {
* @returns {CheerioWrapper}
*/
render() {
- return this.type() === null ? cheerio() : cheerio.load('')(this.html());
+ const html = this.html();
+ return loadCheerioRoot(html);
}
/**
diff --git a/packages/enzyme/src/Utils.js b/packages/enzyme/src/Utils.js
index 935c069d3..aa0d2edf1 100644
--- a/packages/enzyme/src/Utils.js
+++ b/packages/enzyme/src/Utils.js
@@ -6,6 +6,8 @@ import functionName from 'function.prototype.name';
import has from 'has';
import flat from 'array.prototype.flat';
import trim from 'string.prototype.trim';
+import cheerio from 'cheerio';
+import { isHtml } from 'cheerio/lib/utils';
import { get } from './configuration';
import { childrenOfNode } from './RSTTraversal';
@@ -350,3 +352,16 @@ export function renderedDive(nodes) {
return isEmptyValue(n);
});
}
+
+export function loadCheerioRoot(html) {
+ if (!html) {
+ return cheerio.root();
+ }
+
+ if (!isHtml(html)) {
+ // use isDocument=false to create fragment
+ return cheerio.load(html, null, false).root();
+ }
+
+ return cheerio.load('')(html);
+}
diff --git a/packages/enzyme/src/render.js b/packages/enzyme/src/render.js
index bd3871feb..69e12e2b2 100644
--- a/packages/enzyme/src/render.js
+++ b/packages/enzyme/src/render.js
@@ -1,5 +1,5 @@
-import cheerio from 'cheerio';
import getAdapter from './getAdapter';
+import { loadCheerioRoot } from './Utils';
/**
* Renders a react component into static HTML and provides a cheerio wrapper around it. This is
@@ -19,5 +19,5 @@ export default function render(node, options = {}) {
const adapter = getAdapter(options);
const renderer = adapter.createRenderer({ mode: 'string', ...options });
const html = renderer.render(node, options.context);
- return cheerio.load('')(html);
+ return loadCheerioRoot(html);
}