All files / Select Select.spec.js

99.17% Statements 120/121
100% Branches 4/4
100% Functions 29/29
99.17% Lines 120/121
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 2001x 1x 1x   1x   1x               1x   4x 4x   4x 4x 4x     1x         1x 1x 1x 1x     1x 1x 1x     1x 1x 1x   1x     1x 1x 1x 1x 1x 1x     1x 1x 1x 1x 1x     1x 1x 1x 1x 1x 1x     1x 1x 1x 1x   1x 1x 1x         1x 1x 1x 1x 1x     1x 1x 1x 1x     1x 1x 1x 1x 1x     1x 1x 1x 1x 1x     1x 1x 1x     1x 1x 1x 1x     1x 1x 1x 1x 1x       1x 1x 1x     1x 1x   1x 1x 1x 1x       1x 1x 1x 1x   1x 1x 1x 1x 1x 1x 1x 1x 1x           1x 1x 1x 1x 1x 1x 1x       1x 1x 1x     1x       1x 1x 1x     1x 1x 2x     1x       1x 1x      
import React from 'react';
import sinon from 'sinon';
import { shallow, mount } from 'enzyme';
 
import Select from './Select';
 
import {
  KEY_UP,
  KEY_ESC,
  KEY_DOWN,
  KEY_ENTER,
  KEY_BACKSPACE
} from './constants'
 
const typing = (input, value, opts, callback) => {
 
  const options = callback ? opts : {}
  const _callback = callback ? callback : opts
 
  input.node.value = value
  input.simulate('keyDown', options);
  setTimeout(_callback, 1);
}
 
const options = [
  { label: 'One', value: 1 },
  { label: 'Two', value: 2 }
]
 
