import assert from 'assert'; import _, { forEach } from 'lodash'; import React from 'react'; import { shallow } from 'enzyme'; import { createClass, filterTypes, rejectTypes, createElements, findTypes, addSpecialOmittedProps, } from './component-types'; function isReactComponentClass(componentClass: unknown) { return ( _.isFunction(componentClass) && _.has(componentClass, 'prototype') && !!componentClass.prototype.isReactComponent ); } describe('component-types', () => { describe('createClass', () => { it('should return a React component type.', () => { assert( isReactComponentClass(createClass({})), 'must be a React component' ); }); it('should make child `components` static properties.', () => { const 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.', () => { const panelReducers = { // eslint-disable-next-line @typescript-eslint/no-empty-function onExpand() {}, } as any; const 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.', () => { const panelSelectors = { isValid: () => {}, }; const 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.', () => { const initialState = { foo: 'bar' }; const Panel = createClass({ 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', () => { const defaultProps = { baz: 'qux' }; const Panel = createClass({ getDefaultProps: () => 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', () => { const defaultProps = { name: 'jon' }; const NameBadge = createClass({ getDefaultProps: () => 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.', () => { const 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', () => { it('should filter elements by a single component type', () => { const Option = createClass({}); const elements = [ Many, , Make, , Work, ]; const spanElements = filterTypes(elements, 'span'); assert.equal(3, spanElements.length, 'length must be 3'); assert( React.isValidElement(spanElements[0]), 'must be a valid React element' ); assert.equal( 'Many', shallow(spanElements[0]).text(), 'text must be `Many`' ); assert( React.isValidElement(spanElements[1]), 'must be a valid React element' ); assert.equal( 'Make', shallow(spanElements[1]).text(), 'text must be `Make`' ); assert( 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', () => { const Option = createClass({}); const elements = [ Many, ,
Make
, ,
Work
, ]; const spanElements = filterTypes(elements, ['section', Option]); assert.equal(4, spanElements.length, 'length must be 4'); assert( React.isValidElement(spanElements[0]), 'must be a valid React element' ); assert.equal(Option, spanElements[0].type, 'type must be `Option`'); assert( React.isValidElement(spanElements[1]), 'must be a valid React element' ); assert.equal( 'Make', shallow(spanElements[1]).text(), 'text must be `Make`' ); assert( React.isValidElement(spanElements[2]), 'must be a valid React element' ); assert.equal(Option, spanElements[0].type, 'type must be `Option`'); assert( React.isValidElement(spanElements[3]), 'must be a valid React element' ); assert.equal( 'Work', shallow(spanElements[3]).text(), 'text must be `Work`' ); }); }); describe('rejectTypes', () => { it('should reject elements of a single component type', () => { const Option = createClass({}); const elements = [ Many, , Make, , Work, ]; const nonSpanElements = rejectTypes(elements, 'span'); assert.equal(2, nonSpanElements.length, 'length must be 2'); assert( 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( 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', () => { const Option = createClass({}); const elements = [ Many, ,
Make
, , Work, ]; const remainingElements = rejectTypes(elements, [Option, 'span']); assert.equal(1, remainingElements.length, 'length must be 1'); assert( 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', () => { it('should create elements of the given type from the array', () => { const Option = createClass({}); const elements = createElements(Option, [