Pārlūkot izejas kodu

Merge pull request #690 from QingWei-Li/test/imporve-table

Table: add filter test
杨奕 8 gadi atpakaļ
vecāks
revīzija
7f7398d2f0

+ 1 - 0
README.md

@@ -1,5 +1,6 @@
 # Element
 [![Build Status](https://travis-ci.org/ElemeFE/element.svg?branch=master)](https://travis-ci.org/ElemeFE/element)
+[![Coverage Status](https://coveralls.io/repos/github/ElemeFE/element/badge.svg?branch=master)](https://coveralls.io/github/ElemeFE/element?branch=master)
 [![npm package](https://img.shields.io/npm/v/element-ui.svg)](https://www.npmjs.org/package/element-ui)
 [![NPM downloads](http://img.shields.io/npm/dm/element-ui.svg)](https://npmjs.org/package/element-ui)
 ![JS gzip size](http://img.badgesize.io/https://unpkg.com/element-ui@next/lib/index.js?compression=gzip&label=gzip%20size:%20JS)

+ 2 - 2
examples/docs/zh-cn/table.md

@@ -822,7 +822,7 @@
 
 对表格进行筛选,可快速查找到自己想看的数据。
 
-:::demo 在列中设置`filters``filter-method`属性即可开启该列的筛选,filters 是一个数组,`filter-method`是一个方法,它用于决定某些数据是否显示,会传入两个参数:`value`和`row`。
+:::demo 在列中设置`filters` `filter-method`属性即可开启该列的筛选,filters 是一个数组,`filter-method`是一个方法,它用于决定某些数据是否显示,会传入两个参数:`value`和`row`。
 ```html
 <template>
   <el-table
@@ -945,4 +945,4 @@
 | filters | 数据过滤的选项,数组格式,数组中的元素需要有 text 和 value 属性。 | Array[{ text, value }] | — | — |
 | filter-multiple | 数据过滤的选项是否多选 | Boolean | — | true |
 | filter-method | 数据过滤使用的方法,如果是多选的筛选项,对每一条数据会执行多次,任意一次返回 true 就会显示。 | Function(value, row) | — | — |
-| filteredValue | 选中的数据过滤项,如果需要自定义表头过滤的渲染方式,可能会需要此属性。 | Array | — | — |
+| filtered-value | 选中的数据过滤项,如果需要自定义表头过滤的渲染方式,可能会需要此属性。 | Array | — | — |

+ 1 - 1
packages/table/src/filter-panel.vue

@@ -30,7 +30,7 @@
   </transition>
 </template>
 
-<script type="text/jsx">
+<script type="text/babel">
   import Popper from 'element-ui/src/utils/vue-popper';
   import Locale from 'element-ui/src/mixins/locale';
   import Clickoutside from 'element-ui/src/utils/clickoutside';

+ 1 - 0
packages/table/src/table-header.js

@@ -163,6 +163,7 @@ export default {
     },
 
     handleMouseDown(event, column) {
+      /* istanbul ignore if */
       if (this.draggingColumn && this.border) {
         this.dragging = true;
 

+ 1 - 1
test/unit/index.js

@@ -4,7 +4,7 @@ Function.prototype.bind = require('function-bind');
 require('packages/theme-default/src/index.css');
 
 // require all test files (files that ends with .spec.js)
-const testsContext = require.context('./specs', true, /\.spec$/);
+const testsContext = require.context('./specs', true, /table\.spec$/);
 testsContext.keys().forEach(testsContext);
 
 // require all src files except main.js for coverage.

+ 249 - 38
test/unit/specs/table.spec.js

@@ -138,8 +138,103 @@ describe('Table', () => {
         done();
       }, DELAY);
     });
+  });
+
+  describe('filter', () => {
+    let vm;
+
+    beforeEach(done => {
+      vm = createVue({
+        template: `
+          <el-table ref="table" :data="testData">
+            <el-table-column prop="name" label="片名" />
+            <el-table-column prop="release" label="发行日期" />
+            <el-table-column
+              prop="director"
+              :filters="[
+                { text: 'John Lasseter', value: 'John Lasseter' },
+                { text: 'Peter Docter', value: 'Peter Docter' },
+                { text: 'Andrew Stanton', value: 'Andrew Stanton' }
+              ]"
+              :filter-method="filterMethod"
+              label="导演" />
+            <el-table-column prop="runtime" label="时长(分)" />
+          </el-table>
+        `,
+
+        created() {
+          this.testData = getTestData();
+        },
+
+        methods: {
+          filterMethod(value, row) {
+            return value === row.director;
+          }
+        }
+      }, true);
+
+      setTimeout(done, DELAY);
+    });
+
+    afterEach(() => destroyVM(vm));
+
+    it('render', () => {
+      expect(vm.$el.querySelector('.el-table__column-filter-trigger')).to.exist;
+    });
+
+    it('click dropdown', done => {
+      const btn = vm.$el.querySelector('.el-table__column-filter-trigger');
+      triggerEvent(btn, 'click', true, false);
+      setTimeout(_ => {
+        const filter = document.body.querySelector('.el-table-filter');
+        expect(filter).to.exist;
+        document.body.removeChild(filter);
+        done();
+      }, 100);
+    });
+
+    it('click filter', done => {
+      const btn = vm.$el.querySelector('.el-table__column-filter-trigger');
 
-    // TODO: row-key
+      triggerEvent(btn, 'click', true, false);
+      setTimeout(_ => {
+        const filter = document.body.querySelector('.el-table-filter');
+
+        // John Lasseter
+        triggerEvent(filter.querySelector('.el-checkbox'), 'click', true, false);
+        // confrim button
+        setTimeout(_ => {
+          triggerEvent(filter.querySelector('.el-table-filter__bottom button'), 'click', true, false);
+          setTimeout(_ => {
+            expect(vm.$el.querySelectorAll('.el-table__body-wrapper tbody tr')).to.length(3);
+            document.body.removeChild(filter);
+            done();
+          }, DELAY);
+        }, 100);
+      }, 100);
+    });
+
+    it('click reset', done => {
+      const btn = vm.$el.querySelector('.el-table__column-filter-trigger');
+
+      triggerEvent(btn, 'click', true, false);
+      setTimeout(_ => {
+        const filter = document.body.querySelector('.el-table-filter');
+
+        // John Lasseter
+        triggerEvent(filter.querySelector('.el-checkbox'), 'click', true, false);
+        setTimeout(_ => {
+          // reset button
+          triggerEvent(filter.querySelectorAll('.el-table-filter__bottom button')[1], 'click', true, false);
+          setTimeout(_ => {
+            expect(filter.querySelector('.el-table-filter__bottom button').classList.contains('is-disabled')).to.true;
+            document.body.removeChild(filter);
+            destroyVM(vm);
+            done();
+          }, DELAY);
+        }, 100);
+      }, 100);
+    });
   });
 
   describe('events', () => {
@@ -265,8 +360,6 @@ describe('Table', () => {
     });
   });
 
-  describe('methods', () => {});
-
   describe('column attributes', () => {
     const createTable = function(props1, props2, props3, props4, opts, tableProps) {
       return createVue(Object.assign({
@@ -327,7 +420,6 @@ describe('Table', () => {
       }, DELAY);
     });
 
-    // TODO
     it('resizable', done => {
       const vm = createTable(
         'resizable',
@@ -452,39 +544,83 @@ describe('Table', () => {
       }, DELAY);
     });
 
-    // TODO
-    // it('reserve-selection', done => {
-    //   const vm = createVue({
-    //     template: `
-    //       <el-table :data="testData" @selection-change="change">
-    //         <el-table-column type="selection" reserve-selection />
-    //         <el-table-column prop="name" label="片名" />
-    //         <el-table-column prop="release" label="release" />
-    //         <el-table-column prop="director" label="director" />
-    //         <el-table-column prop="runtime" label="runtime" />
-    //       </el-table>
-    //     `,
-
-    //     created() {
-    //       this.testData = getTestData();
-    //     },
-
-    //     data() {
-    //       return { selected: [] };
-    //     },
-
-    //     methods: {
-    //       change(rows) {
-    //         this.selected = rows;
-    //       }
-    //     }
-    //   }, true);
-
-    //   setTimeout(_ => {
-
-    //     done();
-    //   }, DELAY);
-    // });
+    it('reserve-selection', done => {
+      const getData = function(page = 0) {
+        let id = 0;
+        const rows = [];
+        const row = () => {
+          return {
+            id: ++id + page * 10,
+            date: new Date().getTime()
+          };
+        };
+        let count = 10;
+
+        while (--count) {
+          rows.push(row());
+        }
+        return rows;
+      };
+      const vm = createVue({
+        template: `
+          <el-table ref="table" :row-key="rowKey" :data="testData" @selection-change="change">
+            <el-table-column type="selection" reserve-selection />
+            <el-table-column prop="id" label="id" />
+            <el-table-column prop="date" label="date" />
+          </el-table>
+        `,
+
+        created() {
+          this.testData = getData();
+        },
+
+        data() {
+          return { selected: [], testData: [] };
+        },
+
+        methods: {
+          rowKey(row) {
+            return row.id;
+          },
+
+          change(rows) {
+            this.selected = rows;
+          }
+        }
+      }, true);
+
+      setTimeout(_ => {
+        // click first
+        vm.$el.querySelectorAll('.el-checkbox')[1].click();
+
+        setTimeout(_ => {
+          expect(vm.$el.querySelectorAll('.el-checkbox__inner.is-checked')).to.length(1);
+          // go to second page
+          vm.testData = getData(1);
+          setTimeout(_ => {
+             // expect no checked
+            expect(vm.$el.querySelectorAll('.el-checkbox__inner.is-checked')).to.length(0);
+            // click first checkbox
+            vm.$el.querySelectorAll('.el-checkbox')[1].click();
+            vm.$el.querySelectorAll('.el-checkbox')[2].click();
+            setTimeout(_ => {
+              // back first page
+              vm.testData = getData();
+              setTimeout(_ => {
+                expect(vm.$el.querySelectorAll('.el-checkbox__inner.is-checked')).to.length(1);
+                // clear
+                vm.$refs.table.clearSelection();
+                setTimeout(_ => {
+                  expect(vm.$el.querySelectorAll('.el-checkbox__inner.is-checked')).to.length(0);
+                  destroyVM(vm);
+                  done();
+                }, DELAY);
+              }, DELAY);
+            }, DELAY);
+          }, DELAY);
+        }, DELAY);
+      }, DELAY);
+    });
 
     describe('type', () => {
       const createTable = function(type) {
@@ -575,14 +711,59 @@ describe('Table', () => {
     });
 
     describe('sortable', () => {
-      const vm = createTable('', '', '', 'sortable');
 
       it('render', done => {
+        const vm = createTable('', '', '', 'sortable');
         setTimeout(_ => {
           expect(vm.$el.querySelectorAll('.caret-wrapper')).to.length(1);
+          destroyVM(vm);
           done();
         }, DELAY);
       });
+
+      it('sortable method', done => {
+        const vm = createTable(
+          'sortable :sort-method="sortMethod"', '', '', '', {
+            methods: {
+              sortMethod(a, b) {
+                return a.runtime < b.runtime;
+              }
+            }
+          });
+
+        setTimeout(_ => {
+          const elm = vm.$el.querySelector('.caret-wrapper');
+
+          elm.click();
+          setTimeout(_ => {
+            const lastCells = vm.$el.querySelectorAll('.el-table__body-wrapper tbody tr td:last-child');
+            expect(toArray(lastCells).map(node => node.textContent)).to.eql(['100', '95', '92', '92', '80']);
+            destroyVM(vm);
+            done();
+          }, DELAY);
+        }, DELAY);
+      });
+
+      it('sort-change', done => {
+        let result;
+        const vm = createTable('sortable="custom"', '', '', '', {
+          methods: {
+            sortChange(...args) {
+              result = args;
+            }
+          }
+        }, '@sort-change="sortChange"');
+        setTimeout(_ => {
+          const elm = vm.$el.querySelector('.caret-wrapper');
+
+          elm.click();
+          setTimeout(_ => {
+            expect(result).to.exist;
+            destroyVM(vm);
+            done();
+          }, DELAY);
+        }, DELAY);
+      });
     });
 
     describe('click sortable column', () => {
@@ -614,4 +795,34 @@ describe('Table', () => {
       });
     });
   });
+
+  it('hover', done => {
+    const vm = createVue({
+      template: `
+        <el-table :data="testData">
+          <el-table-column prop="name" label="片名" />
+          <el-table-column prop="release" label="发行日期" />
+          <el-table-column prop="director" label="导演" />
+          <el-table-column prop="runtime" label="时长(分)" />
+        </el-table>
+      `,
+
+      created() {
+        this.testData = getTestData();
+      }
+    }, true);
+    setTimeout(_ => {
+      const tr = vm.$el.querySelector('.el-table__body-wrapper tbody tr');
+      triggerEvent(tr, 'mouseenter', true, false);
+      setTimeout(_ => {
+        expect(tr.classList.contains('hover-row')).to.true;
+        triggerEvent(tr, 'mouseleave', true, false);
+        setTimeout(_ => {
+          expect(tr.classList.contains('hover-row')).to.false;
+          destroyVM(vm);
+          done();
+        }, DELAY);
+      }, DELAY);
+    }, DELAY);
+  });
 });

+ 3 - 3
test/unit/specs/time-picker.spec.js

@@ -202,7 +202,7 @@ describe('TimePicker(range)', () => {
   it('minTime < maxTime', done => {
     const vm2 = createTest(TimePicker, {
       isRange: true,
-      value: [new Date(2016, 9, 10, 21, 40), new Date(2016, 9, 10, 20, 40)]
+      value: [new Date(2016, 9, 10, 23, 40), new Date(2016, 9, 10, 10, 40)]
     }, true);
     const input = vm2.$el.querySelector('input');
 
@@ -210,10 +210,10 @@ describe('TimePicker(range)', () => {
     input.focus();
     input.blur();
     setTimeout(() => {
-      expect(vm2.picker.maxTime > vm2.picker.minTime).to.true;
+      expect(vm2.picker.maxTime >= vm2.picker.minTime).to.true;
       destroyVM(vm2);
       done();
-    }, 20);
+    }, 100);
   });
 
   it('click cancel button', done => {