lucid-ui
Version:
A UI component library from AppNexus.
340 lines (336 loc) • 15.1 kB
JavaScript
import _isNull from "lodash/isNull";
import _forEach from "lodash/forEach";
import _isEqual from "lodash/isEqual";
import _get from "lodash/get";
import _has from "lodash/has";
import _isFunction from "lodash/isFunction";
import assert from 'assert';
import React from 'react';
import PropTypes from 'prop-types';
import { shallow } from 'enzyme';
import { createClass, filterTypes, rejectTypes, createElements, findTypes, omitProps } from './component-types';
function isReactComponentClass(componentClass) {
return _isFunction(componentClass) && _has(componentClass, 'prototype') && !!componentClass.prototype.isReactComponent;
}
describe('component-types', function () {
describe('createClass', function () {
it('should return a React component type.', function () {
assert(isReactComponentClass(createClass({})), 'must be a React component');
});
it('should make child `components` static properties.', function () {
var Panel = createClass({
components: {
Header: createClass({}),
Footer: createClass({})
}
});
assert(_has(Panel, 'Header'), 'must have `Header` as a static property');
assert(_has(Panel, 'Footer'), 'must have `Footer` as a static property');
});
it('should make `reducers` a static property.', function () {
var panelReducers = {
// eslint-disable-next-line @typescript-eslint/no-empty-function
onExpand: function onExpand() {}
};
var Panel = createClass({
reducers: panelReducers
});
assert(_has(Panel, 'reducers'), 'must have `reducers` as a static property');
assert.equal(_get(Panel, 'reducers'), panelReducers, 'static `reducers` must equal defined reducers');
});
it('should make `selectors` a static property.', function () {
var panelSelectors = {
isValid: function isValid() {}
};
var Panel = createClass({
selectors: panelSelectors
});
assert(_has(Panel, 'selectors'), 'must have `selectors` as a static property');
assert.equal(_get(Panel, 'selectors'), panelSelectors, 'static `selectors` must equal defined selectors');
});
it('should make `initialState` a static property.', function () {
var initialState = {
foo: 'bar'
};
var Panel = createClass({
initialState: initialState
});
assert(_has(Panel, 'initialState'), 'must have `initialState` as a static property');
assert.equal(_get(Panel, 'initialState'), initialState, 'static `initialState` must equal defined initialState');
});
it('should use `getDefaultProps` for default initialState', function () {
var defaultProps = {
baz: 'qux'
};
var Panel = createClass({
getDefaultProps: function getDefaultProps() {
return defaultProps;
}
});
assert(_has(Panel, 'initialState'), 'must have `initialState` as a static property');
assert.deepEqual(_get(Panel, 'initialState'), defaultProps, 'static `initialState` must equal return value of `getDefaultProps`');
});
it('should move `getDefaultProps` to `defaultProps` on the returned item', function () {
var defaultProps = {
name: 'jon'
};
var NameBadge = createClass({
getDefaultProps: function getDefaultProps() {
return defaultProps;
}
});
assert(!_has(NameBadge, 'getDefaultProps'), 'must not have `getDefaultProps` as a static property');
assert.deepEqual(NameBadge.defaultProps, defaultProps, 'static `defaultProps` must equal expected value passed as `getDefaultProps`');
});
it('should make `propName` a static property.', function () {
var Panel = createClass({
propName: ['Panel', 'panel', 'panels']
});
assert(_has(Panel, 'propName'), 'must have `propName` as a static property');
assert(_isEqual(_get(Panel, 'propName'), ['Panel', 'panel', 'panels']), 'static `propName` must equal defined prop names');
});
});
describe('filterTypes', function () {
it('should filter elements by a single component type', function () {
var Option = createClass({});
var elements = [/*#__PURE__*/React.createElement("span", {
key: "1"
}, "Many"), /*#__PURE__*/React.createElement(Option, {
key: "2"
}, "Hands"), /*#__PURE__*/React.createElement("span", {
key: "3"
}, "Make"), /*#__PURE__*/React.createElement(Option, {
key: "4"
}, "Light"), /*#__PURE__*/React.createElement("span", {
key: "5"
}, "Work")];
var spanElements = filterTypes(elements, 'span');
assert.equal(3, spanElements.length, 'length must be 3');
assert( /*#__PURE__*/React.isValidElement(spanElements[0]), 'must be a valid React element');
assert.equal('Many', shallow(spanElements[0]).text(), 'text must be `Many`');
assert( /*#__PURE__*/React.isValidElement(spanElements[1]), 'must be a valid React element');
assert.equal('Make', shallow(spanElements[1]).text(), 'text must be `Make`');
assert( /*#__PURE__*/React.isValidElement(spanElements[2]), 'must be a valid React element');
assert.equal('Work', shallow(spanElements[2]).text(), 'text must be `Work`');
});
it('should filter elements by many component types', function () {
var Option = createClass({});
var elements = [/*#__PURE__*/React.createElement("span", {
key: "1"
}, "Many"), /*#__PURE__*/React.createElement(Option, {
key: "2"
}, "Hands"), /*#__PURE__*/React.createElement("section", {
key: "3"
}, "Make"), /*#__PURE__*/React.createElement(Option, {
key: "4"
}, "Light"), /*#__PURE__*/React.createElement("section", {
key: "5"
}, "Work")];
var spanElements = filterTypes(elements, ['section', Option]);
assert.equal(4, spanElements.length, 'length must be 4');
assert( /*#__PURE__*/React.isValidElement(spanElements[0]), 'must be a valid React element');
assert.equal(Option, spanElements[0].type, 'type must be `Option`');
assert( /*#__PURE__*/React.isValidElement(spanElements[1]), 'must be a valid React element');
assert.equal('Make', shallow(spanElements[1]).text(), 'text must be `Make`');
assert( /*#__PURE__*/React.isValidElement(spanElements[2]), 'must be a valid React element');
assert.equal(Option, spanElements[0].type, 'type must be `Option`');
assert( /*#__PURE__*/React.isValidElement(spanElements[3]), 'must be a valid React element');
assert.equal('Work', shallow(spanElements[3]).text(), 'text must be `Work`');
});
});
describe('rejectTypes', function () {
it('should reject elements of a single component type', function () {
var Option = createClass({});
var elements = [/*#__PURE__*/React.createElement("span", {
key: "1"
}, "Many"), /*#__PURE__*/React.createElement(Option, {
key: "2"
}, "Hands"), /*#__PURE__*/React.createElement("span", {
key: "3"
}, "Make"), /*#__PURE__*/React.createElement(Option, {
key: "4"
}, "Light"), /*#__PURE__*/React.createElement("span", {
key: "5"
}, "Work")];
var nonSpanElements = rejectTypes(elements, 'span');
assert.equal(2, nonSpanElements.length, 'length must be 2');
assert( /*#__PURE__*/React.isValidElement(nonSpanElements[0]), 'must be a valid React element');
assert.equal(Option, nonSpanElements[0].type, 'type must be `Option`');
assert.equal('Hands', nonSpanElements[0].props.children, 'first element must have the string `Hands`');
assert( /*#__PURE__*/React.isValidElement(nonSpanElements[1]), 'must be a valid React element');
assert.equal(Option, nonSpanElements[1].type, 'type must be `Option`');
assert.equal('Light', nonSpanElements[1].props.children, 'second element must have the string `Light`');
});
it('should reject elements of many component types', function () {
var Option = createClass({});
var elements = [/*#__PURE__*/React.createElement("span", {
key: "1"
}, "Many"), /*#__PURE__*/React.createElement(Option, {
key: "2"
}, "Hands"), /*#__PURE__*/React.createElement("section", {
key: "3"
}, "Make"), /*#__PURE__*/React.createElement(Option, {
key: "4"
}, "Light"), /*#__PURE__*/React.createElement("span", {
key: "5"
}, "Work")];
var remainingElements = rejectTypes(elements, [Option, 'span']);
assert.equal(1, remainingElements.length, 'length must be 1');
assert( /*#__PURE__*/React.isValidElement(remainingElements[0]), 'must be a valid React element');
assert.equal('section', shallow(remainingElements[0]).type(), 'type must be `section`');
assert.equal('Make', shallow(remainingElements[0]).text(), 'element must have the string `Make`');
});
});
describe('createElements', function () {
it('should create elements of the given type from the array', function () {
var Option = createClass({});
var elements = createElements(Option, [/*#__PURE__*/React.createElement(Option, {
key: "1"
}), /*#__PURE__*/React.createElement("button", {
key: "2"
}), 'red', null, {
isDisabled: true
}]);
assert.equal(5, elements.length, 'length must be 5');
_forEach(elements, function (element) {
assert.equal(Option, element.type, 'type must be Option');
});
assert.equal('button', elements[1].props.children.type, 'element must be a button');
assert.equal('red', elements[2].props.children, 'element children must be `red`');
assert(_isNull(elements[3].props.children), 'must pass null values through');
assert(_isEqual({
isDisabled: true
}, elements[4].props), 'element props must match');
});
});
describe('findTypes', function () {
it('should find all elements of the same type from children', function (done) {
var Option = createClass({
propName: 'option'
});
var Selector = createClass({
render: function render() {
var optionElements = findTypes(this.props, Option);
assert.equal(2, optionElements.length, 'length must be 2');
assert.equal(true, _get(optionElements[0].props, 'isDisabled'), 'element must have prop `isDisabled`');
assert.equal('Select red', _get(optionElements[1].props, 'title'), 'element must have prop `title`');
done();
}
});
shallow( /*#__PURE__*/React.createElement(Selector, null, /*#__PURE__*/React.createElement("button", null), /*#__PURE__*/React.createElement(Option, {
isDisabled: true
}), /*#__PURE__*/React.createElement("button", null), /*#__PURE__*/React.createElement(Option, {
title: "Select red"
}, "Red"), /*#__PURE__*/React.createElement("button", null)));
});
it('should find all elements of the same type from props if type has `propName` defined', function (done) {
var Option = createClass({
propName: ['option', 'options']
});
var Selector = createClass({
render: function render() {
var optionElements = findTypes(this.props, Option);
assert.equal(3, optionElements.length, 'length must be 3');
assert.equal('red', _get(optionElements[0].props, 'children'), 'element children must match prop value');
assert(_isEqual({
children: 'green',
isDisabled: true
}, optionElements[1].props), 'element props must match props');
assert.equal('blue', _get(optionElements[2].props, 'children'), 'element children must match prop value');
done();
}
});
shallow( /*#__PURE__*/React.createElement(Selector, {
option: "red",
options: [{
children: 'green',
isDisabled: true
}, 'blue']
}));
});
it('should find all elements of the same type from props and children', function (done) {
var Option = createClass({
propName: ['option', 'options']
});
var Selector = createClass({
render: function render() {
var optionElements = findTypes(this.props, Option);
assert.equal(5, optionElements.length, 'length must be 3');
assert.equal('red', _get(optionElements[0].props, 'children'), 'element children must match prop value');
assert(_isEqual({
children: 'green',
isDisabled: true
}, optionElements[1].props), 'element props must match props');
assert.equal('blue', _get(optionElements[2].props, 'children'), 'element children must match prop value');
assert.equal(true, _get(optionElements[3].props, 'isDisabled'), 'element must have prop `isDisabled`');
assert.equal('Select red', _get(optionElements[4].props, 'title'), 'element must have prop `title`');
done();
}
});
shallow( /*#__PURE__*/React.createElement(Selector, {
option: "red",
options: [{
children: 'green',
isDisabled: true
}, 'blue']
}, /*#__PURE__*/React.createElement("button", null), /*#__PURE__*/React.createElement(Option, {
isDisabled: true
}), /*#__PURE__*/React.createElement("button", null), /*#__PURE__*/React.createElement(Option, {
title: "Select red"
}, "Red"), /*#__PURE__*/React.createElement("button", null)));
});
});
describe('omitProps', function () {
var Button = createClass({
propTypes: {
className: PropTypes.any,
isActive: PropTypes.any,
isDisabled: PropTypes.any,
kind: PropTypes.any,
size: PropTypes.any
}
});
it('should omit props which are defined in propTypes', function () {
var props = omitProps({
className: 'test-button',
text: 'Click Me',
isActive: true,
isPrimary: true,
size: 'normal'
}, Button);
assert.deepEqual(props, {
text: 'Click Me',
isPrimary: true
}, 'must omit props defined in propTypes');
});
it('should omit `callbackId` from props by default', function () {
var props = omitProps({
className: 'test-button',
text: 'Click Me',
isActive: true,
isPrimary: true,
size: 'normal',
callbackId: 'cant find me'
}, Button);
assert.deepEqual(props, {
text: 'Click Me',
isPrimary: true
}, 'must omit props defined in propTypes');
});
it('should not omit `callbackId` from props when specified', function () {
var props = omitProps({
className: 'test-button',
text: 'Click Me',
isActive: true,
isPrimary: true,
size: 'normal',
callbackId: 'can find me'
}, Button, [], false);
assert.deepEqual(props, {
text: 'Click Me',
isPrimary: true,
callbackId: 'can find me'
}, 'must omit props defined in propTypes');
});
});
});