From 44ac5f6cd8396aa63683412a313c0d6c3258ce3b Mon Sep 17 00:00:00 2001 From: Son Hai Ngoc Tang Date: Tue, 21 Feb 2017 19:48:09 +0700 Subject: [PATCH 1/2] [Refactor] Rename `src/render` to `.jsx` so `git mv` works properly. --- src/{render.js => render.jsx} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{render.js => render.jsx} (100%) diff --git a/src/render.js b/src/render.jsx similarity index 100% rename from src/render.js rename to src/render.jsx From 361d34b646067dd69ffc25a67ae0999c88233da3 Mon Sep 17 00:00:00 2001 From: hunterbmt Date: Wed, 22 Feb 2017 08:40:29 +0700 Subject: [PATCH 2/2] [New] `render`: add support for `context` --- docs/api/render.md | 15 +++++++++- src/render.jsx | 29 ++++++++++++++++++- test/staticRender-spec.jsx | 57 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 test/staticRender-spec.jsx diff --git a/docs/api/render.md b/docs/api/render.md index dab1cf262..3123b25c3 100644 --- a/docs/api/render.md +++ b/docs/api/render.md @@ -19,7 +19,6 @@ constructors. import { render } from 'enzyme'; describe('', () => { - it('renders three `.foo-bar`s', () => { const wrapper = render(); expect(wrapper.find('.foo-bar')).to.have.length(3); @@ -30,5 +29,19 @@ describe('', () => { expect(wrapper.text()).to.contain("unique"); }); + it('can pass in context', () => { + const SimpleComponent = React.createClass({ + contextTypes: { + name: React.PropTypes.string, + }, + render() { + return
{this.context.name}
; + }, + }); + + const context = { name: 'foo' }; + const wrapper = render(, { context }); + expect(wrapper.text()).to.equal('foo'); + }); }); ``` diff --git a/src/render.jsx b/src/render.jsx index 0ba17df60..ac98fa359 100644 --- a/src/render.jsx +++ b/src/render.jsx @@ -1,3 +1,5 @@ +import React from 'react'; +import objectAssign from 'object.assign'; import cheerio from 'cheerio'; import { renderToStaticMarkup } from './react-compat'; @@ -11,9 +13,34 @@ import { renderToStaticMarkup } from './react-compat'; * thus I'd like to keep this API in here even though it's not really "ours". * * @param node + * @param options * @returns {Cheerio} */ -export default function render(node) { + +function createContextWrapperForNode(node, context, childContextTypes) { + class ContextWrapper extends React.Component { + getChildContext() { + return context; + } + render() { + return node; + } + } + ContextWrapper.childContextTypes = childContextTypes; + return ContextWrapper; +} + +export default function render(node, options = {}) { + if (options.context && (node.type.contextTypes || options.childContextTypes)) { + const childContextTypes = objectAssign( + {}, + node.type.contextTypes || {}, + options.childContextTypes, + ); + const ContextWrapper = createContextWrapperForNode(node, options.context, childContextTypes); + const html = renderToStaticMarkup(); + return cheerio.load(html).root(); + } const html = renderToStaticMarkup(node); return cheerio.load(html).root(); } diff --git a/test/staticRender-spec.jsx b/test/staticRender-spec.jsx new file mode 100644 index 000000000..39a1c663d --- /dev/null +++ b/test/staticRender-spec.jsx @@ -0,0 +1,57 @@ +import React from 'react'; +import { expect } from 'chai'; +import { describeWithDOM, describeIf } from './_helpers'; +import { render } from '../src/'; +import { REACT013 } from '../src/version'; + +describeWithDOM('render', () => { + describeIf(!REACT013, 'context', () => { + it('can pass in context', () => { + const SimpleComponent = React.createClass({ + contextTypes: { + name: React.PropTypes.string, + }, + render() { + return
{this.context.name}
; + }, + }); + + const context = { name: 'foo' }; + const wrapper = render(, { context }); + expect(wrapper.text()).to.equal('foo'); + }); + it('can pass context to the child of mounted component', () => { + const SimpleComponent = React.createClass({ + contextTypes: { + name: React.PropTypes.string, + }, + render() { + return
{this.context.name}
; + }, + }); + const ComplexComponent = React.createClass({ + render() { + return
; + }, + }); + + const childContextTypes = { + name: React.PropTypes.string.isRequired, + }; + const context = { name: 'foo' }; + const wrapper = render(, { context, childContextTypes }); + expect(wrapper.children()).to.have.length(1); + expect(wrapper.children().first().text()).to.equal('foo'); + }); + it('should not throw if context is passed in but contextTypes is missing', () => { + const SimpleComponent = React.createClass({ + render() { + return
{this.context.name}
; + }, + }); + + const context = { name: 'foo' }; + expect(() => render(, { context })).to.not.throw(Error); + }); + }); +});