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.js b/src/render.js
deleted file mode 100644
index 0ba17df60..000000000
--- a/src/render.js
+++ /dev/null
@@ -1,19 +0,0 @@
-import cheerio from 'cheerio';
-import { renderToStaticMarkup } from './react-compat';
-
-/**
- * Renders a react component into static HTML and provides a cheerio wrapper around it. This is
- * somewhat asymmetric with `mount` and `shallow`, which don't use any external libraries, but
- * Cheerio's API is pretty close to what we actually want and has a significant amount of utility
- * that would be recreating the wheel if we didn't use it.
- *
- * I think there are a lot of good use cases to use `render` instead of `shallow` or `mount`, and
- * thus I'd like to keep this API in here even though it's not really "ours".
- *
- * @param node
- * @returns {Cheerio}
- */
-export default function render(node) {
- const html = renderToStaticMarkup(node);
- return cheerio.load(html).root();
-}
diff --git a/src/render.jsx b/src/render.jsx
new file mode 100644
index 000000000..ac98fa359
--- /dev/null
+++ b/src/render.jsx
@@ -0,0 +1,46 @@
+import React from 'react';
+import objectAssign from 'object.assign';
+import cheerio from 'cheerio';
+import { renderToStaticMarkup } from './react-compat';
+
+/**
+ * Renders a react component into static HTML and provides a cheerio wrapper around it. This is
+ * somewhat asymmetric with `mount` and `shallow`, which don't use any external libraries, but
+ * Cheerio's API is pretty close to what we actually want and has a significant amount of utility
+ * that would be recreating the wheel if we didn't use it.
+ *
+ * I think there are a lot of good use cases to use `render` instead of `shallow` or `mount`, and
+ * thus I'd like to keep this API in here even though it's not really "ours".
+ *
+ * @param node
+ * @param options
+ * @returns {Cheerio}
+ */
+
+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);
+ });
+ });
+});