import {
  testContext,
  testHook,
  testRenderProp,
} from '../../__tests__/helpers/state'
import {
  defaultZIndex,
  useZIndex,
  useZIndexContext,
  ZIndex,
  ZIndexProvider,
} from '../ZIndex'

const validateAPI = (api) => {
  expect(api.value).toEqual(defaultZIndex)
  expect(api.increment).toBeInstanceOf(Function)
}

const apiTest = {
  test: 'api',
  config: {},
  callback: validateAPI,
}

const configTest = {
  test: 'config',
  config: { initialValue: 10 },
  callback: ({ value }) => expect(value).toEqual(10),
}

describe('ZIndex', () => {
  testHook(useZIndex, [
    apiTest,
    configTest,
    {
      test: 'mutations',
      config: {},
      mutations: [['increment', null, ['value', 'toBe', defaultZIndex + 1]]],
    },
  ])

  testRenderProp(ZIndex, 'zIndex', [apiTest, configTest])

  testContext(ZIndexProvider, useZIndexContext, [
    {
      test: 'api',
      config: {},
      callback: (api) => {
        expect(api.value).toEqual(defaultZIndex + 1)
        expect(api.increment).toBeInstanceOf(Function)
      },
    },
    {
      test: 'config',
      config: { initialValue: 10 },
      callback: ({ value }) => expect(value).toEqual(11),
    },
    {
      test: 'missing provider',
      config: {},
      injectProvider: false,
      callback: (context, { spy }) => {
        spy.mockImplementation(() => {})

        expect(context.value).toBe(defaultZIndex + 1)
        context.increment()
        expect(spy).toBeCalledTimes(1)
        expect(spy).toBeCalledWith(
          'Could not call `increment`, please wrap your component in a `<ZIndexProvider>`'
        )

        spy.mockRestore()
      },
    },
  ])
})
