diff --git a/src/renderers/dom/test/__tests__/ReactTestUtils-test.js b/src/renderers/dom/test/__tests__/ReactTestUtils-test.js
index edc11927a7612..09337a0caea6d 100644
--- a/src/renderers/dom/test/__tests__/ReactTestUtils-test.js
+++ b/src/renderers/dom/test/__tests__/ReactTestUtils-test.js
@@ -12,7 +12,6 @@
'use strict';
let createRenderer;
-let PropTypes;
let React;
let ReactDOM;
let ReactDOMServer;
@@ -21,625 +20,12 @@ let ReactTestUtils;
describe('ReactTestUtils', () => {
beforeEach(() => {
createRenderer = require('react-test-renderer/shallow').createRenderer;
- PropTypes = require('prop-types');
React = require('react');
ReactDOM = require('react-dom');
ReactDOMServer = require('react-dom/server');
ReactTestUtils = require('react-dom/test-utils');
});
- it('should call all of the lifecycle hooks', () => {
- const logs = [];
- const logger = message => () => logs.push(message) || true;
-
- class SomeComponent extends React.Component {
- componentWillMount = logger('componentWillMount');
- componentDidMount = logger('componentDidMount');
- componentWillReceiveProps = logger('componentWillReceiveProps');
- shouldComponentUpdate = logger('shouldComponentUpdate');
- componentWillUpdate = logger('componentWillUpdate');
- componentDidUpdate = logger('componentDidUpdate');
- componentWillUnmount = logger('componentWillUnmount');
- render() {
- return
{}}
- onClick={this.handleUserClick}
- className={this.state.clicked ? 'clicked' : ''}
- />
- );
- }
- }
-
- const shallowRenderer = createRenderer();
- shallowRenderer.render(
);
- let result = shallowRenderer.getRenderOutput();
- expect(result.type).toEqual('div');
- expect(result.props.className).toEqual('');
- result.props.onClick();
-
- result = shallowRenderer.getRenderOutput();
- expect(result.type).toEqual('div');
- expect(result.props.className).toEqual('clicked');
- });
-
- it('can setState in componentWillMount when shallow rendering', () => {
- class SimpleComponent extends React.Component {
- componentWillMount() {
- this.setState({groovy: 'doovy'});
- }
-
- render() {
- return
{this.state.groovy}
;
- }
- }
-
- const shallowRenderer = createRenderer();
- const result = shallowRenderer.render(
);
- expect(result).toEqual(
doovy
);
- });
-
- it('can setState in componentWillReceiveProps when shallow rendering', () => {
- class SimpleComponent extends React.Component {
- state = {count: 0};
-
- componentWillReceiveProps(nextProps) {
- if (nextProps.updateState) {
- this.setState({count: 1});
- }
- }
-
- render() {
- return
{this.state.count}
;
- }
- }
-
- const shallowRenderer = createRenderer();
- let result = shallowRenderer.render(
-
,
- );
- expect(result.props.children).toEqual(0);
-
- result = shallowRenderer.render(
);
- expect(result.props.children).toEqual(1);
- });
-
- it('can setState with an updater function', () => {
- let instance;
-
- class SimpleComponent extends React.Component {
- state = {
- counter: 0,
- };
-
- render() {
- instance = this;
- return (
-
- );
- }
- }
-
- const shallowRenderer = createRenderer();
- let result = shallowRenderer.render(
);
- expect(result.props.children).toEqual(0);
-
- instance.setState((state, props) => {
- return {counter: props.defaultCount + 1};
- });
-
- result = shallowRenderer.getRenderOutput();
- expect(result.props.children).toEqual(2);
- });
-
- it('can setState with a callback', () => {
- let instance;
-
- class SimpleComponent extends React.Component {
- state = {
- counter: 0,
- };
- render() {
- instance = this;
- return (
-
- {this.state.counter}
-
- );
- }
- }
-
- const shallowRenderer = createRenderer();
- const result = shallowRenderer.render(
);
- expect(result.props.children).toBe(0);
-
- const callback = jest.fn(function() {
- expect(this).toBe(instance);
- });
-
- instance.setState({counter: 1}, callback);
-
- const updated = shallowRenderer.getRenderOutput();
- expect(updated.props.children).toBe(1);
- expect(callback).toHaveBeenCalled();
- });
-
- it('can replaceState with a callback', () => {
- let instance;
-
- class SimpleComponent extends React.Component {
- state = {
- counter: 0,
- };
- render() {
- instance = this;
- return (
-
- {this.state.counter}
-
- );
- }
- }
-
- const shallowRenderer = createRenderer();
- const result = shallowRenderer.render(
);
- expect(result.props.children).toBe(0);
-
- const callback = jest.fn(function() {
- expect(this).toBe(instance);
- });
-
- // No longer a public API, but we can test that it works internally by
- // reaching into the updater.
- shallowRenderer._updater.enqueueReplaceState(
- instance,
- {counter: 1},
- callback,
- );
-
- const updated = shallowRenderer.getRenderOutput();
- expect(updated.props.children).toBe(1);
- expect(callback).toHaveBeenCalled();
- });
-
- it('can forceUpdate with a callback', () => {
- let instance;
-
- class SimpleComponent extends React.Component {
- state = {
- counter: 0,
- };
- render() {
- instance = this;
- return (
-
- {this.state.counter}
-
- );
- }
- }
-
- const shallowRenderer = createRenderer();
- const result = shallowRenderer.render(
);
- expect(result.props.children).toBe(0);
-
- const callback = jest.fn(function() {
- expect(this).toBe(instance);
- });
-
- instance.forceUpdate(callback);
-
- const updated = shallowRenderer.getRenderOutput();
- expect(updated.props.children).toBe(0);
- expect(callback).toHaveBeenCalled();
- });
-
- it('can pass context when shallowly rendering', () => {
- class SimpleComponent extends React.Component {
- static contextTypes = {
- name: PropTypes.string,
- };
-
- render() {
- return
{this.context.name}
;
- }
- }
-
- const shallowRenderer = createRenderer();
- const result = shallowRenderer.render(
, {
- name: 'foo',
- });
- expect(result).toEqual(
foo
);
- });
-
- it('should track context across updates', () => {
- class SimpleComponent extends React.Component {
- static contextTypes = {
- foo: PropTypes.string,
- };
-
- state = {
- bar: 'bar',
- };
-
- render() {
- return
{`${this.context.foo}:${this.state.bar}`}
;
- }
- }
-
- const shallowRenderer = createRenderer();
- let result = shallowRenderer.render(
, {
- foo: 'foo',
- });
- expect(result).toEqual(
foo:bar
);
-
- const instance = shallowRenderer.getMountedInstance();
- instance.setState({bar: 'baz'});
-
- result = shallowRenderer.getRenderOutput();
- expect(result).toEqual(
foo:baz
);
- });
-
- it('can fail context when shallowly rendering', () => {
- spyOn(console, 'error');
-
- class SimpleComponent extends React.Component {
- static contextTypes = {
- name: PropTypes.string.isRequired,
- };
-
- render() {
- return
{this.context.name}
;
- }
- }
-
- const shallowRenderer = createRenderer();
- shallowRenderer.render(
);
- expectDev(console.error.calls.count()).toBe(1);
- expect(
- console.error.calls.argsFor(0)[0].replace(/\(at .+?:\d+\)/g, '(at **)'),
- ).toBe(
- 'Warning: Failed context type: The context `name` is marked as ' +
- 'required in `SimpleComponent`, but its value is `undefined`.\n' +
- ' in SimpleComponent (at **)',
- );
- });
-
- it('should warn about propTypes (but only once)', () => {
- spyOn(console, 'error');
-
- class SimpleComponent extends React.Component {
- render() {
- return React.createElement('div', null, this.props.name);
- }
- }
-
- SimpleComponent.propTypes = {
- name: PropTypes.string.isRequired,
- };
-
- const shallowRenderer = createRenderer();
- shallowRenderer.render(React.createElement(SimpleComponent, {name: 123}));
-
- expect(console.error.calls.count()).toBe(1);
- expect(
- console.error.calls.argsFor(0)[0].replace(/\(at .+?:\d+\)/g, '(at **)'),
- ).toBe(
- 'Warning: Failed prop type: Invalid prop `name` of type `number` ' +
- 'supplied to `SimpleComponent`, expected `string`.\n' +
- ' in SimpleComponent',
- );
- });
-
it('can scryRenderedDOMComponentsWithClass with TextComponent', () => {
class Wrapper extends React.Component {
render() {
@@ -917,31 +303,6 @@ describe('ReactTestUtils', () => {
expect(hrs.length).toBe(2);
});
- it('should enable rendering of cloned element', () => {
- class SimpleComponent extends React.Component {
- constructor(props) {
- super(props);
-
- this.state = {
- bar: 'bar',
- };
- }
-
- render() {
- return
{`${this.props.foo}:${this.state.bar}`}
;
- }
- }
-
- const shallowRenderer = createRenderer();
- let result = shallowRenderer.render(
);
- expect(result).toEqual(
foo:bar
);
-
- const instance = shallowRenderer.getMountedInstance();
- const cloned = React.cloneElement(instance, {foo: 'baz'});
- result = shallowRenderer.render(cloned);
- expect(result).toEqual(
baz:bar
);
- });
-
describe('Simulate', () => {
it('should set the type of the event', () => {
let event;
diff --git a/src/renderers/testing/__tests__/ReactShallowRenderer-test.js b/src/renderers/testing/__tests__/ReactShallowRenderer-test.js
new file mode 100644
index 0000000000000..40535673b2cc5
--- /dev/null
+++ b/src/renderers/testing/__tests__/ReactShallowRenderer-test.js
@@ -0,0 +1,661 @@
+/**
+ * Copyright 2013-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ *
+ * @emails react-core
+ */
+
+'use strict';
+
+let createRenderer;
+let PropTypes;
+let React;
+
+describe('ReactTestUtils', () => {
+ beforeEach(() => {
+ createRenderer = require('react-test-renderer/shallow').createRenderer;
+ PropTypes = require('prop-types');
+ React = require('react');
+ });
+
+ it('should call all of the lifecycle hooks', () => {
+ const logs = [];
+ const logger = message => () => logs.push(message) || true;
+
+ class SomeComponent extends React.Component {
+ componentWillMount = logger('componentWillMount');
+ componentDidMount = logger('componentDidMount');
+ componentWillReceiveProps = logger('componentWillReceiveProps');
+ shouldComponentUpdate = logger('shouldComponentUpdate');
+ componentWillUpdate = logger('componentWillUpdate');
+ componentDidUpdate = logger('componentDidUpdate');
+ componentWillUnmount = logger('componentWillUnmount');
+ render() {
+ return
;
+ }
+ }
+
+ const shallowRenderer = createRenderer();
+ shallowRenderer.render(
);
+
+ // Calling cDU might lead to problems with host component references.
+ // Since our components aren't really mounted, refs won't be available.
+ expect(logs).toEqual(['componentWillMount']);
+
+ logs.splice(0);
+
+ const instance = shallowRenderer.getMountedInstance();
+ instance.setState({});
+
+ // The previous shallow renderer triggered cDU for setState() calls.
+ expect(logs).toEqual([
+ 'shouldComponentUpdate',
+ 'componentWillUpdate',
+ 'componentDidUpdate',
+ ]);
+
+ logs.splice(0);
+
+ shallowRenderer.render(
);
+
+ // The previous shallow renderer did not trigger cDU for props changes.
+ expect(logs).toEqual([
+ 'componentWillReceiveProps',
+ 'shouldComponentUpdate',
+ 'componentWillUpdate',
+ ]);
+ });
+
+ it('should only render 1 level deep', () => {
+ function Parent() {
+ return
;
+ }
+ function Child() {
+ throw Error('This component should not render');
+ }
+
+ const shallowRenderer = createRenderer();
+ shallowRenderer.render(React.createElement(Parent));
+ });
+
+ it('should have shallow rendering', () => {
+ class SomeComponent extends React.Component {
+ render() {
+ return (
+
+
+
+
+ );
+ }
+ }
+
+ const shallowRenderer = createRenderer();
+ const result = shallowRenderer.render(
);
+
+ expect(result.type).toBe('div');
+ expect(result.props.children).toEqual([
+
,
+
,
+ ]);
+ });
+
+ it('should enable shouldComponentUpdate to prevent a re-render', () => {
+ let renderCounter = 0;
+ class SimpleComponent extends React.Component {
+ state = {update: false};
+ shouldComponentUpdate(nextProps, nextState) {
+ return this.state.update !== nextState.update;
+ }
+ render() {
+ renderCounter++;
+ return
{`${renderCounter}`}
;
+ }
+ }
+
+ const shallowRenderer = createRenderer();
+ shallowRenderer.render(
);
+ expect(shallowRenderer.getRenderOutput()).toEqual(
1
);
+
+ const instance = shallowRenderer.getMountedInstance();
+ instance.setState({update: false});
+ expect(shallowRenderer.getRenderOutput()).toEqual(
1
);
+
+ instance.setState({update: true});
+ expect(shallowRenderer.getRenderOutput()).toEqual(
2
);
+ });
+
+ it('should shallow render a functional component', () => {
+ function SomeComponent(props, context) {
+ return (
+
+
{props.foo}
+
{context.bar}
+
+
+
+ );
+ }
+
+ const shallowRenderer = createRenderer();
+ const result = shallowRenderer.render(
, {
+ bar: 'BAR',
+ });
+
+ expect(result.type).toBe('div');
+ expect(result.props.children).toEqual([
+
FOO
,
+
BAR
,
+
,
+
,
+ ]);
+ });
+
+ it('should shallow render a component returning strings directly from render', () => {
+ const Text = ({value}) => value;
+
+ const shallowRenderer = createRenderer();
+ const result = shallowRenderer.render(
);
+ expect(result).toEqual('foo');
+ });
+
+ it('should shallow render a component returning numbers directly from render', () => {
+ const Text = ({value}) => value;
+
+ const shallowRenderer = createRenderer();
+ const result = shallowRenderer.render(
);
+ expect(result).toEqual(10);
+ });
+
+ it('should shallow render a fragment', () => {
+ class SomeComponent extends React.Component {
+ render() {
+ return
;
+ }
+ }
+ class Fragment extends React.Component {
+ render() {
+ return [
,
,
];
+ }
+ }
+ const shallowRenderer = createRenderer();
+ const result = shallowRenderer.render(
);
+ expect(result).toEqual([
+
,
+
,
+
,
+ ]);
+ });
+
+ it('should throw for invalid elements', () => {
+ class SomeComponent extends React.Component {
+ render() {
+ return
;
+ }
+ }
+
+ const shallowRenderer = createRenderer();
+ expect(() => shallowRenderer.render(SomeComponent)).toThrowError(
+ 'ReactShallowRenderer render(): Invalid component element. Instead of ' +
+ 'passing a component class, make sure to instantiate it by passing it ' +
+ 'to React.createElement.',
+ );
+ expect(() => shallowRenderer.render(
)).toThrowError(
+ 'ReactShallowRenderer render(): Shallow rendering works only with ' +
+ 'custom components, not primitives (div). Instead of calling ' +
+ '`.render(el)` and inspecting the rendered output, look at `el.props` ' +
+ 'directly instead.',
+ );
+ });
+
+ it('should have shallow unmounting', () => {
+ const componentWillUnmount = jest.fn();
+
+ class SomeComponent extends React.Component {
+ componentWillUnmount = componentWillUnmount;
+ render() {
+ return
;
+ }
+ }
+
+ const shallowRenderer = createRenderer();
+ shallowRenderer.render(
);
+ shallowRenderer.unmount();
+
+ expect(componentWillUnmount).toBeCalled();
+ });
+
+ it('can shallow render to null', () => {
+ class SomeComponent extends React.Component {
+ render() {
+ return null;
+ }
+ }
+
+ const shallowRenderer = createRenderer();
+ const result = shallowRenderer.render(
);
+
+ expect(result).toBe(null);
+ });
+
+ it('can shallow render with a ref', () => {
+ class SomeComponent extends React.Component {
+ render() {
+ return
;
+ }
+ }
+
+ const shallowRenderer = createRenderer();
+ // Shouldn't crash.
+ shallowRenderer.render(
);
+ });
+
+ it('lets you update shallowly rendered components', () => {
+ class SomeComponent extends React.Component {
+ state = {clicked: false};
+
+ onClick = () => {
+ this.setState({clicked: true});
+ };
+
+ render() {
+ const className = this.state.clicked ? 'was-clicked' : '';
+
+ if (this.props.aNew === 'prop') {
+ return (
+
+ Test link
+
+ );
+ } else {
+ return (
+
+
+
+
+ );
+ }
+ }
+ }
+
+ const shallowRenderer = createRenderer();
+ const result = shallowRenderer.render(
);
+ expect(result.type).toBe('div');
+ expect(result.props.children).toEqual([
+
,
+
,
+ ]);
+
+ const updatedResult = shallowRenderer.render(
);
+ expect(updatedResult.type).toBe('a');
+
+ const mockEvent = {};
+ updatedResult.props.onClick(mockEvent);
+
+ const updatedResultCausedByClick = shallowRenderer.getRenderOutput();
+ expect(updatedResultCausedByClick.type).toBe('a');
+ expect(updatedResultCausedByClick.props.className).toBe('was-clicked');
+ });
+
+ it('can access the mounted component instance', () => {
+ class SimpleComponent extends React.Component {
+ someMethod = () => {
+ return this.props.n;
+ };
+
+ render() {
+ return
{this.props.n}
;
+ }
+ }
+
+ const shallowRenderer = createRenderer();
+ shallowRenderer.render(
);
+ expect(shallowRenderer.getMountedInstance().someMethod()).toEqual(5);
+ });
+
+ it('can shallowly render components with contextTypes', () => {
+ class SimpleComponent extends React.Component {
+ static contextTypes = {
+ name: PropTypes.string,
+ };
+
+ render() {
+ return
;
+ }
+ }
+
+ const shallowRenderer = createRenderer();
+ const result = shallowRenderer.render(
);
+ expect(result).toEqual(
);
+ });
+
+ it('can shallowly render components with ref as function', () => {
+ class SimpleComponent extends React.Component {
+ state = {clicked: false};
+
+ handleUserClick = () => {
+ this.setState({clicked: true});
+ };
+
+ render() {
+ return (
+
{}}
+ onClick={this.handleUserClick}
+ className={this.state.clicked ? 'clicked' : ''}
+ />
+ );
+ }
+ }
+
+ const shallowRenderer = createRenderer();
+ shallowRenderer.render(
);
+ let result = shallowRenderer.getRenderOutput();
+ expect(result.type).toEqual('div');
+ expect(result.props.className).toEqual('');
+ result.props.onClick();
+
+ result = shallowRenderer.getRenderOutput();
+ expect(result.type).toEqual('div');
+ expect(result.props.className).toEqual('clicked');
+ });
+
+ it('can setState in componentWillMount when shallow rendering', () => {
+ class SimpleComponent extends React.Component {
+ componentWillMount() {
+ this.setState({groovy: 'doovy'});
+ }
+
+ render() {
+ return
{this.state.groovy}
;
+ }
+ }
+
+ const shallowRenderer = createRenderer();
+ const result = shallowRenderer.render(
);
+ expect(result).toEqual(
doovy
);
+ });
+
+ it('can setState in componentWillReceiveProps when shallow rendering', () => {
+ class SimpleComponent extends React.Component {
+ state = {count: 0};
+
+ componentWillReceiveProps(nextProps) {
+ if (nextProps.updateState) {
+ this.setState({count: 1});
+ }
+ }
+
+ render() {
+ return
{this.state.count}
;
+ }
+ }
+
+ const shallowRenderer = createRenderer();
+ let result = shallowRenderer.render(
+
,
+ );
+ expect(result.props.children).toEqual(0);
+
+ result = shallowRenderer.render(
);
+ expect(result.props.children).toEqual(1);
+ });
+
+ it('can setState with an updater function', () => {
+ let instance;
+
+ class SimpleComponent extends React.Component {
+ state = {
+ counter: 0,
+ };
+
+ render() {
+ instance = this;
+ return (
+
+ );
+ }
+ }
+
+ const shallowRenderer = createRenderer();
+ let result = shallowRenderer.render(
);
+ expect(result.props.children).toEqual(0);
+
+ instance.setState((state, props) => {
+ return {counter: props.defaultCount + 1};
+ });
+
+ result = shallowRenderer.getRenderOutput();
+ expect(result.props.children).toEqual(2);
+ });
+
+ it('can setState with a callback', () => {
+ let instance;
+
+ class SimpleComponent extends React.Component {
+ state = {
+ counter: 0,
+ };
+ render() {
+ instance = this;
+ return (
+
+ {this.state.counter}
+
+ );
+ }
+ }
+
+ const shallowRenderer = createRenderer();
+ const result = shallowRenderer.render(
);
+ expect(result.props.children).toBe(0);
+
+ const callback = jest.fn(function() {
+ expect(this).toBe(instance);
+ });
+
+ instance.setState({counter: 1}, callback);
+
+ const updated = shallowRenderer.getRenderOutput();
+ expect(updated.props.children).toBe(1);
+ expect(callback).toHaveBeenCalled();
+ });
+
+ it('can replaceState with a callback', () => {
+ let instance;
+
+ class SimpleComponent extends React.Component {
+ state = {
+ counter: 0,
+ };
+ render() {
+ instance = this;
+ return (
+
+ {this.state.counter}
+
+ );
+ }
+ }
+
+ const shallowRenderer = createRenderer();
+ const result = shallowRenderer.render(
);
+ expect(result.props.children).toBe(0);
+
+ const callback = jest.fn(function() {
+ expect(this).toBe(instance);
+ });
+
+ // No longer a public API, but we can test that it works internally by
+ // reaching into the updater.
+ shallowRenderer._updater.enqueueReplaceState(
+ instance,
+ {counter: 1},
+ callback,
+ );
+
+ const updated = shallowRenderer.getRenderOutput();
+ expect(updated.props.children).toBe(1);
+ expect(callback).toHaveBeenCalled();
+ });
+
+ it('can forceUpdate with a callback', () => {
+ let instance;
+
+ class SimpleComponent extends React.Component {
+ state = {
+ counter: 0,
+ };
+ render() {
+ instance = this;
+ return (
+
+ {this.state.counter}
+
+ );
+ }
+ }
+
+ const shallowRenderer = createRenderer();
+ const result = shallowRenderer.render(
);
+ expect(result.props.children).toBe(0);
+
+ const callback = jest.fn(function() {
+ expect(this).toBe(instance);
+ });
+
+ instance.forceUpdate(callback);
+
+ const updated = shallowRenderer.getRenderOutput();
+ expect(updated.props.children).toBe(0);
+ expect(callback).toHaveBeenCalled();
+ });
+
+ it('can pass context when shallowly rendering', () => {
+ class SimpleComponent extends React.Component {
+ static contextTypes = {
+ name: PropTypes.string,
+ };
+
+ render() {
+ return
{this.context.name}
;
+ }
+ }
+
+ const shallowRenderer = createRenderer();
+ const result = shallowRenderer.render(
, {
+ name: 'foo',
+ });
+ expect(result).toEqual(
foo
);
+ });
+
+ it('should track context across updates', () => {
+ class SimpleComponent extends React.Component {
+ static contextTypes = {
+ foo: PropTypes.string,
+ };
+
+ state = {
+ bar: 'bar',
+ };
+
+ render() {
+ return
{`${this.context.foo}:${this.state.bar}`}
;
+ }
+ }
+
+ const shallowRenderer = createRenderer();
+ let result = shallowRenderer.render(
, {
+ foo: 'foo',
+ });
+ expect(result).toEqual(
foo:bar
);
+
+ const instance = shallowRenderer.getMountedInstance();
+ instance.setState({bar: 'baz'});
+
+ result = shallowRenderer.getRenderOutput();
+ expect(result).toEqual(
foo:baz
);
+ });
+
+ it('can fail context when shallowly rendering', () => {
+ spyOn(console, 'error');
+
+ class SimpleComponent extends React.Component {
+ static contextTypes = {
+ name: PropTypes.string.isRequired,
+ };
+
+ render() {
+ return
{this.context.name}
;
+ }
+ }
+
+ const shallowRenderer = createRenderer();
+ shallowRenderer.render(
);
+ expectDev(console.error.calls.count()).toBe(1);
+ expect(
+ console.error.calls.argsFor(0)[0].replace(/\(at .+?:\d+\)/g, '(at **)'),
+ ).toBe(
+ 'Warning: Failed context type: The context `name` is marked as ' +
+ 'required in `SimpleComponent`, but its value is `undefined`.\n' +
+ ' in SimpleComponent (at **)',
+ );
+ });
+
+ it('should warn about propTypes (but only once)', () => {
+ spyOn(console, 'error');
+
+ class SimpleComponent extends React.Component {
+ render() {
+ return React.createElement('div', null, this.props.name);
+ }
+ }
+
+ SimpleComponent.propTypes = {
+ name: PropTypes.string.isRequired,
+ };
+
+ const shallowRenderer = createRenderer();
+ shallowRenderer.render(React.createElement(SimpleComponent, {name: 123}));
+
+ expect(console.error.calls.count()).toBe(1);
+ expect(
+ console.error.calls.argsFor(0)[0].replace(/\(at .+?:\d+\)/g, '(at **)'),
+ ).toBe(
+ 'Warning: Failed prop type: Invalid prop `name` of type `number` ' +
+ 'supplied to `SimpleComponent`, expected `string`.\n' +
+ ' in SimpleComponent',
+ );
+ });
+
+ it('should enable rendering of cloned element', () => {
+ class SimpleComponent extends React.Component {
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ bar: 'bar',
+ };
+ }
+
+ render() {
+ return
{`${this.props.foo}:${this.state.bar}`}
;
+ }
+ }
+
+ const shallowRenderer = createRenderer();
+ let result = shallowRenderer.render(
);
+ expect(result).toEqual(
foo:bar
);
+
+ const instance = shallowRenderer.getMountedInstance();
+ const cloned = React.cloneElement(instance, {foo: 'baz'});
+ result = shallowRenderer.render(cloned);
+ expect(result).toEqual(
baz:bar
);
+ });
+});