WeAreGenki/minna-ui

View on GitHub
components/switch/src/__tests__/Switch.test.ts

Summary

Maintainability
C
7 hrs
Test Coverage
/* eslint-disable @typescript-eslint/no-non-null-assertion */

import { tick } from 'svelte';
import Switch from '../Switch.svelte';

describe('Switch component', () => {
  it('renders correctly with no props', () => {
    expect.assertions(6);
    const target = document.createElement('div');
    new Switch({ target });
    const el = target.querySelector('.switch')!;
    expect(el.getAttribute('tabindex')).toBe('0');
    expect(el.getAttribute('disabled')).toBeNull();
    expect(el.getAttribute('required')).toBeNull();
    expect(document.querySelector('.switch-checked')).toBeNull();
    expect(document.querySelector('.switch-disabled')).toBeNull();
    expect(target.innerHTML).toMatchSnapshot();
  });

  it("doesn't log errors or warnings with required props", () => {
    expect.assertions(2);
    const spy1 = jest.spyOn(console, 'error');
    const spy2 = jest.spyOn(console, 'warn');
    const target = document.createElement('div');
    new Switch({
      props: {
        value: false,
      },
      target,
    });
    expect(spy1).not.toHaveBeenCalled();
    expect(spy2).not.toHaveBeenCalled();
    spy1.mockRestore();
    spy2.mockRestore();
  });

  it('renders with value true', () => {
    expect.assertions(2);
    const target = document.createElement('div');
    const component = new Switch({
      props: {
        value: true,
      },
      target,
    });
    expect(component.value).toBe(true);
    expect(target.querySelector('.switch-checked')).not.toBeNull();
  });

  it('renders with value false', () => {
    expect.assertions(2);
    const target = document.createElement('div');
    const component = new Switch({
      props: {
        value: false,
      },
      target,
    });
    expect(component.value).toBe(false);
    expect(target.querySelector('.switch-checked')).toBeNull();
  });

  it('renders with textOn/textOff props', () => {
    expect.assertions(4);
    const target = document.createElement('div');
    const component = new Switch({
      props: {
        textOff: 'NO',
        textOn: 'YES',
      },
      target,
    });
    expect(component.textOn).toBe('YES');
    expect(component.textOff).toBe('NO');
    const switchOn = target.querySelector('.switch-on')!;
    const switchOff = target.querySelector('.switch-off')!;
    expect(switchOn.innerHTML).toBe('YES');
    expect(switchOff.innerHTML).toBe('NO');
  });

  it('renders with mini prop', () => {
    expect.assertions(2);
    const target = document.createElement('div');
    const component = new Switch({
      props: {
        mini: true,
      },
      target,
    });
    expect(component.mini).toBe(true);
    expect(target.querySelector('.switch-mini')).not.toBeNull();
  });

  it('renders with disabled prop', () => {
    expect.assertions(3);
    const target = document.createElement('div');
    const component = new Switch({
      props: {
        disabled: true,
      },
      target,
    });
    expect(component.disabled).toBe(true);
    expect(target.querySelector('.switch-disabled')).not.toBeNull();
    expect(target.querySelector('.switch')!.getAttribute('tabindex')).toBe('-1');
  });

  it('toggles class when value changes', async () => {
    expect.assertions(4);
    const target = document.createElement('div');
    const component = new Switch({
      props: {
        value: false,
      },
      target,
    });
    expect(component.value).toBe(false);
    expect(target.querySelector('.switch-checked')).toBeNull();
    component.$set({ value: true });
    await tick();
    expect(target.querySelector('.switch-checked')).not.toBeNull();
    component.$set({ value: false });
    await tick();
    expect(target.querySelector('.switch-checked')).toBeNull();
  });

  it('toggles value on click', async () => {
    expect.assertions(4);
    const target = document.createElement('div');
    const component = new Switch({
      props: {
        value: true,
      },
      target,
    });
    expect(component.value).toBe(true);
    expect(target.querySelector('.switch-checked')).not.toBeNull();
    const el = target.querySelector<HTMLDivElement>('.switch')!;
    el.click();
    await tick();
    expect(component.value).toBe(false);
    expect(target.querySelector('.switch-checked')).toBeNull();
  });

  it('does not toggle value on click when disabled', async () => {
    expect.assertions(4);
    const target = document.createElement('div');
    const component = new Switch({
      props: {
        disabled: true,
        value: true,
      },
      target,
    });
    expect(component.value).toBe(true);
    expect(target.querySelector('.switch-checked')).not.toBeNull();
    const el = target.querySelector<HTMLDivElement>('.switch')!;
    el.click();
    await tick();
    expect(component.value).toBe(true);
    expect(target.querySelector('.switch-checked')).not.toBeNull();
  });

  it('toggles on enter key press', async () => {
    expect.assertions(6);
    const target = document.createElement('div');
    const component = new Switch({
      props: {
        value: true,
      },
      target,
    });
    expect(component.value).toBe(true);
    expect(target.querySelector('.switch-checked')).not.toBeNull();
    const el = target.querySelector('div.switch')!;
    const event1 = new KeyboardEvent('keydown', { key: 'Enter' });
    el.dispatchEvent(event1);
    await tick();
    expect(component.value).toBe(false);
    expect(target.querySelector('.switch-checked')).toBeNull();
    // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
    // @ts-ignore - keyCode does actually exist!
    const event2 = new KeyboardEvent('keydown', { keyCode: 13 });
    el.dispatchEvent(event2);
    await tick();
    expect(component.value).toBe(true);
    expect(target.querySelector('.switch-checked')).not.toBeNull();
  });

  it('toggles on spacebar key press', () => {
    expect.assertions(3);
    const target = document.createElement('div');
    const component = new Switch({
      props: {
        value: true,
      },
      target,
    });
    const el = target.querySelector('div.switch')!;
    const event1 = new KeyboardEvent('keydown', { key: ' ' });
    el.dispatchEvent(event1);
    expect(component.value).toBe(false);
    const event2 = new KeyboardEvent('keydown', { key: 'Spacebar' });
    el.dispatchEvent(event2);
    expect(component.value).toBe(true);
    // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
    // @ts-ignore - keyCode does actually exist!
    const event3 = new KeyboardEvent('keydown', { keyCode: 32 });
    el.dispatchEvent(event3);
    expect(component.value).toBe(false);
  });

  it('does not toggle on key press when disabled', () => {
    expect.assertions(1);
    const target = document.createElement('div');
    const component = new Switch({
      props: {
        disabled: true,
        value: true,
      },
      target,
    });
    const el = target.querySelector('div.switch')!;
    const event = new KeyboardEvent('keydown', { key: 'Enter' });
    el.dispatchEvent(event);
    expect(component.value).toBe(true);
  });

  it('does not toggle on invalid key press', () => {
    expect.assertions(8);
    const target = document.createElement('div');
    const component = new Switch({
      props: {
        value: true,
      },
      target,
    });
    const el = target.querySelector('div.switch')!;
    expect(component.value).toBe(true);
    const event1 = new KeyboardEvent('keydown', { key: 'Escape' });
    el.dispatchEvent(event1);
    expect(component.value).toBe(true);
    component.value = false;
    expect(component.value).toBe(false);
    // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
    // @ts-ignore - keyCode does actually exist!
    const event2 = new KeyboardEvent('keydown', { keyCode: 0 });
    el.dispatchEvent(event2);
    expect(component.value).toBe(false);
    component.value = true;
    expect(component.value).toBe(true);
    const event3 = new KeyboardEvent('keydown', { key: '' });
    el.dispatchEvent(event3);
    expect(component.value).toBe(true);
    component.value = false;
    expect(component.value).toBe(false);
    const event4 = new KeyboardEvent('keydown');
    el.dispatchEvent(event4);
    expect(component.value).toBe(false);
  });
});