describe('<Select />', () => {
  it('should have default placeholder text', () => {
    const wrapper = mount(<Select />);
    expect(wrapper.find('[data-select-placeholder]').at(0).text()).to.equal('Select...');
  })
 
  it('should have custom placeholder text', () => {
    const wrapper = mount(<Select placeholder="My placeholder" />);
    expect(wrapper.find('[data-select-placeholder]').at(0).text()).to.equal('My placeholder');
  })
 
  it('should have two options lists', () => {
    const wrapper = mount(<Select options={options} />);
    wrapper.find('[data-select-control]').at(0).simulate('mouseDown');
 
    expect(wrapper.find('[data-select-option]').length).to.equal(2);
  })
 
  it('should call onChange callback when value change', () => {
    const onChangeSpy = sinon.spy()
    const wrapper = mount(<Select onChange={onChangeSpy} options={options} />);
    wrapper.find('[data-select-control]').at(0).simulate('mouseDown');
    wrapper.find('[data-select-option]').at(0).simulate('mouseDown');
    expect(onChangeSpy).to.have.property('callCount', 1);
  })
 
  it('should call callback onOpen', () => {
    const onOpenSpy = sinon.spy()
    const wrapper = mount(<Select onOpen={onOpenSpy} />);
    wrapper.find('[data-select-control]').at(0).simulate('mouseDown');
    expect(onOpenSpy).to.have.property('callCount', 1);
  })
 
  it('should call callback onValueClick', () => {
    const onValueClickSpy = sinon.spy()
    const wrapper = mount(<Select onValueClick={onValueClickSpy} options={options} />);
    wrapper.find('[data-select-control]').at(0).simulate('mouseDown');
    wrapper.find('[data-select-option]').at(0).simulate('mouseDown');
    expect(onValueClickSpy).to.have.property('callCount', 1);
  })
 
  it('should close when click outside', (done) => {
    const onValueClickSpy = sinon.spy()
    const wrapper = mount(<Select onValueClick={onValueClickSpy} />);
    wrapper.find('[data-select-control]').at(0).simulate('mouseDown');
 
    setTimeout(() => {
      document.querySelector('html').click()// Click outside
      expect(wrapper.find('[data-select-menu-outer]').length).to.equal(0);
      done()
    }, 200)
  })
 
  it('should close when click over some option', () => {
    const wrapper = mount(<Select options={options} />);
    wrapper.find('[data-select-control]').at(0).simulate('mouseDown');
    wrapper.find('[data-select-option]').at(0).simulate('mouseDown');
    expect(wrapper.find('[data-select-menu-outer]').length).to.equal(0);
  })
 
  it('should search disabled when searchable=false', () => {
    const wrapper = mount(<Select options={options} searchable={false} />);
    wrapper.find('[data-select-control]').at(0).simulate('mouseDown');
    expect(wrapper.find('[data-select-input]').length).to.equal(0);
  })
 
  it('should change field value when click over a option', () => {
    const wrapper = mount(<Select options={options} />);
    wrapper.find('[data-select-control]').at(0).simulate('mouseDown');
    wrapper.find('[data-select-option]').at(0).simulate('mouseDown');
    expect(wrapper.find('[data-select-value-label]').at(0).text()).to.equal('One');
  })
 
  it('should began with initial value selected', () => {
    const onValueClickSpy = sinon.spy()
    const wrapper = mount(<Select options={options} value={2} />);
    const selecteValueLabel = wrapper.find('[data-select-value-label]').at(0).text();
    expect(selecteValueLabel).to.equal('Two');
  })
 
  it('should have clear button by default', () => {
    const wrapper = mount(<Select clearable={true} />);
    expect(wrapper.find('[data-select-clear-zone]').length).to.equal(1);
  })
 
  it('should hidden clear button when clearable=false', () => {
    const onValueClickSpy = sinon.spy()
    const wrapper = mount(<Select clearable={false} />);
    expect(wrapper.find('[data-select-clear-zone]').length).to.equal(0);
  })
 
  it('should clear field when click over clear zone', () => {
    const onValueClickSpy = sinon.spy()
    const wrapper = mount(<Select options={options} value={2} clearable={true} />);
    wrapper.find('[data-select-clear-zone]').at(0).simulate('mouseDown');
    expect(wrapper.find('[data-select-placeholder]').length).to.equal(1);
  })
 
 
  it('should hidden placeholder when sarching', (done) => {
    const wrapper = mount(<Select />);
    const input = wrapper.find('[data-select-input-search]').at(0)
 
    // simulate type
    input.node.value = 'some term'
    input.simulate('keyDown');
 
    setTimeout(() => {
      expect(wrapper.find('[data-select-placeholder]').length).to.equal(0);
      expect(wrapper.find('[data-select-value-label]').length).to.equal(0);
      done()
    }, 2)
  })
 
  it('should reset field when search (field == empty && press backspace event)', (done) => {
    const onInputClearSpy = sinon.spy()
    const wrapper = mount(<Select onInputClear={onInputClearSpy} options={options} value={2} />);
    const input = wrapper.find('[data-select-input-search]').at(0)
 
    typing(input, 'a', () => {
      typing(input, '', () => {
        expect(wrapper.find('[data-select-value-label]').length).to.equal(1);
        typing(input, '', {keyCode: KEY_BACKSPACE}, () => {
          expect(wrapper.find('[data-select-value-label]').length).to.equal(0);
          expect(wrapper.find('[data-select-placeholder]').length).to.equal(1);
          expect(onInputClearSpy).to.have.property('callCount', 1);
          expect(wrapper.find('[data-select-menu-outer]').length).to.equal(0);
          done()
        })
      });
    });
  })
 
  it('should open outer menu when KEY_DOWN is pressed', (done) => {
    const onOpenSpy = sinon.spy()
    const wrapper = mount(<Select onOpen={onOpenSpy} options={options} value={2} />);
    const input = wrapper.find('[data-select-input-search]').at(0)
    typing(input, '', {keyCode: KEY_DOWN}, () => {
      expect(wrapper.find('[data-select-menu-outer]').length).to.equal(1);
      done()
    });
  });
 
  it('should render a custom value renderer', () => {
    const valueRenderer = () => {
      return (<div className="my-value" />);
    }
 
    const wrapper = mount(
      <Select options={options} valueRenderer={valueRenderer} />
    );
 
    wrapper.find('[data-select-control]').at(0).simulate('mouseDown');
    wrapper.find('[data-select-option]').at(0).simulate('mouseDown');
    expect(wrapper.find('.my-value')).to.have.property('length', 1);
  })
 
  it('should render a custom option renderer', () => {
    const optionRenderer = (opt, index) => {
      return (<div className="my-option" key={index} />);
    }
 
    const wrapper = mount(
      <Select options={options} optionRenderer={optionRenderer} />
    );
 
    wrapper.find('[data-select-control]').at(0).simulate('mouseDown');
    expect(wrapper.find('.my-option')).to.have.property('length', 2);
  })
});