/// <reference types="jest-enzyme" />
/// <reference path="../../../../../utilities/jest/extensions.ts" />

import * as fc from 'fast-check'
import * as Enzyme from 'enzyme'
import * as Axe from 'jest-axe'
import * as React from 'react'
import Checkbox from '.'
import stringify from '../../utilities/stringify'

it('should exist', () => {
  expect(Checkbox).toBeDefined()
})

it('should be a component', () => {
  expect(Checkbox).toBeComponent()
})

it('should render without crashing given required props', () => {
  expect(() => <Checkbox />).not.toThrow()
})

it('should render a label to describe the intrinsic value of the component', () => {
  const wrapper = Enzyme.shallow(<Checkbox label="foo" />)

  expect(wrapper.find('label').children()).toHaveLength(4)
})

it('should render the label when not undefined or null', () => {
  fc.assert(
    fc.property(fc.anything().filter((v) => !Array.isArray(v) && typeof v !== 'undefined' && v !== null), (label) => {
      const wrapper = Enzyme.shallow(<Checkbox label={label} />)

      expect(
        wrapper
          .find('label')
          .children()
          .last(),
      ).toHaveText(stringify(label))
    }),
    {
      numRuns: 300,
    },
  )
})

it('should render the label when undefined or null', () => {
  fc.assert(
    fc.property(fc.oneof(fc.constant(void 0), fc.constant(null)), (label) => {
      const wrapper = Enzyme.shallow(<Checkbox label={label} />)

      expect(
        wrapper
          .find('label')
          .children()
          .last()
          .text(),
      ).toHaveLength(0)
    }),
  )
})

it('should render the input', () => {
  const wrapper = Enzyme.shallow(<Checkbox />)

  expect(wrapper.find('label').find('input')).toHaveLength(1)
})

it('should guarantee minimal accessibility', () => {
  fc.assert(
    fc.asyncProperty(fc.string(1, 20), async (s) => {
      const wrapper = Enzyme.mount(<Checkbox label={s} />)
      const results = await Axe.axe(wrapper.getDOMNode())

      expect(results).toHaveNoViolations()
    }),
  )
})
