table-column.test.ts 37 KB

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