import React from "dist/React";
import getTestDocument from "./getTestDocument";
import ReactTestUtils from "lib/ReactTestUtils";
import ReactShallowRenderer from "lib/ReactShallowRenderer";

import ReactDOMServer from "dist/ReactDOMServer";
//https://github.com/facebook/react/blob/master/src/isomorphic/children/__tests__/ReactChildren-test.js
var ReactDOM = window.ReactDOM || React;

describe("ReactComponent", function() {
    this.timeout(200000);

    it("should throw on invalid render targets", () => {
        var container = document.createElement("div");
        // jQuery objects are basically arrays; people often pass them in by mistake
        expect(function() {
            ReactDOM.render(<div />, [container]);
        }).toThrowError(/Target container is not a DOM element./);

        expect(function() {
            ReactDOM.render(<div />, null);
        }).toThrowError(/Target container is not a DOM element./);
    });

    it("should throw when supplying a ref outside of render method", () => {
        var instance = <div ref="badDiv" />;

        instance = ReactTestUtils.renderIntoDocument(instance);
        expect(instance.nodeName.toLowerCase()).toBe("div");
    });

    it("should warn when children are mutated during render", () => {
        function Wrapper(props) {
            props.children[1] = <p key={1} />; // Mutation is illegal
            return <div>{props.children}</div>;
        }

        var instance = ReactTestUtils.renderIntoDocument(
            <Wrapper>
                <span key={0} />
                <span key={1} />
                <span key={2} />
            </Wrapper>
        );
        expect(
            ReactTestUtils.scryRenderedDOMComponentsWithTag(instance, "p").length
        ).toBe(1);
    });

    it("should warn when children are mutated during update", () => {

        class Wrapper extends React.Component {
            componentDidMount() {
                this.props.children[1] = <p key={1} />; // Mutation is illegal
                this.forceUpdate();
            }

            render() {
                return <div>{this.props.children}</div>;
            }
        }

        var instance = ReactTestUtils.renderIntoDocument(
            <Wrapper>
                <span key={0} />
                <span key={1} />
                <span key={2} />
            </Wrapper>
        );
        expect(
            ReactTestUtils.scryRenderedDOMComponentsWithTag(instance, "p").length
        ).toBe(1);
    });

    it('should support refs on owned components', () => {
    var innerObj = {};
    var outerObj = {};

    class Wrapper extends React.Component {
      getObject = () => {
        return this.props.object;
      };

      render() {
        return <div>{this.props.children}</div>;
      }
    }

    class Component extends React.Component {
      render() {
        var inner = <Wrapper object={innerObj} ref="inner" />;
        var outer = <Wrapper object={outerObj} ref="outer">{inner}</Wrapper>;
        return outer;
      }

      componentDidMount() {
        expect(this.refs.inner.getObject()).toEqual(innerObj);
        expect(this.refs.outer.getObject()).toEqual(outerObj);
      }
    }

    ReactTestUtils.renderIntoDocument(<Component />);
  });

  it('should not have refs on unmounted components', () => {
    class Parent extends React.Component {
      render() {
        return <Child><div ref="test" /></Child>;
      }

      componentDidMount() {
        expect(this.refs && this.refs.test).toEqual(undefined);
      }
    }

    class Child extends React.Component {
      render() {
        return <div />;
      }
    }

    ReactTestUtils.renderIntoDocument(<Parent child={<span />} />);
  });

});
