Skip to content

Commit

Permalink
[enzyme] [new] & [fix]: render: handle Fiber strings and numbers
Browse files Browse the repository at this point in the history
 - [enzyme] [fix] `render`: handle Fiber strings and numbers
 - [enzyme] [new] `Utils`: add `loadCheerioRoot`

Fixes #2098
  • Loading branch information
ottosichert authored and ljharb committed Aug 11, 2019
1 parent 66ff0d4 commit d9cc09e
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 8 deletions.
14 changes: 14 additions & 0 deletions packages/enzyme-test-suite/test/Utils-spec.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
isEmptyValue,
renderedDive,
isCustomComponent,
loadCheerioRoot,
} from 'enzyme/build/Utils';
import getAdapter from 'enzyme/build/getAdapter';
import EnzymeAdapter from 'enzyme/build/EnzymeAdapter';
Expand Down Expand Up @@ -1073,4 +1074,17 @@ describe('Utils', () => {
expect(() => isCustomComponent({}, {})).to.throw(Error);
});
});

describe('loadCheerioRoot', () => {
it('always returns a Cheerio instance', () => {
expect(loadCheerioRoot()).to.have.property('cheerio', '[cheerio object]');
expect(loadCheerioRoot(null)).to.have.property('cheerio', '[cheerio object]');
expect(loadCheerioRoot('')).to.have.property('cheerio', '[cheerio object]');
expect(loadCheerioRoot('foo')).to.have.property('cheerio', '[cheerio object]');
expect(loadCheerioRoot('123')).to.have.property('cheerio', '[cheerio object]');
expect(loadCheerioRoot('<div>bar</div>')).to.have.property('cheerio', '[cheerio object]');
expect(loadCheerioRoot('leading <span>text</span>')).to.have.property('cheerio', '[cheerio object]');
expect(loadCheerioRoot('<div>malformed</><<html')).to.have.property('cheerio', '[cheerio object]');
});
});
});
46 changes: 45 additions & 1 deletion packages/enzyme-test-suite/test/staticRender-spec.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,51 @@ describeWithDOM('render', () => {
});

const context = { name: 'foo' };
expect(() => render(<SimpleComponent />, { context })).to.not.throw(Error);
expect(() => render(<SimpleComponent />, { context })).not.to.throw();
});
});

describe('rendering non-elements', () => {
it('can render strings', () => {
const StringComponent = createClass({
render() {
return 'foo';
},
});

const getWrapper = (options) => render(<StringComponent />, 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(<NumberComponent />, 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();
}
});
});

Expand Down
2 changes: 1 addition & 1 deletion packages/enzyme/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
4 changes: 2 additions & 2 deletions packages/enzyme/src/ReactWrapper.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import cheerio from 'cheerio';
import flat from 'array.prototype.flat';
import has from 'has';

Expand All @@ -15,6 +14,7 @@ import {
cloneElement,
renderedDive,
isCustomComponent,
loadCheerioRoot,
} from './Utils';
import getAdapter from './getAdapter';
import { debugNodes } from './Debug';
Expand Down Expand Up @@ -650,7 +650,7 @@ class ReactWrapper {
*/
render() {
const html = this.html();
return html === null ? cheerio() : cheerio.load('')(html);
return loadCheerioRoot(html);
}

/**
Expand Down
5 changes: 3 additions & 2 deletions packages/enzyme/src/ShallowWrapper.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import flat from 'array.prototype.flat';
import cheerio from 'cheerio';
import has from 'has';
import shallowEqual from 'enzyme-shallow-equal';

Expand All @@ -20,6 +19,7 @@ import {
cloneElement,
spyMethod,
isEmptyValue,
loadCheerioRoot,
} from './Utils';
import getAdapter from './getAdapter';
import { debugNodes } from './Debug';
Expand Down Expand Up @@ -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);
}

/**
Expand Down
15 changes: 15 additions & 0 deletions packages/enzyme/src/Utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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);
}
4 changes: 2 additions & 2 deletions packages/enzyme/src/render.js
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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);
}

0 comments on commit d9cc09e

Please sign in to comment.