import { expect } from 'chai'; import React from 'react'; import { elementType } from '..'; import callValidator from './_callValidator'; function SFC() {} class Component extends React.Component {} // eslint-disable-line react/prefer-stateless-function describe('elementType', () => { it('returns a function', () => { expect(typeof elementType('')).to.equal('function'); }); it('throws on an invalid type', () => { expect(() => elementType()).to.throw(TypeError); expect(() => elementType(null)).to.throw(TypeError); expect(() => elementType(undefined)).to.throw(TypeError); expect(() => elementType(42)).to.throw(TypeError); expect(() => elementType(true)).to.throw(TypeError); expect(() => elementType([])).to.throw(TypeError); expect(() => elementType({})).to.throw(TypeError); }); function assertPasses(validator, element, propName, componentName) { expect(callValidator(validator, element, propName, componentName)).to.equal(null); } function assertFails(validator, element, propName, componentName) { expect(callValidator(validator, element, propName, componentName)).to.be.instanceOf(Error); } describe('a single child', () => { it('passes with a DOM element', () => assertPasses( elementType('span'), (
), 'children', 'span!', )); it('passes with an SFC', () => assertPasses( elementType(SFC), (
), 'children', 'SFC!', )); it('passes with a Component', () => assertPasses( elementType(Component), (
), 'children', 'Component!', )); it('fails expecting a DOM element', () => assertFails( elementType('span'), (
No way.
), 'children', 'span!', )); it('fails expecting an SFC', () => assertFails( elementType(SFC), (
No way.
), 'children', 'SFC!', )); it('fails expecting a Component', () => assertFails( elementType(Component), (
No way.
), 'children', 'Component!', )); }); describe('a prop', () => { it('passes expecting a DOM element', () => assertPasses( elementType('span'), (
} />), 'a', 'span!', )); it('passes expecting an SFC', () => assertPasses( elementType(SFC), (
} />), 'a', 'SFC!', )); it('passes expecting a Component', () => assertPasses( elementType(Component), (
} />), 'a', 'Component!', )); it('fails expecting a DOM element', () => assertFails( elementType('span'), (
No way.} />), 'a', 'span!', )); it('fails expecting an SFC', () => assertFails( elementType(SFC), (
No way.} />), 'a', 'SFC!', )); it('fails expecting a Component', () => assertFails( elementType(Component), (
No way.} />), 'a', 'Component!', )); }); describe('*', () => { it('allows a DOM element as a child', () => assertPasses( elementType('*'), (
), 'children', 'span!', )); it('allows a DOM element as a prop', () => assertPasses( elementType('*'), (
} />), 'a', 'span!', )); it('allows a Component as a child', () => assertPasses( elementType('*'), (
), 'children', 'Component!', )); it('allows a Component as a prop', () => assertPasses( elementType('*'), (
} />), 'a', 'Component!', )); it('allows an SFC as a child', () => assertPasses( elementType('*'), (
), 'children', 'SFC!', )); it('allows an SFC as a prop', () => assertPasses( elementType('*'), (
} />), 'a', 'SFC!', )); describe('with a nonelement child', () => { it('fails with a string', () => assertFails( elementType('*'), (
foo
), 'children', 'string', )); it('fails with a number', () => assertFails( elementType('*'), (
{3}
), 'children', 'number', )); it('fails with true', () => assertFails( elementType('*'), (
{true}
), 'children', 'true', )); it('fails with false', () => assertFails( elementType('*'), (
{false}
), 'children', 'false', )); it('fails with an array', () => assertFails( elementType('*'), (
{[]}
), 'children', 'array', )); }); describe('with a nonelement prop', () => { it('passes with undefined', () => assertPasses( elementType('*'), (
), 'a', 'undefined', )); it('fails with undefined when required', () => assertFails( elementType('*').isRequired, (
), 'a', 'undefined required', )); it('passes with null', () => { assertPasses( elementType('*'), (
), 'a', 'null *', ); assertPasses( elementType('span'), (
), 'a', 'null span', ); }); it('fails with null when required', () => { assertFails( elementType('*').isRequired, (
), 'a', 'null required *', ); assertFails( elementType('span').isRequired, (
), 'a', 'null required span', ); }); it('fails with a string', () => assertFails( elementType('*'), (
), 'a', 'string', )); it('fails with a number', () => assertFails( elementType('*'), (
), 'a', 'number', )); it('fails with true', () => assertFails( elementType('*'), (
), 'a', 'true', )); it('fails with false', () => assertFails( elementType('*'), (
), 'a', 'false', )); it('fails with an array', () => assertFails( elementType('*'), (
), 'a', 'array', )); }); (React.forwardRef ? describe : describe.skip)('React.forwardRef', () => { const MyForwardRef = React.forwardRef && React.forwardRef((props, ref) =>
); it('passes with * and a forwardRef', () => assertPasses( elementType('*'), (
} />), 'a', '* + forwardRef', )); it('passes with matching forwardRef', () => assertPasses( elementType(MyForwardRef), (
} />), 'a', 'forwardRef + forwardRef', )); it('fails with a string and a forwardRef', () => assertFails( elementType('div'), (
} />), 'a', 'div + forwardRef', )); }); (React.createContext ? describe : describe.skip)('React.createContext', () => { const { Provider, Consumer } = React.createContext ? React.createContext('test') : {}; it('passes with * and a Provider', () => assertPasses( elementType('*'), (
} />), 'a', '* + Provider', )); it('passes with * and a Consumer', () => assertPasses( elementType('*'), (
} />), 'a', '* + Consumer', )); it('passes with matching Provider', () => assertPasses( elementType(Provider), (
} />), 'a', 'Provider + Provider', )); it('passes with matching Consumer', () => assertPasses( elementType(Consumer), (
} />), 'a', 'Consumer + Consumer', )); it('fails with a string and a Provider', () => assertFails( elementType('div'), (
} />), 'a', 'div + Provider', )); it('fails with a string and a Consumer', () => assertFails( elementType('div'), (
} />), 'a', 'div + Consumer', )); }); }); });