select.spec.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. import { createTest, createVue, triggerEvent, destroyVM } from '../util';
  2. import Select from 'packages/select';
  3. describe('Select', () => {
  4. const getSelectVm = (configs = {}, options) => {
  5. ['multiple', 'clearable', 'filterable', 'remote'].forEach(config => {
  6. configs[config] = configs[config] || false;
  7. });
  8. if (!options) {
  9. options = [{
  10. value: '选项1',
  11. label: '黄金糕',
  12. disabled: false
  13. }, {
  14. value: '选项2',
  15. label: '双皮奶',
  16. disabled: false
  17. }, {
  18. value: '选项3',
  19. label: '蚵仔煎',
  20. disabled: false
  21. }, {
  22. value: '选项4',
  23. label: '龙须面',
  24. disabled: false
  25. }, {
  26. value: '选项5',
  27. label: '北京烤鸭',
  28. disabled: false
  29. }];
  30. }
  31. const vm = createVue({
  32. template: `
  33. <div>
  34. <el-select
  35. v-model="value"
  36. :multiple="multiple"
  37. :clearable="clearable"
  38. :filterable="filterable"
  39. :filterMethod="filterMethod"
  40. :remote="remote"
  41. :loading="loading"
  42. :remoteMethod="remoteMethod">
  43. <el-option
  44. v-for="item in options"
  45. :label="item.label"
  46. :disabled="item.disabled"
  47. :value="item.value">
  48. </el-option>
  49. </el-select>
  50. </div>
  51. `,
  52. data() {
  53. return {
  54. options,
  55. multiple: configs.multiple,
  56. clearable: configs.clearable,
  57. filterable: configs.filterable,
  58. loading: false,
  59. filterMethod: configs.filterMethod && configs.filterMethod(this),
  60. remote: configs.remote,
  61. remoteMethod: configs.remoteMethod && configs.remoteMethod(this),
  62. value: configs.multiple ? [] : ''
  63. };
  64. }
  65. }, true);
  66. return vm;
  67. };
  68. let vm;
  69. afterEach(() => {
  70. destroyVM(vm);
  71. });
  72. it('create', () => {
  73. vm = createTest(Select, true);
  74. expect(vm.$el.className).to.equal('el-select');
  75. expect(vm.$el.querySelector('.el-input__inner').placeholder).to.equal('请选择');
  76. vm.toggleMenu();
  77. expect(vm.visible).to.true;
  78. });
  79. it('options rendered correctly', () => {
  80. vm = getSelectVm();
  81. const options = vm.$el.querySelectorAll('.el-select-dropdown__item');
  82. const result = [].every.call(options, (option, index) => {
  83. let text = option.querySelector('span').textContent;
  84. return text === vm.options[index].label;
  85. });
  86. expect(result).to.true;
  87. });
  88. it('default value', done => {
  89. vm = createVue({
  90. template: `
  91. <div>
  92. <el-select v-model="value">
  93. <el-option
  94. v-for="item in options"
  95. :label="item.label"
  96. :value="item.value">
  97. </el-option>
  98. </el-select>
  99. </div>
  100. `,
  101. data() {
  102. return {
  103. options: [{
  104. value: '选项1',
  105. label: '黄金糕'
  106. }, {
  107. value: '选项2',
  108. label: '双皮奶'
  109. }],
  110. value: '选项2'
  111. };
  112. }
  113. }, true);
  114. setTimeout(() => {
  115. expect(vm.$el.querySelector('.el-input__inner').value).to.equal('双皮奶');
  116. done();
  117. }, 100);
  118. });
  119. it('single select', done => {
  120. sinon.stub(window.console, 'log');
  121. vm = createVue({
  122. template: `
  123. <div>
  124. <el-select v-model="value" @change="handleChange">
  125. <el-option
  126. v-for="item in options"
  127. :label="item.label"
  128. :value="item.value">
  129. <p>{{item.label}} {{item.value}}</p>
  130. </el-option>
  131. </el-select>
  132. </div>
  133. `,
  134. data() {
  135. return {
  136. options: [{
  137. value: '选项1',
  138. label: '黄金糕'
  139. }, {
  140. value: '选项2',
  141. label: '双皮奶'
  142. }, {
  143. value: '选项3',
  144. label: '蚵仔煎'
  145. }, {
  146. value: '选项4',
  147. label: '龙须面'
  148. }, {
  149. value: '选项5',
  150. label: '北京烤鸭'
  151. }],
  152. value: ''
  153. };
  154. },
  155. methods: {
  156. handleChange() {
  157. console.log('changed');
  158. }
  159. }
  160. }, true);
  161. const options = vm.$el.querySelectorAll('.el-select-dropdown__item');
  162. expect(vm.value).to.equal('');
  163. triggerEvent(options[2], 'mouseenter');
  164. options[2].click();
  165. setTimeout(() => {
  166. expect(vm.value).to.equal('选项3');
  167. expect(window.console.log.callCount).to.equal(1);
  168. options[4].click();
  169. setTimeout(() => {
  170. expect(vm.value).to.equal('选项5');
  171. expect(window.console.log.callCount).to.equal(2);
  172. window.console.log.restore();
  173. done();
  174. }, 100);
  175. }, 100);
  176. });
  177. it('disabled option', done => {
  178. vm = getSelectVm();
  179. vm.options[1].disabled = true;
  180. setTimeout(() => {
  181. const options = vm.$el.querySelectorAll('.el-select-dropdown__item');
  182. expect(options[1].classList.contains('is-disabled')).to.true;
  183. options[1].click();
  184. setTimeout(() => {
  185. expect(vm.value).to.equal('');
  186. done();
  187. }, 100);
  188. }, 100);
  189. });
  190. it('disabled select', () => {
  191. vm = createTest(Select, { disabled: true }, true);
  192. expect(vm.$el.querySelector('.el-input').classList.contains('is-disabled')).to.true;
  193. });
  194. it('keyboard operations', done => {
  195. vm = getSelectVm();
  196. const select = vm.$children[0];
  197. let i = 8;
  198. while (i--) {
  199. select.navigateOptions('next');
  200. }
  201. select.navigateOptions('prev');
  202. setTimeout(() => {
  203. expect(select.hoverIndex).to.equal(0);
  204. select.selectOption();
  205. setTimeout(() => {
  206. expect(select.value).to.equal('选项1');
  207. done();
  208. }, 100);
  209. }, 100);
  210. });
  211. it('clearable', done => {
  212. vm = getSelectVm({ clearable: true });
  213. const select = vm.$children[0];
  214. vm.value = '选项1';
  215. select.inputHovering = true;
  216. setTimeout(() => {
  217. const icon = vm.$el.querySelector('.el-input__icon');
  218. expect(icon.classList.contains('el-icon-circle-close')).to.true;
  219. icon.click();
  220. expect(vm.value).to.equal('');
  221. done();
  222. }, 100);
  223. });
  224. it('custom el-option template', () => {
  225. vm = createVue({
  226. template: `
  227. <div>
  228. <el-select v-model="value">
  229. <el-option
  230. v-for="item in options"
  231. :label="item.label"
  232. :value="item.value">
  233. <p>{{item.label}} {{item.value}}</p>
  234. </el-option>
  235. </el-select>
  236. </div>
  237. `,
  238. data() {
  239. return {
  240. options: [{
  241. value: 'value',
  242. label: 'label'
  243. }],
  244. value: ''
  245. };
  246. }
  247. }, true);
  248. expect(vm.$el.querySelector('.el-select-dropdown__item p').textContent).to.equal('label value');
  249. });
  250. it('option group', () => {
  251. vm = createVue({
  252. template: `
  253. <div>
  254. <el-select v-model="value">
  255. <el-option-group
  256. v-for="group in options"
  257. :disabled="group.disabled"
  258. :label="group.label">
  259. <el-option
  260. v-for="item in group.options"
  261. :label="item.label"
  262. :value="item.value">
  263. </el-option>
  264. </el-option-group>
  265. </el-select>
  266. </div>
  267. `,
  268. data() {
  269. return {
  270. options: [{
  271. label: '热门城市',
  272. options: [{
  273. value: 'Shanghai',
  274. label: '上海'
  275. }, {
  276. value: 'Beijing',
  277. label: '北京'
  278. }]
  279. }, {
  280. label: '城市名',
  281. disabled: true,
  282. options: [{
  283. value: 'Chengdu',
  284. label: '成都'
  285. }, {
  286. value: 'Shenzhen',
  287. label: '深圳'
  288. }, {
  289. value: 'Guangzhou',
  290. label: '广州'
  291. }, {
  292. value: 'Dalian',
  293. label: '大连'
  294. }]
  295. }],
  296. value: ''
  297. };
  298. }
  299. }, true);
  300. const groups = vm.$el.querySelectorAll('.el-select-group__wrap');
  301. const options = groups[1].querySelectorAll('.el-select-dropdown__item');
  302. expect(groups.length).to.equal(2);
  303. expect(options.length).to.equal(4);
  304. expect(options[0].querySelector('span').textContent).to.equal('成都');
  305. });
  306. it('filterable', done => {
  307. vm = getSelectVm({ filterable: true });
  308. const select = vm.$children[0];
  309. select.selectedLabel = '面';
  310. select.onInputChange();
  311. select.visible = true;
  312. setTimeout(() => {
  313. expect(select.filteredOptionsCount).to.equal(1);
  314. done();
  315. }, 100);
  316. });
  317. it('filterable with custom filter-method', done => {
  318. const filterMethod = vm => {
  319. return query => {
  320. vm.options = vm.options.filter(option => option.label.indexOf(query) === -1);
  321. };
  322. };
  323. vm = getSelectVm({ filterable: true, filterMethod });
  324. const select = vm.$children[0];
  325. select.query = '面';
  326. setTimeout(() => {
  327. expect(select.filteredOptionsCount).to.equal(4);
  328. done();
  329. }, 100);
  330. });
  331. it('multiple select', done => {
  332. vm = getSelectVm({ multiple: true });
  333. const options = vm.$el.querySelectorAll('.el-select-dropdown__item');
  334. vm.value = ['选项1'];
  335. setTimeout(() => {
  336. options[1].click();
  337. options[3].click();
  338. setTimeout(() => {
  339. expect(vm.value.indexOf('选项2') > -1 && vm.value.indexOf('选项4') > -1).to.true;
  340. const tagCloseIcons = vm.$el.querySelectorAll('.el-tag__close');
  341. tagCloseIcons[0].click();
  342. setTimeout(() => {
  343. expect(vm.value.indexOf('选项1')).to.equal(-1);
  344. done();
  345. }, 100);
  346. }, 100);
  347. }, 100);
  348. });
  349. it('multiple remote search', done => {
  350. const remoteMethod = vm => {
  351. return query => {
  352. vm.loading = true;
  353. setTimeout(() => {
  354. vm.options = vm.options.filter(option => {
  355. return option.label.indexOf(query) > -1;
  356. });
  357. vm.loading = false;
  358. }, 200);
  359. };
  360. };
  361. vm = getSelectVm({
  362. multiple: true,
  363. remote: true,
  364. filterable: true,
  365. remoteMethod
  366. });
  367. const select = vm.$children[0];
  368. select.query = '面';
  369. setTimeout(() => {
  370. expect(select.filteredOptionsCount).to.equal(1);
  371. select.query = '';
  372. select.options[0].$el.click();
  373. vm.$nextTick(() => {
  374. expect(vm.value[0]).to.equal('选项4');
  375. select.deletePrevTag({ target: select.$refs.input });
  376. select.deletePrevTag({ target: select.$refs.input });
  377. select.resetInputState({ keyCode: 1 });
  378. vm.$nextTick(() => {
  379. expect(vm.value.length).to.equal(0);
  380. done();
  381. });
  382. });
  383. }, 250);
  384. });
  385. });