function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }

/*
Copyright (c) 2018 Uber Technologies, Inc.

This source code is licensed under the MIT license found in the
LICENSE file in the root directory of this source tree.
*/
import * as React from 'react';
import { getOverride, getOverrideProps, toObjectOverride, mergeOverrides, mergeOverride, mergeStyleOverrides, getOverrides } from '../overrides.js';

function getMockComponent() {
  var mock = function mock() {
    return null;
  };

  return mock;
}

describe('Helpers - Overrides', function () {
  test('getOverride', function () {
    var CustomComponent = getMockComponent();
    expect(getOverride(null)).toEqual(null);
    expect(getOverride(CustomComponent)).toEqual(CustomComponent);
    expect(getOverride({
      component: CustomComponent
    })).toEqual(CustomComponent);
  });
  test('getOverrideProps', function () {
    var CustomComponent = getMockComponent();
    var override = {
      props: {
        propName: 'propsValue'
      },
      style: {
        color: 'blue'
      }
    };
    expect(getOverrideProps(null)).toMatchSnapshot('returns empty object when no overrides');
    expect(getOverrideProps(CustomComponent)).toMatchSnapshot('returns empty object when override is a component');
    expect(getOverrideProps(override)).toMatchSnapshot('returns correct object when override has props and styles');
  });
  test('toObjectOverride', function () {
    var CustomComponent = getMockComponent(); // $FlowFixMe - Calling toObjectOverride with no args

    expect(toObjectOverride()).toEqual({}); // $FlowFixMe - Calling toObjectOverride with null

    expect(toObjectOverride(null)).toEqual({});
    expect(toObjectOverride(CustomComponent)).toEqual({
      component: CustomComponent
    });
    expect(toObjectOverride({
      component: CustomComponent,
      style: {
        width: '300px'
      }
    })).toEqual({
      component: CustomComponent,
      style: {
        width: '300px'
      }
    });
  });
  test('mergeOverrides', function () {
    var CustomRoot = getMockComponent();
    var CustomFoo = getMockComponent();
    var CustomBar = getMockComponent();
    var overrides1 = {
      Root: CustomRoot
    };
    var overrides2 = {
      Root: {
        component: CustomFoo
      },
      Bar: CustomBar
    };
    expect(mergeOverrides(overrides1)).toEqual({
      Root: {
        component: CustomRoot
      }
    });
    expect(mergeOverrides(overrides1, overrides2)).toEqual({
      Root: {
        component: CustomFoo
      },
      Bar: {
        component: CustomBar
      }
    });
  });
  test('mergeOverride can merge props and style objects', function () {
    expect(mergeOverride({
      props: {
        foo: true,
        bar: false
      },
      style: {
        color: 'red',
        textTransform: 'uppercase'
      }
    }, {
      props: {
        foo: false
      },
      style: {
        color: 'blue'
      }
    })).toEqual({
      props: {
        foo: false,
        bar: false
      },
      style: {
        color: 'blue',
        textTransform: 'uppercase'
      }
    });
  });
  test('mergeOverride doesnt unnecessarily create new objects', function () {
    var override1 = {
      props: {
        foo: true
      }
    };
    var override2 = {
      style: {
        color: 'red'
      }
    };
    var result = mergeOverride(override1, override2);
    expect(result.props).toBe(override1.props);
    expect(result.style).toBe(override2.style);
  });
  test('mergeOverride can compose style functions', function () {
    var override1 = {
      style: function style() {
        return {
          color: 'red',
          textTransform: 'uppercase'
        };
      }
    };
    var override2 = {
      style: function style() {
        return {
          color: 'blue'
        };
      }
    };
    var result = mergeOverride(override1, override2);
    expect(_typeof(result.style)).toBe('function'); // $FlowFixMe style should be a function here

    expect(result.style()).toEqual({
      color: 'blue',
      textTransform: 'uppercase'
    });
  });
  test('mergeStyleOverrides', function () {
    var overrideObject1 = {
      color: 'red',
      textTransform: 'uppercase'
    };
    var overrideObject2 = {
      color: 'blue'
    };

    var overrideFunction1 = function overrideFunction1() {
      return overrideObject1;
    };

    var overrideFunction2 = function overrideFunction2() {
      return overrideObject2;
    };

    var expectedResult = {
      color: 'blue',
      textTransform: 'uppercase'
    };
    var result1 = mergeStyleOverrides(overrideObject1, overrideObject2);
    var result2 = mergeStyleOverrides(overrideObject1, overrideFunction2);
    var result3 = mergeStyleOverrides(overrideFunction1, overrideObject2);
    var result4 = mergeStyleOverrides(overrideFunction1, overrideFunction2);
    expect(_typeof(result1)).toBe('object');
    expect(result1).toEqual(expectedResult);
    expect(_typeof(result2)).toBe('function'); // $FlowFixMe result should be a function here

    expect(result2()).toEqual(expectedResult);
    expect(_typeof(result3)).toBe('function'); // $FlowFixMe result should be a function here

    expect(result3()).toEqual(expectedResult);
    expect(_typeof(result4)).toBe('function'); // $FlowFixMe result should be a function here

    expect(result4()).toEqual(expectedResult);
  });
  test('getOverrides', function () {
    var DefaultComponent = getMockComponent();
    var OverrideComponent = getMockComponent();
    expect(getOverrides(null, DefaultComponent)).toEqual([DefaultComponent, {}]);
    expect(getOverrides(OverrideComponent, DefaultComponent)).toEqual([OverrideComponent, {}]);
    expect(getOverrides({
      component: OverrideComponent,
      props: {
        custom: 'prop'
      },
      style: {
        cursor: 'pointer'
      }
    }, DefaultComponent)).toEqual([OverrideComponent, {
      custom: 'prop',
      $style: {
        cursor: 'pointer'
      }
    }]);
  });
});