Skip to content

Commit

Permalink
[Fix] render: handle Fiber strings and numbers
Browse files Browse the repository at this point in the history
- Fix enzymejs#2098
- Introduce `loadCheerioRoot` util
- Use util in `render`, `mount` and `shallow`
  • Loading branch information
ottosichert committed Sep 16, 2019
1 parent 0494f16 commit b530e0c
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 6 deletions.
36 changes: 36 additions & 0 deletions packages/enzyme-test-suite/test/staticRender-spec.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,42 @@ describeWithDOM('render', () => {
});
});

describeIf(is('>= 16'), 'React Fiber', () => {
it('can render strings', () => {
const StringComponent = createClass({
render() {
return 'foo';
},
});

const getWrapper = options => render(<StringComponent />, options);
expect(getWrapper).to.not.throw(Error);

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);
});

it('can render numbers', () => {
const NumberComponent = createClass({
render() {
return 42;
},
});

const getWrapper = options => render(<NumberComponent />, options);
expect(getWrapper).to.not.throw(Error);

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);
});
});

describeIf(is('> 16.6'), 'suspense fallback option', () => {
it('throws if options.suspenseFallback is specified', () => {
class DynamicComponent extends React.Component {
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 b530e0c

Please sign in to comment.