import PropTypes from '../../lib/ReactPropTypes'; import ReactTestUtils from "../../lib/ReactTestUtils"; import React from '../../src/May'; import { render, unmountComponentAtNode, findDOMNode } from '../../src/may-dom/MayDom'; import {shallowCompare} from '../../src/PureComponent'; var ReactDOM = { render: render, unmountComponentAtNode: unmountComponentAtNode, findDOMNode: findDOMNode } React.render = render; // import React from "../../dist/ReactANU"; // var ReactDOM = React; // var ReactTestUtils = { // renderIntoDocument: function (element) { // var div = document.createElement("div"); // return React.render(element, div); // } // }; //https://github.com/facebook/react/blob/master/src/isomorphic/children/__tests__/ReactChildren-test.js describe("ReactES6Class", function() { // this.timeout(200000); var container; var freeze = function(expectation) { Object.freeze(expectation); return expectation; }; var Inner; var attachedListener = null; var renderedName = null; beforeEach(() => { container = document.createElement("div"); attachedListener = null; renderedName = null; Inner = class extends React.Component { getName() { return this.props.name; } render() { attachedListener = this.props.onClick; renderedName = this.props.name; return
; } }; }); function test(element, expectedTag, expectedClassName) { var instance = ReactDOM.render(element, container); expect(container.firstChild).not.toBeNull(); expect(container.firstChild.tagName).toBe(expectedTag); expect(container.firstChild.className).toBe(expectedClassName); return instance; } it("preserves the name of the class for use in error messages", () => { class Foo extends React.Component {} expect(Foo.name).toBe("Foo"); }); it("renders a simple stateless component with prop", () => { class Foo extends React.Component { render() { return ; } } test(, "DIV", "foo"); test(, "DIV", "bar"); }); it("renders based on state using initial values in this.props", () => { class Foo extends React.Component { constructor(props) { super(props); this.state = {bar: this.props.initialValue}; } render() { return ; } } test(, "SPAN", "foo"); }); it("renders based on state using props in the constructor", () => { class Foo extends React.Component { constructor(props) { super(props); this.state = {bar: props.initialValue}; } changeState() { this.setState({bar: "bar"}); } render() { if (this.state.bar === "foo") { return
; } return ; } } var instance = test(, "DIV", "foo"); instance.changeState(); test(, "SPAN", "bar"); }); it("renders based on context in the constructor", () => { class Foo extends React.Component { constructor(props, context) { super(props, context); this.state = {tag: context.tag, className: this.context.className}; } render() { var Tag = this.state.tag; return ; } } Foo.contextTypes = { tag: PropTypes.string, className: PropTypes.string, }; class Outer extends React.Component { getChildContext() { return {tag: "span", className: "foo"}; } render() { return ; } } Outer.childContextTypes = { tag: PropTypes.string, className: PropTypes.string, }; test(, "SPAN", "foo"); }); it("renders only once when setting state in componentWillMount", () => { var renderCount = 0; class Foo extends React.Component { constructor(props) { super(props); this.state = {bar: props.initialValue}; } componentWillMount() { this.setState({bar: "bar"}); } render() { renderCount++; return ; } } test(, "SPAN", "bar"); expect(renderCount).toBe(1); }); it("should render with null in the initial state property", () => { class Foo extends React.Component { constructor() { super(); this.state = null; } render() { return ; } } test(, "SPAN", ""); }); it("setState through an event handler", () => { class Foo extends React.Component { constructor(props) { super(props); this.state = {bar: props.initialValue}; } handleClick() { this.setState({bar: "bar"}); } render() { return ( ); } } test(, "DIV", "foo"); attachedListener(); expect(renderedName).toBe("bar"); }); it("should not implicitly bind event handlers", () => { class Foo extends React.Component { constructor(props) { super(props); this.state = {bar: props.initialValue}; } handleClick() { this.setState({bar: "bar"}); } render() { return ; } } test(, "DIV", "foo"); expect(attachedListener).toThrow(); }); it("renders using forceUpdate even when there is no state", () => { class Foo extends React.Component { constructor(props) { super(props); this.mutativeValue = props.initialValue; } handleClick() { this.mutativeValue = "bar"; this.forceUpdate(); } render() { return ( ); } } test(, "DIV", "foo"); attachedListener(); expect(renderedName).toBe("bar"); }); it("will call all the normal life cycle methods", () => { var lifeCycles = []; class Foo extends React.Component { constructor() { super(); this.state = {}; } componentWillMount() { lifeCycles.push("will-mount"); } componentDidMount() { lifeCycles.push("did-mount"); } componentWillReceiveProps(nextProps) { lifeCycles.push("receive-props", nextProps); } shouldComponentUpdate(nextProps, nextState) { lifeCycles.push("should-update", nextProps, nextState); return true; } componentWillUpdate(nextProps, nextState) { lifeCycles.push("will-update", nextProps, nextState); } componentDidUpdate(prevProps, prevState) { lifeCycles.push("did-update", prevProps, prevState); } componentWillUnmount() { lifeCycles.push("will-unmount"); } render() { return ; } } test(, "SPAN", "foo"); expect(lifeCycles).toEqual(["will-mount", "did-mount"]); lifeCycles = []; // reset test(, "SPAN", "bar"); // prettier-ignore expect(lifeCycles).toEqual([ "receive-props", freeze({value: "bar"}), "should-update", freeze({value: "bar"}), {}, "will-update", freeze({value: "bar"}), {}, "did-update", freeze({value: "foo"}), {}, ]); lifeCycles = []; // reset ReactDOM.unmountComponentAtNode(container); expect(lifeCycles).toEqual(["will-unmount"]); }); it("warns when classic properties are defined on the instance, but does not invoke them.", () => { var getDefaultPropsWasCalled = false; var getInitialStateWasCalled = false; class Foo extends React.Component { constructor() { super(); this.contextTypes = {}; this.propTypes = {}; } getInitialState() { getInitialStateWasCalled = true; return {}; } getDefaultProps() { getDefaultPropsWasCalled = true; return {}; } render() { return ; } } test(, "SPAN", "foo"); expect(getInitialStateWasCalled).toBe(false); expect(getDefaultPropsWasCalled).toBe(false); }); it('does not warn about getInitialState() on class components if state is also defined.', () => { spyOn(console, 'error'); class Foo extends React.Component { state = this.getInitialState(); getInitialState() { return {}; } render() { return ; } } test(, 'SPAN', 'foo'); expect(console.error.calls.count()).toBe(0); }); it('should warn when misspelling shouldComponentUpdate', () => { class NamedComponent extends React.Component { componentShouldUpdate() { return false; } render() { return ; } } test(, 'SPAN', 'foo'); }); it('should warn when misspelling componentWillReceiveProps', () => { class NamedComponent extends React.Component { componentWillRecieveProps() { return false; } render() { return ; } } test(, 'SPAN', 'foo'); }); it('supports this.context passed via getChildContext', () => { class Bar extends React.Component { render() { return
; } } Bar.contextTypes = {bar: PropTypes.string}; class Foo extends React.Component { getChildContext() { return {bar: 'bar-through-context'}; } render() { return ; } } Foo.childContextTypes = {bar: PropTypes.string}; test(, 'DIV', 'bar-through-context'); }); it('supports classic refs', () => { class Foo extends React.Component { render() { return ; } } var instance = test(, 'DIV', 'foo'); expect(instance.refs.inner.getName()).toBe('foo'); }); it('supports drilling through to the DOM using findDOMNode', () => { var instance = test(, 'DIV', 'foo'); var node = ReactDOM.findDOMNode(instance); expect(node).toBe(container.firstChild); }); });