/*
 * A note about these tests:
 *
 * These tests are specifically only testing that the correct calls are being made
  * to unexpected-htmllike, and that the output is correctly returned.
  * They also test the integration with the unexpected-htmllike-rendered-react-adapter
  * There are many, many more cases for specific diffing cases in the tests for
  * `unexpected-htmllike`
 */

'use strict';

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();

var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var EmulateDom = require('../testHelpers/emulateDom');

var Unexpected = require('unexpected');
var UnexpectedReact = require('../unexpected-react');

var React = require('react/addons');

var TestUtils = React.addons.TestUtils;

var expect = Unexpected.clone().use(UnexpectedReact);

expect.output.preferredWidth = 80;

var CustomComp = (function (_React$Component) {
    _inherits(CustomComp, _React$Component);

    function CustomComp() {
        _classCallCheck(this, CustomComp);

        _get(Object.getPrototypeOf(CustomComp.prototype), 'constructor', this).call(this);
        this.state = {
            clickCount: 0
        };
        this.onClick = this.onClick.bind(this);
    }

    _createClass(CustomComp, [{
        key: 'onClick',
        value: function onClick(event) {
            event.preventDefault(); // Used to check that we get the event properly
            this.setState({
                clickCount: this.state.clickCount + 1
            });
        }
    }, {
        key: 'render',
        value: function render() {
            var children = null;
            if (this.props.childCount) {
                children = [];
                for (var i = 1; i <= this.props.childCount; ++i) {
                    children.push(React.createElement(
                        'span',
                        { key: i, className: '' + i },
                        null,
                        i
                    ));
                }
            }
            // If onClick was passed, add it as a prop, otherwise, leave it undefined
            var extraProps = {};
            if (this.props.useEvents) {
                extraProps.onClick = this.onClick;
                extraProps['data-click-count'] = this.state.clickCount;
            }

            return React.createElement(
                'div',
                _extends({
                    className: this.props.className
                }, extraProps),
                children
            );
        }
    }]);

    return CustomComp;
})(React.Component);

var WrapperComp = (function (_React$Component2) {
    _inherits(WrapperComp, _React$Component2);

    function WrapperComp() {
        _classCallCheck(this, WrapperComp);

        _get(Object.getPrototypeOf(WrapperComp.prototype), 'constructor', this).apply(this, arguments);
    }

    _createClass(WrapperComp, [{
        key: 'render',
        value: function render() {
            return React.createElement(CustomComp, this.props);
        }
    }]);

    return WrapperComp;
})(React.Component);

var MyDiv = (function (_React$Component3) {
    _inherits(MyDiv, _React$Component3);

    function MyDiv() {
        _classCallCheck(this, MyDiv);

        _get(Object.getPrototypeOf(MyDiv.prototype), 'constructor', this).apply(this, arguments);
    }

    // Dummy assertion for testing async expect.it

    _createClass(MyDiv, [{
        key: 'render',
        value: function render() {
            return React.createElement(
                'div',
                this.props,
                this.props.children
            );
        }
    }]);

    return MyDiv;
})(React.Component);

expect.addAssertion('<string> to eventually have value <string>', function (expect, subject, value) {

    return expect.promise(function (resolve, reject) {

        setTimeout(function () {
            if (subject === value) {
                resolve();
            } else {
                try {
                    expect.fail('Failed');
                } catch (e) {
                    reject(e); // Return the UnexpectedError object
                }
            }
        }, 10);
    });
});

