import * as fc from 'fast-check' import * as Enzyme from 'enzyme' import * as Axe from 'jest-axe' import * as React from 'react' import TextInput from './TextInput' import stringify from '../../services/stringify' it('should exist', () => { expect(TextInput).toBeDefined() }) it('should be a component', () => { expect(TextInput).toBeComponent() }) it('should render without crashing given required props', () => { expect(() => ).not.toThrow() }) it('should render a base element to put interactive elements on', () => { const wrapper = Enzyme.shallow() expect(wrapper.find('label')).toHaveLength(1) }) it('should render an indicator as additional description for the content', () => { fc.assert( fc.property(fc.string(1, 20), (indicator) => { const wrapper = Enzyme.shallow() expect(wrapper.find('div').childAt(2)).toHaveText(indicator) }), ) }) it('should render a hint for describing valid input values', () => { fc.assert( fc.property(fc.anything(), (label) => { const wrapper = Enzyme.shallow() const renderedLabel = stringify(label) if (renderedLabel.length > 0) { expect(wrapper.find('div').children()).toHaveLength(4) expect(wrapper.find('div').childAt(3)).toHaveText(`(${renderedLabel})`) } else { expect(wrapper.find('div').children()).toHaveLength(2) } }), ) }) it('should render a padding on the hint element when an indicator is present', () => { const wrapper = Enzyme.shallow() expect(wrapper.find('div').childAt(3)).not.toHaveStyle('padding', '1rem') }) it('should render as half-opaque when disabled', () => { const wrapper = Enzyme.shallow() expect(wrapper.find('div')).toHaveStyle('opacity', 0.5) }) describe.each` multiline | inputWidth | tag ${false} | ${'100%'} | ${'input'} ${true} | ${undefined} | ${'textarea'} `('on multiline (multiline=$multiline)', ({ tag: rawTag, multiline: rawMultiline, inputWidth: rawInputWidth }) => { const tag = rawTag as string const multiline = rawMultiline as boolean const inputWidth = rawInputWidth as string it('should render an element to input text on', () => { const wrapper = Enzyme.shallow() expect(wrapper.find('label').find(tag)).toHaveLength(1) }) it('should render the rest of the passed props', () => { const wrapper = Enzyme.shallow() expect( wrapper .find('label') .find(tag) .prop('placeholder'), ).toBe('foo') }) it('should render a padding on the input element when an indicator is present', () => { const wrapper = Enzyme.shallow() expect( wrapper .find('div') .find(tag) .prop('style')!.paddingRight, ).not.toBe('1rem') }) describe('on being declared a block component', () => { const BLOCK_DISPLAYS = ['block', 'grid', 'flex', 'table'] it('should render the base element fullwidth', () => { const wrapper = Enzyme.shallow() const { display } = wrapper.find('div').prop('style')! expect(BLOCK_DISPLAYS).toContain(display) }) it('should render the input fullwidth', () => { const wrapper = Enzyme.shallow() if (tag === 'textarea') { expect(wrapper.find('label').find(tag)).not.toHaveStyle('width') } else { expect(wrapper.find('label').find(tag)).toHaveStyle('width', inputWidth) } }) it('should render the input as block element', () => { const wrapper = Enzyme.shallow() const { display } = wrapper .find('label') .find(tag) .prop('style')! expect(BLOCK_DISPLAYS).toContain(display) }) }) }) describe('on aiding user input', () => { it("should render a label to indicate the nature of the component's value", () => { const wrapper = Enzyme.shallow() expect(wrapper.find('label').find('span')).toHaveLength(1) }) it('should render the label text', () => { fc.assert( fc.property(fc.anything(), (label) => { const wrapper = Enzyme.shallow() expect(wrapper.find('label').find('span')).toHaveText(stringify(label)) }), { numRuns: 300, }, ) }) }) it('should guarantee minimal accessibility', () => { fc.assert( fc.asyncProperty(fc.string(1, 20), async (s) => { const wrapper = Enzyme.mount() const results = await Axe.axe(wrapper.getDOMNode()) expect(results).toHaveNoViolations() }), ) })