table.spec.js 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444
  1. import { createVue, triggerEvent, destroyVM } from '../util';
  2. const DELAY = 10;
  3. const testDataArr = [];
  4. const toArray = function(obj) {
  5. return [].slice.call(obj);
  6. };
  7. const getTestData = function() {
  8. return [
  9. { name: 'Toy Story', release: '1995-11-22', director: 'John Lasseter', runtime: 80 },
  10. { name: 'A Bug\'s Life', release: '1998-11-25', director: 'John Lasseter', runtime: 95 },
  11. { name: 'Toy Story 2', release: '1999-11-24', director: 'John Lasseter', runtime: 92 },
  12. { name: 'Monsters, Inc.', release: '2001-11-2', director: 'Peter Docter', runtime: 92 },
  13. { name: 'Finding Nemo', release: '2003-5-30', director: 'Andrew Stanton', runtime: 100 }
  14. ];
  15. };
  16. getTestData().forEach(cur => {
  17. Object.keys(cur).forEach(prop => {
  18. testDataArr.push(cur[prop].toString());
  19. });
  20. });
  21. describe('Table', () => {
  22. describe('rendering data is correct', () => {
  23. const vm = createVue({
  24. template: `
  25. <el-table :data="testData">
  26. <el-table-column prop="name" label="片名" />
  27. <el-table-column prop="release" label="发行日期" />
  28. <el-table-column prop="director" label="导演" />
  29. <el-table-column prop="runtime" label="时长(分)" />
  30. </el-table>
  31. `,
  32. created() {
  33. this.testData = getTestData();
  34. }
  35. });
  36. it('head', done => {
  37. setTimeout(_ => {
  38. const ths = toArray(vm.$el.querySelectorAll('thead th'));
  39. expect(ths.map(node => node.textContent).filter(o => o))
  40. .to.eql(['片名', '发行日期', '导演', '时长(分)']);
  41. done();
  42. }, DELAY);
  43. });
  44. it('row length', () => {
  45. expect(vm.$el.querySelectorAll('.el-table__body-wrapper tbody tr')).to.length(getTestData().length);
  46. });
  47. it('row data', () => {
  48. const cells = toArray(vm.$el.querySelectorAll('td .cell'))
  49. .map(node => node.textContent);
  50. expect(cells).to.eql(testDataArr);
  51. destroyVM(vm);
  52. });
  53. });
  54. describe('attributes', () => {
  55. const createTable = function(props, opts) {
  56. return createVue(Object.assign({
  57. template: `
  58. <el-table :data="testData" ${props}>
  59. <el-table-column prop="name" label="片名" />
  60. <el-table-column prop="release" label="发行日期" />
  61. <el-table-column prop="director" label="导演" />
  62. <el-table-column prop="runtime" label="时长(分)" />
  63. </el-table>
  64. `,
  65. created() {
  66. this.testData = getTestData();
  67. }
  68. }, opts));
  69. };
  70. it('height', done => {
  71. const vm = createTable('height="134"');
  72. setTimeout(_ => {
  73. expect(vm.$el.style.height).to.equal('134px');
  74. destroyVM(vm);
  75. done();
  76. }, DELAY);
  77. });
  78. it('stripe', done => {
  79. const vm = createTable('stripe');
  80. setTimeout(_ => {
  81. expect(vm.$el.classList.contains('el-table--striped')).to.true;
  82. destroyVM(vm);
  83. done();
  84. }, DELAY);
  85. });
  86. it('border', done => {
  87. const vm = createTable('border');
  88. setTimeout(_ => {
  89. expect(vm.$el.classList.contains('el-table--border')).to.true;
  90. destroyVM(vm);
  91. done();
  92. }, DELAY);
  93. });
  94. it('fit', done => {
  95. const vm = createTable(':fit="false"');
  96. setTimeout(_ => {
  97. expect(vm.$el.classList.contains('el-table--fit')).to.false;
  98. destroyVM(vm);
  99. done();
  100. }, DELAY);
  101. });
  102. it('show-header', done => {
  103. const vm = createTable(':show-header="false"');
  104. setTimeout(_ => {
  105. expect(vm.$el.querySelectorAll('.el-table__header-wrapper').length).to.equal(0);
  106. destroyVM(vm);
  107. done();
  108. }, DELAY);
  109. });
  110. it('tableRowClassName', done => {
  111. const vm = createTable(':row-class-name="tableRowClassName"', {
  112. methods: {
  113. tableRowClassName(row, index) {
  114. if (index === 1) {
  115. return 'info-row';
  116. } else if (index === 3) {
  117. return 'positive-row';
  118. }
  119. return '';
  120. }
  121. }
  122. });
  123. setTimeout(_ => {
  124. expect(vm.$el.querySelectorAll('.info-row')).to.length(1);
  125. expect(vm.$el.querySelectorAll('.positive-row')).to.length(1);
  126. destroyVM(vm);
  127. done();
  128. }, DELAY);
  129. });
  130. it('tableRowStyle[Object]', done => {
  131. const vm = createTable(':row-style="{ height: \'60px\' }"', {});
  132. setTimeout(_ => {
  133. expect(vm.$el.querySelector('.el-table__body tr').style.height).to.equal('60px');
  134. destroyVM(vm);
  135. done();
  136. }, DELAY);
  137. });
  138. it('tableRowStyle[Function]', done => {
  139. const vm = createTable(':row-style="tableRowStyle"', {
  140. methods: {
  141. tableRowStyle(row, index) {
  142. if (index === 1) {
  143. return { height: '60px' };
  144. }
  145. return null;
  146. }
  147. }
  148. });
  149. setTimeout(_ => {
  150. expect(vm.$el.querySelector('.el-table__body tr:nth-child(1)').style.height).to.equal('');
  151. expect(vm.$el.querySelector('.el-table__body tr:nth-child(2)').style.height).to.equal('60px');
  152. destroyVM(vm);
  153. done();
  154. }, DELAY);
  155. });
  156. });
  157. describe('filter', () => {
  158. let vm;
  159. beforeEach(done => {
  160. vm = createVue({
  161. template: `
  162. <el-table ref="table" :data="testData">
  163. <el-table-column prop="name" label="片名" />
  164. <el-table-column prop="release" label="发行日期" />
  165. <el-table-column
  166. prop="director"
  167. :filters="[
  168. { text: 'John Lasseter', value: 'John Lasseter' },
  169. { text: 'Peter Docter', value: 'Peter Docter' },
  170. { text: 'Andrew Stanton', value: 'Andrew Stanton' }
  171. ]"
  172. :filter-method="filterMethod"
  173. label="导演" />
  174. <el-table-column prop="runtime" label="时长(分)" />
  175. </el-table>
  176. `,
  177. created() {
  178. this.testData = getTestData();
  179. },
  180. methods: {
  181. filterMethod(value, row) {
  182. return value === row.director;
  183. }
  184. }
  185. }, true);
  186. setTimeout(done, DELAY);
  187. });
  188. afterEach(() => destroyVM(vm));
  189. it('render', () => {
  190. expect(vm.$el.querySelector('.el-table__column-filter-trigger')).to.exist;
  191. });
  192. it('click dropdown', done => {
  193. const btn = vm.$el.querySelector('.el-table__column-filter-trigger');
  194. triggerEvent(btn, 'click', true, false);
  195. setTimeout(_ => {
  196. const filter = document.body.querySelector('.el-table-filter');
  197. expect(filter).to.exist;
  198. document.body.removeChild(filter);
  199. done();
  200. }, 100);
  201. });
  202. it('click filter', done => {
  203. const btn = vm.$el.querySelector('.el-table__column-filter-trigger');
  204. triggerEvent(btn, 'click', true, false);
  205. setTimeout(_ => {
  206. const filter = document.body.querySelector('.el-table-filter');
  207. // John Lasseter
  208. triggerEvent(filter.querySelector('.el-checkbox'), 'click', true, false);
  209. // confrim button
  210. setTimeout(_ => {
  211. triggerEvent(filter.querySelector('.el-table-filter__bottom button'), 'click', true, false);
  212. setTimeout(_ => {
  213. expect(vm.$el.querySelectorAll('.el-table__body-wrapper tbody tr')).to.length(3);
  214. document.body.removeChild(filter);
  215. done();
  216. }, DELAY);
  217. }, 100);
  218. }, 100);
  219. });
  220. it('click reset', done => {
  221. const btn = vm.$el.querySelector('.el-table__column-filter-trigger');
  222. triggerEvent(btn, 'click', true, false);
  223. setTimeout(_ => {
  224. const filter = document.body.querySelector('.el-table-filter');
  225. // John Lasseter
  226. triggerEvent(filter.querySelector('.el-checkbox'), 'click', true, false);
  227. setTimeout(_ => {
  228. // reset button
  229. triggerEvent(filter.querySelectorAll('.el-table-filter__bottom button')[1], 'click', true, false);
  230. setTimeout(_ => {
  231. expect(filter.querySelector('.el-table-filter__bottom button').classList.contains('is-disabled')).to.true;
  232. document.body.removeChild(filter);
  233. destroyVM(vm);
  234. done();
  235. }, DELAY);
  236. }, 100);
  237. }, 100);
  238. });
  239. });
  240. describe('events', () => {
  241. const createTable = function(prop = '', opts) {
  242. return createVue({
  243. template: `
  244. <el-table :data="testData" @${prop}="handleEvent">
  245. <el-table-column type="selection" />
  246. <el-table-column prop="name" />
  247. <el-table-column prop="release" />
  248. <el-table-column prop="director" />
  249. <el-table-column prop="runtime"/>
  250. </el-table>
  251. `,
  252. methods: {
  253. handleEvent(...args) {
  254. this.result = args;
  255. }
  256. },
  257. created() {
  258. this.testData = getTestData();
  259. },
  260. data() {
  261. return { result: '', testData: this.testData };
  262. }
  263. }, true);
  264. };
  265. it('select', done => {
  266. const vm = createTable('select');
  267. setTimeout(_ => {
  268. vm.$el.querySelectorAll('.el-checkbox')[1].click();
  269. expect(vm.result).to.length(2);
  270. expect(vm.result[1]).to.have.property('name').to.equal(getTestData()[0].name);
  271. destroyVM(vm);
  272. done();
  273. }, DELAY);
  274. });
  275. it('select-all', done => {
  276. const vm = createTable('select-all');
  277. setTimeout(_ => {
  278. vm.$el.querySelector('.el-checkbox').click();
  279. setTimeout(_ => {
  280. expect(vm.result).to.length(1);
  281. expect(vm.result[0]).to.length(getTestData().length);
  282. destroyVM(vm);
  283. done();
  284. }, DELAY);
  285. }, DELAY);
  286. });
  287. it('selection-change', done => {
  288. const vm = createTable('selection-change');
  289. setTimeout(_ => {
  290. vm.$el.querySelectorAll('.el-checkbox')[1].click();
  291. expect(vm.result).to.length(1);
  292. destroyVM(vm);
  293. done();
  294. }, DELAY);
  295. });
  296. it('cell-mouse-enter', done => {
  297. const vm = createTable('cell-mouse-enter');
  298. setTimeout(_ => {
  299. const cell = vm.$el.querySelectorAll('.el-table__body .cell')[2]; // first row
  300. triggerEvent(cell.parentNode, 'mouseenter');
  301. expect(vm.result).to.length(4); // row, column, cell, event
  302. expect(vm.result[0]).to.have.property('name').to.equal(getTestData()[0].name);
  303. destroyVM(vm);
  304. done();
  305. }, DELAY);
  306. });
  307. it('cell-mouse-leave', done => {
  308. const vm = createTable('cell-mouse-leave');
  309. setTimeout(_ => {
  310. const cell = vm.$el.querySelectorAll('.el-table__body .cell')[7]; // second row
  311. const cell2 = vm.$el.querySelectorAll('.el-table__body .cell')[2]; // first row
  312. triggerEvent(cell2.parentNode, 'mouseenter');
  313. triggerEvent(cell.parentNode, 'mouseleave');
  314. expect(vm.result).to.length(4); // row, column, cell, event
  315. expect(vm.result[0]).to.have.property('name').to.equal(getTestData()[0].name);
  316. destroyVM(vm);
  317. done();
  318. }, DELAY);
  319. });
  320. it('cell-click', done => {
  321. const vm = createTable('cell-click');
  322. setTimeout(_ => {
  323. const cell = vm.$el.querySelectorAll('.el-table__body .cell')[2]; // first row
  324. cell.parentNode.click();
  325. expect(vm.result).to.length(4); // row, column, cell, event
  326. expect(vm.result[0]).to.have.property('name').to.equal(getTestData()[0].name);
  327. destroyVM(vm);
  328. done();
  329. }, DELAY);
  330. });
  331. it('row-click', done => {
  332. const vm = createTable('row-click');
  333. setTimeout(_ => {
  334. const cell = vm.$el.querySelectorAll('.el-table__body .cell')[2]; // first row
  335. triggerEvent(cell.parentNode.parentNode, 'click');
  336. expect(vm.result).to.length(2); // row, event
  337. expect(vm.result[0]).to.have.property('name').to.equal(getTestData()[0].name);
  338. destroyVM(vm);
  339. done();
  340. }, DELAY);
  341. });
  342. it('current-change', done => {
  343. const vm = createTable('current-change');
  344. setTimeout(_ => {
  345. const cell = vm.$el.querySelectorAll('.el-table__body .cell')[2]; // first row
  346. triggerEvent(cell.parentNode.parentNode, 'click');
  347. expect(vm.result).to.length(2); // currentRow, oldCurrentRow
  348. expect(vm.result[0]).to.have.property('name').to.equal(getTestData()[0].name);
  349. expect(vm.result[1]).to.equal(null);
  350. // clear data => current-change should fire again.
  351. const oldRow = vm.result[0];
  352. vm.testData = [];
  353. setTimeout(() => {
  354. expect(vm.result).to.length(2); // currentRow, oldCurrentRow
  355. expect(vm.result[0]).to.equal(null);
  356. expect(vm.result[1]).to.equal(oldRow);
  357. destroyVM(vm);
  358. done();
  359. }, DELAY);
  360. }, DELAY);
  361. });
  362. it('header-click', done => {
  363. const vm = createTable('header-click');
  364. setTimeout(_ => {
  365. const cell = vm.$el.querySelectorAll('.el-table__header th')[1]; // header[prop='name']
  366. triggerEvent(cell, 'click');
  367. expect(vm.result).to.length(2); // column, event
  368. expect(vm.result[0]).to.have.property('property').to.equal('name');
  369. destroyVM(vm);
  370. done();
  371. }, DELAY);
  372. });
  373. });
  374. describe('column attributes', () => {
  375. const createTable = function(props1, props2, props3, props4, opts, tableProps) {
  376. return createVue(Object.assign({
  377. template: `
  378. <el-table :data="testData" ${tableProps || ''}>
  379. <el-table-column prop="name" ${props1 || ''} />
  380. <el-table-column prop="release" ${props2 || ''} />
  381. <el-table-column prop="director" ${props3 || ''} />
  382. <el-table-column prop="runtime" ${props4 || ''} />
  383. </el-table>
  384. `,
  385. created() {
  386. this.testData = getTestData();
  387. }
  388. }, opts));
  389. };
  390. it('label', done => {
  391. const vm = createTable('label="啊哈哈哈"', 'label="啊啦啦啦"');
  392. setTimeout(_ => {
  393. const ths = toArray(vm.$el.querySelectorAll('thead th'))
  394. .map(node => node.textContent).filter(o => o);
  395. expect(ths).to.eql(['啊哈哈哈', '啊啦啦啦']);
  396. destroyVM(vm);
  397. done();
  398. }, DELAY);
  399. });
  400. it('width', done => {
  401. const vm = createTable('width="123px"', ':width="102"', 'width="39"');
  402. setTimeout(_ => {
  403. const ths = toArray(vm.$el.querySelectorAll('.el-table__header-wrapper col'))
  404. .map(node => node.width).filter(o => o);
  405. expect(ths).to.include('123').include('102').include('39');
  406. destroyVM(vm);
  407. done();
  408. }, DELAY);
  409. });
  410. it('fixed', done => {
  411. const vm = createTable(
  412. 'fixed label="test1"',
  413. 'fixed="right" label="test2"',
  414. 'fixed="left" label="test3"');
  415. setTimeout(_ => {
  416. expect(toArray(vm.$el.querySelectorAll('.el-table__fixed th:not(.is-hidden)'))
  417. .map(node => node.textContent))
  418. .to.eql(['test1', 'test3']);
  419. expect(toArray(vm.$el.querySelectorAll('.el-table__fixed-right th:not(.is-hidden)'))
  420. .map(node => node.textContent))
  421. .to.eql(['test2']);
  422. expect(vm.$el.querySelector('.el-table__body-wrapper').style.height).to.equal('');
  423. destroyVM(vm);
  424. done();
  425. }, DELAY);
  426. });
  427. it('resizable', done => {
  428. const vm = createTable(
  429. 'resizable',
  430. ':resizable="false"',
  431. '',
  432. '',
  433. {},
  434. 'border');
  435. setTimeout(_ => {
  436. const firstCol = vm.$el.querySelector('thead th');
  437. triggerEvent(firstCol, 'mousemove');
  438. triggerEvent(firstCol, 'mousedown');
  439. destroyVM(vm);
  440. done();
  441. }, DELAY);
  442. });
  443. it('formatter', done => {
  444. const vm = createTable(
  445. ':formatter="renderCell"', '', '', '', {
  446. methods: {
  447. renderCell(row, column) {
  448. return `[${row.name}]`;
  449. }
  450. }
  451. });
  452. setTimeout(_ => {
  453. const cells = toArray(vm.$el.querySelectorAll('.el-table__body-wrapper tbody tr td:first-child'));
  454. expect(cells.map(n => n.textContent)).to.eql(getTestData().map(o => `[${o.name}]`));
  455. destroyVM(vm);
  456. done();
  457. }, DELAY);
  458. });
  459. it('show-overflow-tooltip', done => {
  460. const vm = createTable('show-overflow-tooltip');
  461. setTimeout(_ => {
  462. expect(vm.$el.querySelectorAll('.el-tooltip')).to.length(5);
  463. destroyVM(vm);
  464. done();
  465. }, DELAY);
  466. });
  467. it('show-tooltip-when-overflow', done => { // old version prop name
  468. const vm = createTable('show-tooltip-when-overflow');
  469. setTimeout(_ => {
  470. expect(vm.$el.querySelectorAll('.el-tooltip')).to.length(5);
  471. destroyVM(vm);
  472. done();
  473. }, DELAY);
  474. });
  475. it('inline-template', done => {
  476. const vm = createVue({
  477. template: `
  478. <el-table :data="testData">
  479. <el-table-column prop="name" inline-template>
  480. <span>[{{ row.name }}]</span>
  481. </el-table-column>
  482. <el-table-column prop="release"/>
  483. <el-table-column prop="director"/>
  484. <el-table-column prop="runtime"/>
  485. </el-table>
  486. `,
  487. created() {
  488. this.testData = getTestData();
  489. }
  490. });
  491. setTimeout(_ => {
  492. const cells = toArray(vm.$el.querySelectorAll('.el-table__body-wrapper tbody tr td:first-child'));
  493. expect(cells.map(n => n.textContent)).to.eql(getTestData().map(o => `[${o.name}]`));
  494. destroyVM(vm);
  495. done();
  496. }, DELAY);
  497. });
  498. it('render-header', done => {
  499. const vm = createVue({
  500. template: `
  501. <el-table :data="testData">
  502. <el-table-column prop="name" :render-header="renderHeader" label="name">
  503. </el-table-column>
  504. <el-table-column prop="release"/>
  505. <el-table-column prop="director"/>
  506. <el-table-column prop="runtime"/>
  507. </el-table>
  508. `,
  509. methods: {
  510. renderHeader(h, { column, $index }) {
  511. return '' + $index + ':' + column.label;
  512. }
  513. },
  514. created() {
  515. this.testData = getTestData();
  516. }
  517. });
  518. setTimeout(_ => {
  519. const headerCell = vm.$el.querySelector('.el-table__header-wrapper thead tr th:first-child .cell');
  520. expect(headerCell.textContent).to.equal('0:name');
  521. destroyVM(vm);
  522. done();
  523. }, DELAY);
  524. });
  525. it('align', done => {
  526. const vm = createTable('align="left"', 'align="right"', 'align="center"');
  527. setTimeout(_ => {
  528. var len = getTestData().length + 1;
  529. expect(vm.$el.querySelectorAll('.is-left')).to.length(len);
  530. expect(vm.$el.querySelectorAll('.is-right')).to.length(len);
  531. expect(vm.$el.querySelectorAll('.is-center')).to.length(len);
  532. destroyVM(vm);
  533. done();
  534. }, DELAY);
  535. });
  536. it('class-name', done => {
  537. const vm = createTable('class-name="column-1"', 'class-name="column-2 column-class-a"', 'class-name="column-class-a"');
  538. setTimeout(_ => {
  539. var len = getTestData().length + 1;
  540. expect(vm.$el.querySelectorAll('.column-1')).to.length(len);
  541. expect(vm.$el.querySelectorAll('.column-2')).to.length(len);
  542. expect(vm.$el.querySelectorAll('.column-class-a')).to.length(len * 2);
  543. destroyVM(vm);
  544. done();
  545. }, DELAY);
  546. });
  547. it('selectable', done => {
  548. const vm = createVue({
  549. template: `
  550. <el-table :data="testData" @selection-change="change">
  551. <el-table-column type="selection" :selectable="filterSelect" />
  552. <el-table-column prop="name" label="name" />
  553. <el-table-column prop="release" label="release" />
  554. <el-table-column prop="director" label="director" />
  555. <el-table-column prop="runtime" label="runtime" />
  556. </el-table>
  557. `,
  558. created() {
  559. this.testData = getTestData();
  560. },
  561. data() {
  562. return { selected: [] };
  563. },
  564. methods: {
  565. change(rows) {
  566. this.selected = rows;
  567. },
  568. filterSelect(row, index) {
  569. return index > 2;
  570. }
  571. }
  572. }, true);
  573. setTimeout(_ => {
  574. vm.$el.querySelector('.el-checkbox').click();
  575. setTimeout(_ => {
  576. expect(vm.selected).to.length(2);
  577. destroyVM(vm);
  578. done();
  579. }, DELAY);
  580. }, DELAY);
  581. });
  582. it('selectable === false & check selectAll status', done => {
  583. const vm = createVue({
  584. template: `
  585. <el-table :data="testData" @selection-change="change">
  586. <el-table-column type="selection" :selectable="filterSelect" />
  587. <el-table-column prop="name" label="name" />
  588. <el-table-column prop="release" label="release" />
  589. <el-table-column prop="director" label="director" />
  590. <el-table-column prop="runtime" label="runtime" />
  591. </el-table>
  592. `,
  593. created() {
  594. },
  595. data() {
  596. return { selected: [], testData: null };
  597. },
  598. methods: {
  599. change(rows) {
  600. this.selected = rows;
  601. },
  602. filterSelect(row, index) {
  603. return false;
  604. }
  605. }
  606. }, true);
  607. vm.testData = getTestData();
  608. setTimeout(_ => {
  609. expect(vm.$el.querySelector('.el-checkbox').__vue__.checked).to.be.false;
  610. setTimeout(_ => {
  611. expect(vm.selected).to.length(0);
  612. destroyVM(vm);
  613. done();
  614. }, DELAY);
  615. }, DELAY);
  616. });
  617. it('emit selection-change after row has been removed', done => {
  618. const vm = createVue({
  619. template: `
  620. <el-table :data="testData" @selection-change="change">
  621. <el-table-column type="selection" />
  622. <el-table-column prop="name" label="name" />
  623. <el-table-column prop="release" label="release" />
  624. <el-table-column prop="director" label="director" />
  625. <el-table-column prop="runtime" label="runtime" />
  626. </el-table>
  627. `,
  628. created() {
  629. this.testData = getTestData();
  630. },
  631. data() {
  632. return { selected: [], testData: null };
  633. },
  634. methods: {
  635. change(rows) {
  636. this.selected = rows;
  637. },
  638. filterSelect(row, index) {
  639. return index > 2;
  640. }
  641. }
  642. }, true);
  643. setTimeout(_ => {
  644. vm.$el.querySelector('.el-checkbox').click();
  645. setTimeout(_ => {
  646. expect(vm.selected).to.length(5);
  647. vm.testData.splice(0, 1);
  648. setTimeout(_ => {
  649. expect(vm.selected).to.length(4);
  650. destroyVM(vm);
  651. done();
  652. });
  653. }, DELAY);
  654. }, DELAY);
  655. });
  656. it('reserve-selection', done => {
  657. const getData = function(page = 0) {
  658. let id = 0;
  659. const rows = [];
  660. const row = () => {
  661. return {
  662. id: ++id + page * 10,
  663. date: new Date().getTime()
  664. };
  665. };
  666. let count = 10;
  667. while (--count) {
  668. rows.push(row());
  669. }
  670. return rows;
  671. };
  672. const vm = createVue({
  673. template: `
  674. <el-table ref="table" :row-key="rowKey" :data="testData" @selection-change="change">
  675. <el-table-column type="selection" reserve-selection />
  676. <el-table-column prop="id" label="id" />
  677. <el-table-column prop="date" label="date" />
  678. </el-table>
  679. `,
  680. created() {
  681. this.testData = getData();
  682. },
  683. data() {
  684. return { selected: [], testData: [] };
  685. },
  686. methods: {
  687. rowKey(row) {
  688. return row.id;
  689. },
  690. change(rows) {
  691. this.selected = rows;
  692. }
  693. }
  694. }, true);
  695. setTimeout(_ => {
  696. // click first
  697. vm.$el.querySelectorAll('.el-checkbox')[1].click();
  698. setTimeout(_ => {
  699. expect(vm.$el.querySelectorAll('.el-checkbox__inner.is-checked')).to.length(1);
  700. // go to second page
  701. vm.testData = getData(1);
  702. setTimeout(_ => {
  703. // expect no checked
  704. expect(vm.$el.querySelectorAll('.el-checkbox__inner.is-checked')).to.length(0);
  705. // click first checkbox
  706. vm.$el.querySelectorAll('.el-checkbox')[1].click();
  707. vm.$el.querySelectorAll('.el-checkbox')[2].click();
  708. setTimeout(_ => {
  709. // back first page
  710. vm.testData = getData();
  711. setTimeout(_ => {
  712. expect(vm.$el.querySelectorAll('.el-checkbox__inner.is-checked')).to.length(1);
  713. // clear
  714. vm.$refs.table.clearSelection();
  715. setTimeout(_ => {
  716. expect(vm.$el.querySelectorAll('.el-checkbox__inner.is-checked')).to.length(0);
  717. destroyVM(vm);
  718. done();
  719. }, DELAY);
  720. }, DELAY);
  721. }, DELAY);
  722. }, DELAY);
  723. }, DELAY);
  724. }, DELAY);
  725. });
  726. describe('type', () => {
  727. const createTable = function(type) {
  728. return createVue({
  729. template: `
  730. <el-table :data="testData" @selection-change="change">
  731. <el-table-column type="${type}" />
  732. <el-table-column prop="name" label="name" />
  733. <el-table-column prop="release" label="release" />
  734. <el-table-column prop="director" label="director" />
  735. <el-table-column prop="runtime" label="runtime" />
  736. </el-table>
  737. `,
  738. created() {
  739. this.testData = getTestData();
  740. },
  741. data() {
  742. return { selected: [] };
  743. },
  744. methods: {
  745. change(rows) {
  746. this.selected = rows;
  747. }
  748. }
  749. }, true);
  750. };
  751. describe('= selection', () => {
  752. const vm = createTable('selection');
  753. it('render', done => {
  754. setTimeout(_ => {
  755. expect(vm.$el.querySelectorAll('.el-checkbox')).to.length(getTestData().length + 1);
  756. done();
  757. }, DELAY);
  758. });
  759. it('select all', done => {
  760. vm.$el.querySelector('.el-checkbox').click();
  761. setTimeout(_ => {
  762. expect(vm.selected).to.length(getTestData().length);
  763. done();
  764. }, DELAY);
  765. });
  766. it('cancel all', done => {
  767. vm.$el.querySelector('.el-checkbox').click();
  768. setTimeout(_ => {
  769. expect(vm.selected).to.length(0);
  770. destroyVM(vm);
  771. done();
  772. }, DELAY);
  773. });
  774. it('select one', done => {
  775. const vm2 = createTable('selection');
  776. setTimeout(_ => {
  777. vm2.$el.querySelectorAll('.el-checkbox')[1].click();
  778. setTimeout(_ => {
  779. expect(vm2.selected).to.length(1);
  780. expect(vm2.selected[0].name).to.equal(getTestData()[0].name);
  781. destroyVM(vm2);
  782. done();
  783. }, DELAY);
  784. }, DELAY);
  785. });
  786. });
  787. describe('= index', () => {
  788. const vm = createTable('index');
  789. it('render', done => {
  790. setTimeout(_ => {
  791. expect(toArray(vm.$el.querySelectorAll('.el-table__body-wrapper tbody tr td:first-child'))
  792. .map(node => node.textContent)).to.eql(['1', '2', '3', '4', '5']);
  793. destroyVM(vm);
  794. done();
  795. }, DELAY);
  796. });
  797. });
  798. });
  799. describe('sortable', () => {
  800. it('render', done => {
  801. const vm = createTable('', '', '', 'sortable');
  802. setTimeout(_ => {
  803. expect(vm.$el.querySelectorAll('.caret-wrapper')).to.length(1);
  804. destroyVM(vm);
  805. done();
  806. }, DELAY);
  807. });
  808. it('sortable method', done => {
  809. const vm = createTable(
  810. 'sortable :sort-method="sortMethod"', '', '', '', {
  811. methods: {
  812. sortMethod(a, b) {
  813. return a.runtime < b.runtime;
  814. }
  815. }
  816. });
  817. setTimeout(_ => {
  818. const elm = vm.$el.querySelector('.caret-wrapper');
  819. elm.click();
  820. setTimeout(_ => {
  821. const lastCells = vm.$el.querySelectorAll('.el-table__body-wrapper tbody tr td:last-child');
  822. expect(toArray(lastCells).map(node => node.textContent)).to.eql(['100', '95', '92', '92', '80']);
  823. destroyVM(vm);
  824. done();
  825. }, DELAY);
  826. }, DELAY);
  827. });
  828. it('sort-change', done => {
  829. let result;
  830. const vm = createTable('sortable="custom"', '', '', '', {
  831. methods: {
  832. sortChange(...args) {
  833. result = args;
  834. }
  835. }
  836. }, '@sort-change="sortChange"');
  837. setTimeout(_ => {
  838. const elm = vm.$el.querySelector('.caret-wrapper');
  839. elm.click();
  840. setTimeout(_ => {
  841. expect(result).to.exist;
  842. destroyVM(vm);
  843. done();
  844. }, DELAY);
  845. }, DELAY);
  846. });
  847. });
  848. describe('click sortable column', () => {
  849. const vm = createTable('', '', '', 'sortable');
  850. it('ascending', done => {
  851. const elm = vm.$el.querySelector('.caret-wrapper');
  852. elm.click();
  853. setTimeout(_ => {
  854. const lastCells = vm.$el.querySelectorAll('.el-table__body-wrapper tbody tr td:last-child');
  855. expect(toArray(lastCells).map(node => node.textContent))
  856. .to.eql(['80', '92', '92', '95', '100']);
  857. done();
  858. }, DELAY);
  859. });
  860. it('descending', done => {
  861. const elm = vm.$el.querySelector('.caret-wrapper');
  862. elm.click();
  863. setTimeout(_ => {
  864. const lastCells = vm.$el.querySelectorAll('.el-table__body-wrapper tbody tr td:last-child');
  865. expect(toArray(lastCells).map(node => node.textContent))
  866. .to.eql(['100', '95', '92', '92', '80']);
  867. destroyVM(vm);
  868. done();
  869. }, DELAY);
  870. });
  871. });
  872. });
  873. describe('multi level column', () => {
  874. it('should works', done => {
  875. const vm = createVue({
  876. template: `
  877. <el-table :data="testData">
  878. <el-table-column prop="name" />
  879. <el-table-column label="group">
  880. <el-table-column prop="release"/>
  881. <el-table-column prop="director"/>
  882. </el-table-column>
  883. <el-table-column prop="runtime"/>
  884. </el-table>
  885. `,
  886. created() {
  887. this.testData = null;
  888. }
  889. }, true);
  890. setTimeout(_ => {
  891. const trs = vm.$el.querySelectorAll('.el-table__header tr');
  892. expect(trs.length).equal(2);
  893. const firstRowHeader = trs[0].querySelectorAll('th .cell').length;
  894. const secondRowHeader = trs[1].querySelectorAll('th .cell').length;
  895. expect(firstRowHeader).to.equal(3);
  896. expect(secondRowHeader).to.equal(2);
  897. expect(trs[0].querySelector('th:first-child').getAttribute('rowspan')).to.equal('2');
  898. expect(trs[0].querySelector('th:nth-child(2)').getAttribute('colspan')).to.equal('2');
  899. destroyVM(vm);
  900. done();
  901. }, DELAY);
  902. });
  903. it('should works', done => {
  904. const vm = createVue({
  905. template: `
  906. <el-table :data="testData">
  907. <el-table-column prop="name" />
  908. <el-table-column label="group">
  909. <el-table-column label="group's group">
  910. <el-table-column prop="release" />
  911. <el-table-column prop="runtime"/>
  912. </el-table-column>
  913. <el-table-column prop="director" />
  914. </el-table-column>
  915. <el-table-column prop="runtime"/>
  916. </el-table>
  917. `,
  918. created() {
  919. this.testData = null;
  920. }
  921. }, true);
  922. setTimeout(_ => {
  923. const trs = vm.$el.querySelectorAll('.el-table__header tr');
  924. expect(trs.length).equal(3);
  925. const firstRowHeader = trs[0].querySelectorAll('th .cell').length;
  926. const secondRowHeader = trs[1].querySelectorAll('th .cell').length;
  927. const thirdRowHeader = trs[2].querySelectorAll('th .cell').length;
  928. expect(firstRowHeader).to.equal(3);
  929. expect(secondRowHeader).to.equal(2);
  930. expect(thirdRowHeader).to.equal(2);
  931. expect(trs[0].querySelector('th:first-child').getAttribute('rowspan')).to.equal('3');
  932. expect(trs[0].querySelector('th:nth-child(2)').getAttribute('colspan')).to.equal('3');
  933. expect(trs[1].querySelector('th:first-child').getAttribute('colspan')).to.equal('2');
  934. expect(trs[1].querySelector('th:nth-child(2)').getAttribute('rowspan')).to.equal('2');
  935. destroyVM(vm);
  936. done();
  937. }, DELAY);
  938. });
  939. it('should work in one column', done => {
  940. const vm = createVue({
  941. template: `
  942. <el-table :data="testData">
  943. <el-table-column label="group">
  944. <el-table-column prop="release"/>
  945. </el-table-column>
  946. </el-table>
  947. `,
  948. created() {
  949. this.testData = null;
  950. }
  951. }, true);
  952. setTimeout(_ => {
  953. const trs = vm.$el.querySelectorAll('.el-table__header tr');
  954. expect(trs.length).equal(2);
  955. const firstRowLength = trs[0].querySelectorAll('th .cell').length;
  956. const secondRowLength = trs[1].querySelectorAll('th .cell').length;
  957. expect(firstRowLength).to.equal(1);
  958. expect(secondRowLength).to.equal(1);
  959. expect(trs[0].querySelector('th:first-child').getAttribute('rowspan')).to.equal('1');
  960. expect(trs[0].querySelector('th:first-child').getAttribute('colspan')).to.equal('1');
  961. destroyVM(vm);
  962. done();
  963. }, DELAY);
  964. });
  965. });
  966. describe('dynamic column attribtes', () => {
  967. const DELAY = 50;
  968. it('label', (done) => {
  969. const vm = createVue({
  970. template: `
  971. <el-table :data="testData">
  972. <el-table-column prop="name" :label="label"/>
  973. <el-table-column prop="release" />
  974. <el-table-column prop="director" />
  975. <el-table-column prop="runtime" />
  976. </el-table>
  977. `,
  978. data() {
  979. return {
  980. label: 'name'
  981. };
  982. },
  983. created() {
  984. this.testData = getTestData();
  985. }
  986. }, true);
  987. setTimeout(() => {
  988. expect(vm.$el.querySelector('.el-table__header th .cell').textContent).to.equal('name');
  989. vm.label = 'NAME';
  990. vm.$nextTick(() => {
  991. expect(vm.$el.querySelector('.el-table__header th .cell').textContent).to.equal('NAME');
  992. });
  993. done();
  994. }, DELAY);
  995. });
  996. it('align', (done) => {
  997. const vm = createVue({
  998. template: `
  999. <el-table :data="testData">
  1000. <el-table-column prop="name" :align="align"/>
  1001. </el-table>
  1002. `,
  1003. data() {
  1004. return {
  1005. align: 'left'
  1006. };
  1007. },
  1008. created() {
  1009. this.testData = getTestData();
  1010. }
  1011. }, true);
  1012. setTimeout(() => {
  1013. expect(vm.$el.querySelectorAll('.el-table__body td.is-right').length === 0).to.be.true;
  1014. vm.align = 'right';
  1015. vm.$nextTick(() => {
  1016. expect(vm.$el.querySelectorAll('.el-table__body td.is-right').length > 0).to.be.true;
  1017. });
  1018. done();
  1019. }, DELAY);
  1020. });
  1021. it('width', (done) => {
  1022. const vm = createVue({
  1023. template: `
  1024. <el-table :data="testData" :fit="false">
  1025. <el-table-column prop="name" :width="width"/>
  1026. </el-table>
  1027. `,
  1028. data() {
  1029. return {
  1030. width: 100
  1031. };
  1032. },
  1033. created() {
  1034. this.testData = getTestData();
  1035. }
  1036. }, true);
  1037. setTimeout(() => {
  1038. expect(vm.$el.querySelector('.el-table__body col').getAttribute('width')).to.equal('100');
  1039. vm.width = 200;
  1040. vm.$nextTick(() => {
  1041. expect(vm.$el.querySelector('.el-table__body col').getAttribute('width')).to.equal('200');
  1042. });
  1043. done();
  1044. }, DELAY);
  1045. });
  1046. it('min-width', (done) => {
  1047. const vm = createVue({
  1048. template: `
  1049. <el-table :data="testData" :fit="false">
  1050. <el-table-column prop="name" :min-width="width"/>
  1051. </el-table>
  1052. `,
  1053. data() {
  1054. return {
  1055. width: 100
  1056. };
  1057. },
  1058. created() {
  1059. this.testData = getTestData();
  1060. }
  1061. }, true);
  1062. setTimeout(() => {
  1063. expect(vm.$el.querySelector('.el-table__body col').getAttribute('width')).to.equal('100');
  1064. vm.width = 200;
  1065. vm.$nextTick(() => {
  1066. expect(vm.$el.querySelector('.el-table__body col').getAttribute('width')).to.equal('200');
  1067. });
  1068. done();
  1069. }, DELAY);
  1070. });
  1071. it('fixed', (done) => {
  1072. const vm = createVue({
  1073. template: `
  1074. <el-table :data="testData">
  1075. <el-table-column :fixed="fixed" />
  1076. <el-table-column prop="release" />
  1077. <el-table-column prop="director" />
  1078. <el-table-column prop="runtime" />
  1079. </el-table>
  1080. `,
  1081. data() {
  1082. return {
  1083. fixed: false
  1084. };
  1085. },
  1086. created() {
  1087. this.testData = getTestData();
  1088. }
  1089. }, true);
  1090. setTimeout(() => {
  1091. expect(!vm.$el.querySelector('.el-table__fixed')).to.be.true;
  1092. vm.fixed = true;
  1093. vm.$nextTick(() => {
  1094. expect(!!vm.$el.querySelector('.el-table__fixed')).to.be.true;
  1095. });
  1096. done();
  1097. }, DELAY);
  1098. });
  1099. it('prop', (done) => {
  1100. const vm = createVue({
  1101. template: `
  1102. <el-table :data="testData">
  1103. <el-table-column :prop="name" />
  1104. <el-table-column prop="release" />
  1105. <el-table-column prop="director" />
  1106. <el-table-column prop="runtime" />
  1107. </el-table>
  1108. `,
  1109. data() {
  1110. return {
  1111. prop: 'name'
  1112. };
  1113. },
  1114. created() {
  1115. this.testData = getTestData();
  1116. }
  1117. }, true);
  1118. setTimeout(() => {
  1119. let firstColumnContent = vm.$el.querySelector('.el-table__body td .cell').textContent;
  1120. let secondColumnContent = vm.$el.querySelector('.el-table__body td:nth-child(2) .cell').textContent;
  1121. expect(firstColumnContent !== secondColumnContent).to.be.true;
  1122. vm.prop = 'release';
  1123. vm.property = 'release';
  1124. vm.$nextTick(() => {
  1125. firstColumnContent = vm.$el.querySelector('.el-table__body td .cell').textContent;
  1126. secondColumnContent = vm.$el.querySelector('.el-table__body td:nth-child(2) .cell').textContent;
  1127. expect(firstColumnContent === secondColumnContent).to.be.true;
  1128. });
  1129. done();
  1130. }, DELAY);
  1131. });
  1132. });
  1133. describe('methods', () => {
  1134. const createTable = function(prop = '', opts) {
  1135. return createVue({
  1136. template: `
  1137. <el-table ref="table" :data="testData" @${prop}="handleEvent">
  1138. <el-table-column type="selection" />
  1139. <el-table-column prop="name" />
  1140. <el-table-column prop="release" />
  1141. <el-table-column prop="director" />
  1142. <el-table-column prop="runtime"/>
  1143. </el-table>
  1144. `,
  1145. methods: {
  1146. handleEvent(selection) {
  1147. this.fireCount++;
  1148. this.selection = selection;
  1149. }
  1150. },
  1151. created() {
  1152. this.testData = getTestData();
  1153. },
  1154. data() {
  1155. return { selection: null, testData: this.testData, fireCount: 0 };
  1156. }
  1157. }, true);
  1158. };
  1159. it('toggleRowSelection', () => {
  1160. const vm = createTable('selection-change');
  1161. vm.$refs.table.toggleRowSelection(vm.testData[0]);
  1162. expect(vm.selection).to.length(1);
  1163. expect(vm.fireCount).to.equal(1);
  1164. // test use second parameter
  1165. vm.$refs.table.toggleRowSelection(vm.testData[0], true);
  1166. expect(vm.fireCount).to.equal(1);
  1167. vm.$refs.table.toggleRowSelection(vm.testData[0], false);
  1168. expect(vm.fireCount).to.equal(2);
  1169. expect(vm.selection).to.length(0);
  1170. destroyVM(vm);
  1171. });
  1172. it('clearSelection', () => {
  1173. const vm = createTable('selection-change');
  1174. vm.$refs.table.toggleRowSelection(vm.testData[0]);
  1175. expect(vm.selection).to.length(1);
  1176. expect(vm.fireCount).to.equal(1);
  1177. // clear selection
  1178. vm.$refs.table.clearSelection();
  1179. expect(vm.fireCount).to.equal(2);
  1180. expect(vm.selection).to.length(0);
  1181. vm.$refs.table.clearSelection();
  1182. expect(vm.fireCount).to.equal(2);
  1183. destroyVM(vm);
  1184. });
  1185. });
  1186. it('hover', done => {
  1187. const vm = createVue({
  1188. template: `
  1189. <el-table :data="testData">
  1190. <el-table-column prop="name" label="片名" fixed />
  1191. <el-table-column prop="release" label="发行日期" />
  1192. <el-table-column prop="director" label="导演" />
  1193. <el-table-column prop="runtime" label="时长(分)" />
  1194. </el-table>
  1195. `,
  1196. created() {
  1197. this.testData = getTestData();
  1198. }
  1199. }, true);
  1200. setTimeout(_ => {
  1201. const tr = vm.$el.querySelector('.el-table__body-wrapper tbody tr');
  1202. triggerEvent(tr, 'mouseenter', true, false);
  1203. setTimeout(_ => {
  1204. expect(tr.classList.contains('hover-row')).to.true;
  1205. triggerEvent(tr, 'mouseleave', true, false);
  1206. setTimeout(_ => {
  1207. expect(tr.classList.contains('hover-row')).to.false;
  1208. destroyVM(vm);
  1209. done();
  1210. }, DELAY);
  1211. }, DELAY);
  1212. }, DELAY);
  1213. });
  1214. it('highlight-current-row', done => {
  1215. const vm = createVue({
  1216. template: `
  1217. <el-table :data="testData" highlight-current-row>
  1218. <el-table-column prop="name" label="片名" />
  1219. <el-table-column prop="release" label="发行日期" />
  1220. <el-table-column prop="director" label="导演" />
  1221. <el-table-column prop="runtime" label="时长(分)" />
  1222. </el-table>
  1223. `,
  1224. created() {
  1225. this.testData = getTestData();
  1226. }
  1227. }, true);
  1228. setTimeout(_ => {
  1229. const tr = vm.$el.querySelector('.el-table__body-wrapper tbody tr');
  1230. triggerEvent(tr, 'click', true, false);
  1231. setTimeout(_ => {
  1232. expect(tr.classList.contains('current-row')).to.be.true;
  1233. const rows = vm.$el.querySelectorAll('.el-table__body-wrapper tbody tr');
  1234. triggerEvent(rows[2], 'click', true, false);
  1235. setTimeout(_ => {
  1236. expect(tr.classList.contains('current-row')).to.be.false;
  1237. expect(rows[2].classList.contains('current-row')).to.be.true;
  1238. destroyVM(vm);
  1239. done();
  1240. }, DELAY);
  1241. }, DELAY);
  1242. }, DELAY);
  1243. });
  1244. });