describe('unexpected-react (deep rendering)', function () {

    beforeEach(function () {
        UnexpectedReact.clearAll();
    });

    describe('identify', function () {

        it('identifies a rendered component', function () {

            var component = TestUtils.renderIntoDocument(React.createElement('div', { className: 'foo' }));
            expect(component, 'to be a', 'RenderedReactElement');
        });
    });

    describe('ReactModule', function () {
        it('identifies React correctly', function () {

            expect(React, 'to be a', 'ReactModule');
        });

        it('determines that the global hook has been installed', function () {

            expect(React, 'to have been injected');
        });
    });

    describe('inspect', function () {

        it('inspects a rendered native element', function () {

            var component = TestUtils.renderIntoDocument(React.createElement(MyDiv, { className: 'foo' }));
            expect(expect.inspect(component).toString(), 'to equal', '<MyDiv className="foo"><div className="foo" /></MyDiv>');
        });

        it('inspects a rendered native element with a string child', function () {

            var component = TestUtils.renderIntoDocument(React.createElement(
                MyDiv,
                { className: 'foo' },
                'content'
            ));
            expect(expect.inspect(component).toString(), 'to equal', '<MyDiv className="foo"><div className="foo">content</div></MyDiv>');
        });

        it('inspects a rendered native element with a numeric child', function () {

            var component = TestUtils.renderIntoDocument(React.createElement(
                MyDiv,
                { className: 'foo' },
                42
            ));
            expect(expect.inspect(component).toString(), 'to equal', '<MyDiv className="foo"><div className="foo">42</div></MyDiv>');
        });

        it('inspects a rendered element with children', function () {

            var component = TestUtils.renderIntoDocument(React.createElement(
                MyDiv,
                { className: 'foo' },
                React.createElement('span', { className: 'child1' })
            ));
            expect(expect.inspect(component).toString(), 'to equal', '<MyDiv className="foo"><div className="foo"><span className="child1" /></div></MyDiv>');
        });

        it('inspects a rendered native element with children and content', function () {

            var component = TestUtils.renderIntoDocument(React.createElement(
                MyDiv,
                { className: 'foo' },
                React.createElement(
                    'span',
                    { className: 'child1' },
                    'child content 1'
                ),
                React.createElement(
                    'span',
                    { className: 'child2' },
                    'child content 2'
                )
            ));
            expect(expect.inspect(component).toString(), 'to equal', '<MyDiv className="foo">\n' + '  <div className="foo">\n' + '    <span className="child1">child content 1</span>\n' + '    <span className="child2">child content 2</span>\n' + '  </div>\n' + '</MyDiv>');
        });

        it('inspects a rendered custom component', function () {

            var component = TestUtils.renderIntoDocument(React.createElement(CustomComp, { className: 'bar' }));
            expect(expect.inspect(component).toString(), 'to equal', '<CustomComp className="bar"><div className="bar" /></CustomComp>');
        });

        it('inspects a rendered custom component with a child custom component element', function () {

            var component = TestUtils.renderIntoDocument(React.createElement(WrapperComp, { className: 'bar' }));
            expect(expect.inspect(component).toString(), 'to equal', '<WrapperComp className="bar">\n' + '  <CustomComp className="bar"><div className="bar" /></CustomComp>\n' + '</WrapperComp>');
        });
    });

    describe('to have rendered', function () {

        it('matches a rendered simple component', function () {

            var component = TestUtils.renderIntoDocument(React.createElement(CustomComp, { className: 'bar' }));
            return expect(component, 'to have rendered', React.createElement(
                CustomComp,
                { className: 'bar' },
                React.createElement('div', { className: 'bar' })
            ));
        });

        it('matches a rendered deeper component', function () {

            var component = TestUtils.renderIntoDocument(React.createElement(WrapperComp, { className: 'bar' }));
            return expect(component, 'to have rendered', React.createElement(
                WrapperComp,
                { className: 'bar' },
                React.createElement(
                    CustomComp,
                    { className: 'bar' },
                    React.createElement('div', { className: 'bar' })
                )
            ));
        });

        it('matches an a component with many children', function () {

            var component = TestUtils.renderIntoDocument(React.createElement(WrapperComp, { className: 'bar', childCount: 3 }));
            return expect(component, 'to have rendered', React.createElement(
                WrapperComp,
                { className: 'bar', childCount: 3 },
                React.createElement(
                    'div',
                    { className: 'bar' },
                    React.createElement(
                        'span',
                        { className: '1' },
                        '1'
                    ),
                    React.createElement(
                        'span',
                        { className: '2' },
                        '2'
                    ),
                    React.createElement(
                        'span',
                        { className: '3' },
                        '3'
                    )
                )
            ));
        });

        it('identifies a missing class', function () {

            var component = TestUtils.renderIntoDocument(React.createElement(CustomComp, { className: 'bar foo' }));

            return expect(function () {
                return expect(component, 'to have rendered', React.createElement(CustomComp, { className: 'blah foo bar' }));
            }, 'to error', 'expected <CustomComp className="bar foo"><div className="bar foo" /></CustomComp>\n' + 'to have rendered <CustomComp className="blah foo bar" />\n' + '\n' + '<CustomComp className="bar foo" // missing class \'blah\'\n' + '>\n' + '  <div className="bar foo" />\n' + '</CustomComp>');
        });

        it('identifies a wrapper', function () {
            var component = TestUtils.renderIntoDocument(React.createElement(WrapperComp, { className: 'bar', childCount: 3 }));
            return expect(component, 'to have rendered', React.createElement(
                WrapperComp,
                { className: 'bar', childCount: 3 },
                React.createElement(
                    'span',
                    { className: '1' },
                    '1'
                ),
                React.createElement(
                    'span',
                    { className: '2' },
                    '2'
                ),
                React.createElement(
                    'span',
                    { className: '3' },
                    '3'
                )
            ));
        });

        it('updates on change', function () {

            var component = TestUtils.renderIntoDocument(React.createElement(CustomComp, { className: 'bar', useEvents: true }));
            TestUtils.Simulate.click(React.findDOMNode(component));

            return expect(component, 'to have rendered', React.createElement('div', { className: 'bar', 'data-click-count': 1 }));
        });

        it('matches an expect.it assertion on a prop', function () {

            var component = TestUtils.renderIntoDocument(React.createElement(CustomComp, { className: 'bar' }));

            return expect(component, 'to have rendered', React.createElement('div', { className: expect.it('to match', /bar/) }));
        });

        it('highlights a difference with an expect.it assertion on a prop', function () {

            var component = TestUtils.renderIntoDocument(React.createElement(CustomComp, { className: 'bar' }));

            return expect(function () {
                return expect(component, 'to have rendered', React.createElement('div', { className: expect.it('to match', /foo/) }));
            }, 'to throw', 'expected <CustomComp className="bar"><div className="bar" /></CustomComp>\n' + 'to have rendered <div className={expect.it(\'to match\', /foo/)} />\n' + '\n' + '<CustomComp className="bar">\n' + '  <div className="bar" // expected \'bar\' to match /foo/\n' + '  />\n' + '</CustomComp>');
        });

        it('highlights a difference with an expect.it assertion on content', function () {

            var component = TestUtils.renderIntoDocument(React.createElement(CustomComp, { className: 'bar', childCount: 1 }));
            return expect(function () {
                return expect(component, 'to have rendered', React.createElement(
                    'div',
                    null,
                    React.createElement(
                        'span',
                        null,
                        expect.it('to match', /[a-z]/)
                    )
                ));
            }, 'to error', 'expected\n' + '<CustomComp className="bar" childCount={1}>\n' + '  <div className="bar"><span className="1">1</span></div>\n' + '</CustomComp>\n' + 'to have rendered <div><span>{expect.it(\'to match\', /[a-z]/)}</span></div>\n' + '\n' + '<CustomComp className="bar" childCount={1}>\n' + '  <div className="bar">\n' + '    <span className="1">\n' + "      1 // expected '1' to match /[a-z]/\n" + '    </span>\n' + '  </div>\n' + '</CustomComp>');
        });
    });

    describe('contains', function () {

        it('finds a deep nested component', function () {

            var component = TestUtils.renderIntoDocument(React.createElement(CustomComp, { className: 'bar', childCount: 3 }));
            return expect(component, 'to contain', React.createElement(
                CustomComp,
                null,
                React.createElement(
                    'div',
                    null,
                    React.createElement(
                        'span',
                        null,
                        '2'
                    )
                )
            ));
        });

        it('throws an error with the best match when the element is not found', function () {

            var component = TestUtils.renderIntoDocument(React.createElement(CustomComp, { className: 'bar', childCount: 3 }));
            return expect(function () {
                return expect(component, 'to contain', React.createElement(
                    'span',
                    { className: 'foo' },
                    '2'
                ));
            }, 'to throw', 'expected\n' + '<CustomComp className="bar" childCount={3}>\n' + '  <div className="bar">\n' + '    <span className="1">1</span>\n' + '    <span className="2">2</span>\n' + '    <span className="3">3</span>\n' + '  </div>\n' + '</CustomComp>\n' + 'to contain <span className="foo">2</span>\n' + '\n' + 'the best match was\n' + '<span className="2" // missing class \'foo\'\n' + '>\n' + '  2\n' + '</span>');
        });

        it('throws an error for `not to contain` with the match when the element is found ', function () {

            var component = TestUtils.renderIntoDocument(React.createElement(CustomComp, { className: 'bar', childCount: 3 }));
            return expect(function () {
                return expect(component, 'not to contain', React.createElement(
                    'span',
                    { className: '2' },
                    '2'
                ));
            }, 'to throw', 'expected\n' + '<CustomComp className="bar" childCount={3}>\n' + '  <div className="bar">\n' + '    <span className="1">1</span>\n' + '    <span className="2">2</span>\n' + '    <span className="3">3</span>\n' + '  </div>\n' + '</CustomComp>\n' + 'not to contain <span className="2">2</span>\n' + '\n' + 'but found the following match\n' + '<span className="2">2</span>');
        });

        it('returns a rejected promise with the best match when the element is not found with an async expect.it', function () {

            var component = TestUtils.renderIntoDocument(React.createElement(CustomComp, { className: 'bar', childCount: 3 }));
            return expect(expect(component, 'to contain', React.createElement(
                'span',
                { className: expect.it('to eventually have value', 'foo') },
                '2'
            )), 'to be rejected with', 'expected\n' + '<CustomComp className="bar" childCount={3}>\n' + '  <div className="bar">\n' + '    <span className="1">1</span>\n' + '    <span className="2">2</span>\n' + '    <span className="3">3</span>\n' + '  </div>\n' + '</CustomComp>\n' + 'to contain <span className={expect.it(\'to eventually have value\', \'foo\')}>2</span>\n' + '\n' + 'the best match was\n' + '<span className="2" // expected \'2\' to eventually have value \'foo\'\n' + '>\n' + '  2\n' + '</span>');
        });
    });
});
//# sourceMappingURL=unexpected-react-deep.spec.js.map