This commit is contained in:
Ivan
2021-06-07 11:56:04 +08:00
commit c3c9fee2fb
1071 changed files with 195655 additions and 0 deletions

13
test/.eslintrc Normal file
View File

@@ -0,0 +1,13 @@
{
"env": {
"mocha": true,
"es6": true
},
"globals": {
"expect": true,
"sinon": true
},
"parserOptions": {
"ecmaVersion": 2017
}
}

10
test/ssr/require.test.js Normal file
View File

@@ -0,0 +1,10 @@
const path = require('path');
try {
process.env.VUE_ENV = 'server';
require(path.join(process.env.PWD, './lib/index'));
console.log('SSR require test PASS');
} catch (e) {
console.error('SSR require test error');
throw Error(e);
}

12
test/unit/index.js Normal file
View File

@@ -0,0 +1,12 @@
require('babel-regenerator-runtime'); // add regenerator support for async await
require('packages/theme-chalk/lib/index.css');
// require all test files (files that ends with .spec.js)
const testsContext = require.context('./specs', true, /\.spec$/);
testsContext.keys().forEach(testsContext);
// require all src files except main.js for coverage.
// you can also change this to match only the subset of files that
// you want coverage for.
const srcContext = require.context('../../src', true, /^\.\/(?!main(\.js)?$)/);
srcContext.keys().forEach(srcContext);

31
test/unit/karma.conf.js Normal file
View File

@@ -0,0 +1,31 @@
const webpackConfig = require('../../build/webpack.test');
module.exports = function(config) {
const configuration = {
browsers: ['ChromeHeadless'],
frameworks: ['mocha', 'sinon-chai'],
reporters: ['spec', 'coverage'],
files: ['./index.js'],
preprocessors: {
'./index.js': ['webpack', 'sourcemap']
},
webpack: webpackConfig,
webpackMiddleware: {
noInfo: true
},
coverageReporter: {
dir: './coverage',
reporters: [
{ type: 'lcov', subdir: '.' },
{ type: 'text-summary' }
]
},
client: {
mocha: {
timeout: 4000
}
}
};
config.set(configuration);
};

3
test/unit/mocks/uri.js Normal file
View File

@@ -0,0 +1,3 @@
export const IMAGE_SUCCESS = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAFmklEQVR4Xu2ba2wUVRTH/2cWtlaooFQwKpr4CkESTQBNUAkodGeaKFGD2u6WGPyAmmAEEZmpj1VhBghE/KKGBIztDIXAByWBnQ1oQREfARNiDDHiF1+ooBiksVt295hFiqSdxx3KdmcH5uv+z+3//O65c19TwgX+0AWePy4CuFgBISCQ3J6+DFLuVQKmg2k4gK3xuvwr6+9e+Xe57YViCCRttY1ALX2S/asIPLRB1jvLCSEUAFK2egKgYf0T5a6TxdhtmxqXfl8uCBUHMHfP4rqeE0OOeyS4w5T1hsgCmLNTvaWYp299EpxoyvpX5YBQ8QpotlvvkMBfeCbHvMpUjOejCSCjPSYROrySY/B+SzYmRRJA0tZWEfCcJwBGz81yvDZN6eL5hlDxIZCyta8BTPBLjIv5sVbjyp/8dEF/ryiAlL3kJkD6TsQ0STS5vWHZPhFtEE1FAYiUf28yBaZ7OpRle4IkJ6KtGIDZexfU1hyv/QXASBGjBeYpHYrxmYg2iKZiAFIZdSGIVouaLVJx0obE8v2ielFdRQA83pkemc/lDgE0StRopF6CSVuzCGgWTb6ku7T+aHztpLUng8SIaAe9ApJ265MEflvE3P8a/t2UjTHBYsTUgwqgKauOk4p0gAhxMXunVcwfmYpxX6AYQfGgAWjqTNdL3bndRDRe0NsZGYPXWLKxIGiciH5QAJye8r4UWfE5mWbCE1ZCXy+SUFBN2QEo2+fXjKK6zSDcH9Rcr55i0vj2mUsPnmu8V1xZAZxKXhq+G6A7z9U8Mx+zFOOKc433iysbgNKYj3XnNoHoXj8T3r/z+6ZsPDiwNtyjHQE07dTGSAU8QkX4LlSY6Ndh9UfWnT1Ht2QXjeZifC8INw7UOAMfE2MgB6NdhaFo65ih/+bkxRFAMqPuIaK7xM3zu6ZszO3Vt2S1CcwobXPD8TAfoZjU6LSb7AdgWmd6yLW5nqArrm5T1mtDC+A/Y3tNWe/XqY4VkLK1fwBcItp9DGZLNqQwA2DmgiUbQ0Hgs/NyBpBRD4PoqigBKOWSGxuv2XxruscXQNJWDxJoXJQAMPCnJev9XuouQ0D9PMjcXQ1DAIx9pqJP7tupLrOAZhMhEaUKAGOjqehNYgBsdSOBHo0UAOBlU9ZfFwOQUd8honmRAsA8y1SMrWIAbHUFgRZHCUCe6LqNiWU/igHIaCoR9KgAYMZRS9GvFF4Kp7LqU2B6KzoAeKulGLOEASRtrZkAK0IAVEsxlgsDaM6ojRLRtqgAIImntTcYu4UBpLKtU8D8aRQAMJD/uSZeu2t6Oi8MILldHU8SfRMFAG67wN7cHFeCcz5svaZ4koWvosO9FGbdlI1Wt850BNCSXTSMOX4iEhVAaDAT+o5AAEriVEYrgHBmj+8FI7QVwJzLjei+fPOUN0rnG46P66FoMqMdIUK9SBWEGIDvjZIrgFRGOyR6qBlWAMzQLEU3vDrRvQJsdR+BJlZzBYh8VuM1BHYSQehCMpwVwF1mwqjrewYotBk69RK0tS0AHq7eChC7UPEYAto6As6c9VfdLED8tJkwfL9DcH8J2upqgBZWbwXgalPWD/v59wCgvQTgNb8GSr+H7x3AB0zZuF3EuyuA5oz6jET0pkgjYQPAzEstxSh1oO/jVQFzALzn20IIK0CKFa5vm7niBxHvHgsh9QEQfSDSSP8KWDSaOe54GyvS3sA0vMuUjemibbgPgWzrVInZ8RChb+N9AQSdRkXNiul4qikbn4hp4f5/g7N3vDAiXpCOEcj/IwpG0VT02Nl/9NSOshjvGMinMaJJ9OqYeYulGLODxHkml7TVZ8GYT0Q3uDfKXQxaY8n6i06aZnvJDGKaB8JMAo0IYk5UW7r5BbAtNhRz22YYf4jGlXT+vRuktSrUXgRQhZ12Xi1f8BXwL38cy1+mrtJNAAAAAElFTkSuQmCC';
export const IMAGE_FAIL = 'data:image/png;base64,fail';

View File

@@ -0,0 +1,69 @@
import { createTest, createVue, destroyVM } from '../util';
import Alert from 'packages/alert';
describe('Alert', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', () => {
vm = createTest(Alert, {
title: 'test',
showIcon: true
}, true);
expect(vm.$el.querySelector('.el-alert__title').textContent).to.equal('test');
expect(vm.$el.classList.contains('el-alert--info')).to.true;
});
it('type', () => {
vm = createTest(Alert, {
title: 'test',
type: 'success',
showIcon: true
}, true);
expect(vm.$el.classList.contains('el-alert--success')).to.true;
});
it('description', () => {
vm = createTest(Alert, {
title: 'Dorne',
description: 'Unbowed, Unbent, Unbroken',
showIcon: true
}, true);
expect(vm.$el.querySelector('.el-alert__description').textContent)
.to.equal('Unbowed, Unbent, Unbroken');
});
it('theme', () => {
vm = createTest(Alert, {
title: 'test',
effect: 'dark'
}, true);
expect(vm.$el.classList.contains('is-dark')).to.true;
});
it('title slot', () => {
vm = createVue(`
<el-alert>
<span slot="title">foo</span>
</el-alert>
`);
expect(vm.$el.querySelector('.el-alert__title').textContent).to.equal('foo');
});
it('close', () => {
vm = createVue({
template: `
<div>
<el-alert
title="test"
close-text="close"></el-alert>
</div>
`
}, true);
vm.$el.querySelector('.el-alert__closebtn').click();
expect(vm.$children[0].visible).to.false;
});
});

View File

@@ -0,0 +1,623 @@
import { createVue, triggerClick, destroyVM, triggerKeyDown } from '../util';
describe('Autocomplete', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', done => {
vm = createVue({
template: `
<div>
<button class="btn">a</button>
<el-autocomplete
ref="autocomplete"
v-model="state"
:fetch-suggestions="querySearch"
placeholder="请输入内容autocomplete1"
></el-autocomplete>
</div>
`,
data() {
return {
restaurants: [],
state: ''
};
},
methods: {
querySearch(queryString, cb) {
var restaurants = this.restaurants;
var results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants;
cb(results);
},
createFilter(queryString) {
return (restaurant) => {
return (restaurant.value.indexOf(queryString.toLowerCase()) === 0);
};
},
loadAll() {
return [
{ 'value': '三全鲜食(北新泾店)', 'address': '长宁区新渔路144号' },
{ 'value': 'Hot honey 首尔炸鸡(仙霞路)', 'address': '上海市长宁区淞虹路661号' },
{ 'value': '新旺角茶餐厅', 'address': '上海市普陀区真北路988号创邑金沙谷6号楼113' },
{ 'value': '泷千家(天山西路店)', 'address': '天山西路438号' }
];
}
},
mounted() {
this.restaurants = this.loadAll();
}
}, true);
let elm = vm.$el;
let inputElm = elm.querySelector('input');
inputElm.focus();
expect(inputElm.getAttribute('placeholder')).to.be.equal('请输入内容autocomplete1');
setTimeout(_ => {
const suggestions = vm.$refs.autocomplete.$refs.suggestions.$el;
expect(suggestions.style.display).to.not.equal('none');
expect(suggestions.querySelectorAll('.el-autocomplete-suggestion__list li').length).to.be.equal(4);
triggerClick(document);
setTimeout(_ => {
expect(suggestions.style.display).to.be.equal('none');
done();
}, 500);
}, 500);
});
it('select', done => {
vm = createVue({
template: `
<el-autocomplete
v-model="state"
ref="autocomplete"
:fetch-suggestions="querySearch"
placeholder="请输入内容autocomplete2"
></el-autocomplete>
`,
data() {
return {
restaurants: [],
state: ''
};
},
methods: {
querySearch(queryString, cb) {
var restaurants = this.restaurants;
var results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants;
cb(results);
},
createFilter(queryString) {
return (restaurant) => {
return (restaurant.value.indexOf(queryString.toLowerCase()) === 0);
};
},
loadAll() {
return [
{ 'value': '三全鲜食(北新泾店)', 'address': '长宁区新渔路144号' },
{ 'value': 'Hot honey 首尔炸鸡(仙霞路)', 'address': '上海市长宁区淞虹路661号' },
{ 'value': '新旺角茶餐厅', 'address': '上海市普陀区真北路988号创邑金沙谷6号楼113' },
{ 'value': '泷千家(天山西路店)', 'address': '天山西路438号' }
];
}
},
mounted() {
this.restaurants = this.loadAll();
}
}, true);
const autocomplete = vm.$refs.autocomplete;
const elm = vm.$el;
const inputElm = elm.querySelector('input');
const spy = sinon.spy();
autocomplete.$on('select', spy);
inputElm.focus();
setTimeout(_ => {
const suggestions = autocomplete.$refs.suggestions.$el;
const suggestionList = suggestions.querySelectorAll('.el-autocomplete-suggestion__list li');
suggestionList[1].click();
setTimeout(_ => {
expect(inputElm.value).to.be.equal('Hot honey 首尔炸鸡(仙霞路)');
expect(vm.state).to.be.equal('Hot honey 首尔炸鸡(仙霞路)');
expect(spy.withArgs().calledOnce).to.be.true;
expect(suggestions.style.display).to.be.equal('none');
done();
}, 500);
}, 500);
});
it('input', done => {
vm = createVue({
template: `
<el-autocomplete
ref="autocomplete"
v-model="state"
:trigger-on-focus="false"
:fetch-suggestions="querySearch"
></el-autocomplete>
`,
data() {
return {
restaurants: [],
state: ''
};
},
methods: {
querySearch(queryString, cb) {
var restaurants = this.restaurants;
var results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants;
cb(results);
},
createFilter(queryString) {
return (restaurant) => {
return (restaurant.value.indexOf(queryString.toLowerCase()) === 0);
};
},
loadAll() {
return [
{ 'value': '三全鲜食(北新泾店)', 'address': '长宁区新渔路144号' },
{ 'value': 'Hot honey 首尔炸鸡(仙霞路)', 'address': '上海市长宁区淞虹路661号' },
{ 'value': '新旺角茶餐厅', 'address': '上海市普陀区真北路988号创邑金沙谷6号楼113' },
{ 'value': '泷千家(天山西路店)', 'address': '天山西路438号' }
];
}
},
mounted() {
this.restaurants = this.loadAll();
}
}, true);
const autocomplete = vm.$refs.autocomplete;
const input = autocomplete.$refs.input;
input.$emit('input', '三');
setTimeout(() => {
expect(vm.state).to.be.equal('三');
expect(autocomplete.suggestions[0].value).to.be.equal('三全鲜食(北新泾店)');
input.$emit('input', '');
setTimeout(() => {
expect(vm.state).to.be.equal('');
expect(autocomplete.suggestions.length).to.be.equal(0);
done();
}, 500);
}, 500);
});
describe('enter select', () => {
const createVm = (selectWhenUnmatched = false) => {
return createVue({
template: `
<el-autocomplete
ref="autocomplete"
v-model="state"
@select="handleSelect"
:trigger-on-focus="false"
:select-when-unmatched="selectWhenUnmatched"
:fetch-suggestions="querySearch"
></el-autocomplete>
`,
data() {
return {
restaurants: [],
state: '',
selectWhenUnmatched: selectWhenUnmatched,
item: {}
};
},
methods: {
querySearch(queryString, cb) {
var restaurants = this.restaurants;
var results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants;
cb(results);
},
createFilter(queryString) {
return (restaurant) => {
return (restaurant.value.indexOf(queryString.toLowerCase()) === 0);
};
},
loadAll() {
return [
{ 'value': '三全鲜食(北新泾店)', 'address': '长宁区新渔路144号' },
{ 'value': 'Hot honey 首尔炸鸡(仙霞路)', 'address': '上海市长宁区淞虹路661号' },
{ 'value': '新旺角茶餐厅', 'address': '上海市普陀区真北路988号创邑金沙谷6号楼113' },
{ 'value': '泷千家(天山西路店)', 'address': '天山西路438号' }
];
},
handleSelect(item) {
this.item = item;
}
},
mounted() {
this.restaurants = this.loadAll();
}
}, true);
};
it('select', done => {
vm = createVm();
const autocomplete = vm.$refs.autocomplete;
const input = autocomplete.$refs.input;
input.$el.querySelector('input').focus();
input.$emit('input', '三');
setTimeout(() => {
triggerKeyDown(input.$el, 40); // down
setTimeout(() => {
triggerKeyDown(input.$el, 13); // enter
setTimeout(() => {
expect(vm.item.address).to.be.equal('长宁区新渔路144号');
done();
}, 200);
}, 200);
}, 500);
});
it('select unmatched', done => {
vm = createVm(true);
const autocomplete = vm.$refs.autocomplete;
const input = autocomplete.$refs.input;
input.$emit('input', '关键字');
setTimeout(() => {
expect(autocomplete.suggestions.length).to.be.equal(0);
triggerKeyDown(input.$el, 13); // enter
setTimeout(() => {
expect(autocomplete.highlightedIndex).to.be.equal(-1);
expect(vm.item.value).to.be.equal('关键字');
done();
}, 500);
}, 500);
});
});
it('props', done => {
vm = createVue({
template: `
<el-autocomplete
v-model="state"
ref="autocomplete"
value-key="address"
:fetch-suggestions="querySearch"
placeholder="请输入内容autocomplete2"
></el-autocomplete>
`,
data() {
return {
restaurants: [],
state: ''
};
},
methods: {
querySearch(queryString, cb) {
var restaurants = this.restaurants;
var results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants;
cb(results);
},
createFilter(queryString) {
return (restaurant) => {
return (restaurant.value.indexOf(queryString.toLowerCase()) === 0);
};
},
loadAll() {
return [
{ 'name': '三全鲜食(北新泾店)', 'address': '长宁区新渔路144号' },
{ 'name': 'Hot honey 首尔炸鸡(仙霞路)', 'address': '上海市长宁区淞虹路661号' },
{ 'name': '新旺角茶餐厅', 'address': '上海市普陀区真北路988号创邑金沙谷6号楼113' },
{ 'name': '泷千家(天山西路店)', 'address': '天山西路438号' }
];
}
},
mounted() {
this.restaurants = this.loadAll();
}
}, true);
const autocomplete = vm.$refs.autocomplete;
const elm = vm.$el;
const inputElm = elm.querySelector('input');
const spy = sinon.spy();
autocomplete.$on('select', spy);
inputElm.focus();
setTimeout(_ => {
const suggestions = autocomplete.$refs.suggestions.$el;
const suggestionList = suggestions.querySelectorAll('.el-autocomplete-suggestion__list li');
expect(suggestionList[1].innerHTML === '上海市长宁区淞虹路661号');
suggestionList[1].click();
setTimeout(_ => {
expect(inputElm.value).to.be.equal('上海市长宁区淞虹路661号');
expect(vm.state).to.be.equal('上海市长宁区淞虹路661号');
expect(spy.withArgs().calledOnce).to.be.true;
expect(suggestions.style.display).to.be.equal('none');
done();
}, 500);
}, 500);
});
it('highlight', done => {
vm = createVue({
template: `
<el-autocomplete
ref="autocomplete"
v-model="state"
:fetch-suggestions="querySearch"
placeholder="请输入内容autocomplete3"
></el-autocomplete>
`,
data() {
return {
restaurants: [],
state: ''
};
},
methods: {
querySearch(queryString, cb) {
var restaurants = this.restaurants;
var results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants;
cb(results);
},
createFilter(queryString) {
return (restaurant) => {
return (restaurant.value.indexOf(queryString.toLowerCase()) === 0);
};
},
loadAll() {
return [
{ 'value': '三全鲜食(北新泾店)', 'address': '长宁区新渔路144号' },
{ 'value': 'Hot honey 首尔炸鸡(仙霞路)', 'address': '上海市长宁区淞虹路661号' },
{ 'value': '新旺角茶餐厅', 'address': '上海市普陀区真北路988号创邑金沙谷6号楼113' },
{ 'value': '泷千家(天山西路店)', 'address': '天山西路438号' },
{ 'value': '胖仙女纸杯蛋糕(上海凌空店)', 'address': '上海市长宁区金钟路968号1幢18号楼一层商铺18-101' },
{ 'value': '贡茶', 'address': '上海市长宁区金钟路633号' },
{ 'value': '豪大大香鸡排超级奶爸', 'address': '上海市嘉定区曹安公路曹安路1685号' },
{ 'value': '茶芝兰(奶茶,手抓饼)', 'address': '上海市普陀区同普路1435号' },
{ 'value': '十二泷町', 'address': '上海市北翟路1444弄81号B幢-107' },
{ 'value': '星移浓缩咖啡', 'address': '上海市嘉定区新郁路817号' },
{ 'value': '阿姨奶茶/豪大大', 'address': '嘉定区曹安路1611号' },
{ 'value': '新麦甜四季甜品炸鸡', 'address': '嘉定区曹安公路2383弄55号' },
{ 'value': 'Monica摩托主题咖啡店', 'address': '嘉定区江桥镇曹安公路2409号1F2383弄62号1F' },
{ 'value': '浮生若茶凌空soho店', 'address': '上海长宁区金钟路968号9号楼地下一层' },
{ 'value': 'NONO JUICE 鲜榨果汁', 'address': '上海市长宁区天山西路119号' },
{ 'value': 'CoCo都可(北新泾店)', 'address': '上海市长宁区仙霞西路' },
{ 'value': '快乐柠檬(神州智慧店)', 'address': '上海市长宁区天山西路567号1层R117号店铺' },
{ 'value': 'Merci Paul cafe', 'address': '上海市普陀区光复西路丹巴路28弄6号楼819' },
{ 'value': '猫山王(西郊百联店)', 'address': '上海市长宁区仙霞西路88号第一层G05-F01-1-306' },
{ 'value': '枪会山', 'address': '上海市普陀区棕榈路' },
{ 'value': '纵食', 'address': '元丰天山花园(东门) 双流路267号' },
{ 'value': '钱记', 'address': '上海市长宁区天山西路' }
];
}
},
mounted() {
this.restaurants = this.loadAll();
}
}, true);
const autocomplete = vm.$refs.autocomplete;
const inputElm = autocomplete.$el.querySelector('input');
inputElm.focus();
setTimeout(_ => {
autocomplete.highlight(8);
vm.$nextTick(_ => {
const suggestions = autocomplete.$refs.suggestions.$el.querySelector('.el-autocomplete-suggestion__wrap');
let suggestionsList = suggestions.querySelectorAll('.el-autocomplete-suggestion__list li');
let highlightedItem = suggestionsList[8];
expect(highlightedItem.classList.contains('highlighted')).to.be.true;
expect(suggestions.scrollTop === highlightedItem.scrollHeight).to.be.true;
done();
});
}, 500);
});
it('highlight out of bounds', done => {
vm = createVue({
template: `
<el-autocomplete
ref="autocomplete"
v-model="state"
:fetch-suggestions="querySearch"
placeholder="请输入内容autocomplete3"
></el-autocomplete>
`,
data() {
return {
restaurants: [],
state: ''
};
},
methods: {
querySearch(queryString, cb) {
var restaurants = this.restaurants;
var results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants;
cb(results);
},
createFilter(queryString) {
return (restaurant) => {
return (restaurant.value.indexOf(queryString.toLowerCase()) === 0);
};
},
loadAll() {
return [
{ 'value': '三全鲜食(北新泾店)', 'address': '长宁区新渔路144号' },
{ 'value': 'Hot honey 首尔炸鸡(仙霞路)', 'address': '上海市长宁区淞虹路661号' },
{ 'value': '新旺角茶餐厅', 'address': '上海市普陀区真北路988号创邑金沙谷6号楼113' },
{ 'value': '泷千家(天山西路店)', 'address': '天山西路438号' },
{ 'value': '胖仙女纸杯蛋糕(上海凌空店)', 'address': '上海市长宁区金钟路968号1幢18号楼一层商铺18-101' },
{ 'value': '贡茶', 'address': '上海市长宁区金钟路633号' },
{ 'value': '豪大大香鸡排超级奶爸', 'address': '上海市嘉定区曹安公路曹安路1685号' },
{ 'value': '茶芝兰(奶茶,手抓饼)', 'address': '上海市普陀区同普路1435号' },
{ 'value': '十二泷町', 'address': '上海市北翟路1444弄81号B幢-107' },
{ 'value': '星移浓缩咖啡', 'address': '上海市嘉定区新郁路817号' },
{ 'value': '阿姨奶茶/豪大大', 'address': '嘉定区曹安路1611号' },
{ 'value': '新麦甜四季甜品炸鸡', 'address': '嘉定区曹安公路2383弄55号' }
];
}
},
mounted() {
this.restaurants = this.loadAll();
}
}, true);
const autocomplete = vm.$refs.autocomplete;
let inputElm = vm.$el.querySelector('input');
inputElm.focus();
setTimeout(_ => {
autocomplete.highlight(15);
vm.$nextTick(_ => {
const suggestions = autocomplete.$refs.suggestions.$el;
const suggestionsList = suggestions.querySelectorAll('.el-autocomplete-suggestion__list li');
let highlightedItem = suggestionsList[11];
expect(highlightedItem.className).to.be.equal('highlighted');
done();
});
}, 500);
});
it('triggerOnFocus', done => {
vm = createVue({
template: `
<el-autocomplete
ref="autocomplete"
v-model="state"
:fetch-suggestions="querySearch"
:trigger-on-focus="false"
placeholder="请输入内容autocomplete1"
></el-autocomplete>
`,
data() {
return {
restaurants: [],
state: ''
};
},
methods: {
querySearch(queryString, cb) {
var restaurants = this.restaurants;
var results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants;
cb(results);
},
createFilter(queryString) {
return (restaurant) => {
return (restaurant.value.indexOf(queryString.toLowerCase()) === 0);
};
},
loadAll() {
return [
{ 'value': '三全鲜食(北新泾店)', 'address': '长宁区新渔路144号' },
{ 'value': 'Hot honey 首尔炸鸡(仙霞路)', 'address': '上海市长宁区淞虹路661号' },
{ 'value': '新旺角茶餐厅', 'address': '上海市普陀区真北路988号创邑金沙谷6号楼113' },
{ 'value': '泷千家(天山西路店)', 'address': '天山西路438号' }
];
}
},
mounted() {
this.restaurants = this.loadAll();
}
}, true);
let inputElm = vm.$el.querySelector('input');
inputElm.focus();
setTimeout(_ => {
let suggestions = vm.$refs.autocomplete.$refs.suggestions.$el;
expect(suggestions.style.display).to.be.equal('none');
done();
}, 500);
});
it('event:focus & blur', done => {
vm = createVue({
template: `
<el-autocomplete
ref="input"
v-model="state"
:fetch-suggestions="querySearch"
:trigger-on-focus="false"
placeholder="请输入内容autocomplete1"
></el-autocomplete>
`,
data() {
return {
restaurants: [],
state: ''
};
},
methods: {
querySearch(queryString, cb) {
var restaurants = this.restaurants;
var results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants;
cb(results);
},
createFilter(queryString) {
return (restaurant) => {
return (restaurant.value.indexOf(queryString.toLowerCase()) === 0);
};
},
loadAll() {
return [
{ 'value': '三全鲜食(北新泾店)', 'address': '长宁区新渔路144号' },
{ 'value': 'Hot honey 首尔炸鸡(仙霞路)', 'address': '上海市长宁区淞虹路661号' },
{ 'value': '新旺角茶餐厅', 'address': '上海市普陀区真北路988号创邑金沙谷6号楼113' },
{ 'value': '泷千家(天山西路店)', 'address': '天山西路438号' }
];
}
},
mounted() {
this.restaurants = this.loadAll();
}
}, true);
const spyFocus = sinon.spy();
const spyBlur = sinon.spy();
vm.$refs.input.$on('focus', spyFocus);
vm.$refs.input.$on('blur', spyBlur);
vm.$el.querySelector('input').focus();
vm.$el.querySelector('input').blur();
vm.$nextTick(_ => {
expect(spyFocus.calledOnce).to.be.true;
expect(spyBlur.calledOnce).to.be.true;
done();
});
});
it('can highlight first item', done => {
vm = createVue({
template: `
<el-autocomplete
ref="autocomplete"
v-model="state"
:fetch-suggestions="querySearch"
highlight-first-item
></el-autocomplete>
`,
data() {
return {
restaurants: [],
state: ''
};
},
methods: {
querySearch(queryString, cb) {
const opts = [
{ 'value': '1' },
{ 'value': '11' },
{ 'value': '2' },
{ 'value': '22' }
];
cb(
queryString
? opts.filter(opt => opt.value.indexOf(queryString) >= 0)
: opts
);
}
}
}, true);
let elm = vm.$el;
let inputElm = elm.querySelector('input');
inputElm.focus();
const autocomplete = vm.$refs.autocomplete;
const input = autocomplete.$refs.input;
input.$emit('input', '1');
setTimeout(_ => {
const suggestions = vm.$refs.autocomplete.$refs.suggestions.$el;
const items = suggestions.querySelectorAll('.el-autocomplete-suggestion__list li');
expect(items.length).to.equal(2);
expect(items[0].classList.contains('highlighted')).to.be.true;
done();
}, 500);
});
});

View File

@@ -0,0 +1,119 @@
import { createTest, createVue, destroyVM, wait } from '../util';
import Avatar from 'packages/avatar';
import { IMAGE_SUCCESS, IMAGE_FAIL } from '../mocks/uri';
describe('Avatar', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', () => {
vm = createTest(Avatar);
expect(vm.$el).to.exist;
});
it('size is number', () => {
vm = createVue({
template: `
<el-avatar :size="50">
</el-avatar>
`
}, true);
const avatarElm = vm.$el;
expect(avatarElm.style.height).to.equal('50px');
});
it('size is string', () => {
vm = createVue({
template: `
<el-avatar size="small">
user
</el-avatar>
`
}, true);
const avatarElm = vm.$el;
expect(avatarElm.classList.contains('el-avatar--small')).to.be.true;
});
it('shape', () => {
vm = createVue({
template: `
<el-avatar size="small" shape="square">
user
</el-avatar>
`
}, true);
const avatarElm = vm.$el;
expect(avatarElm.classList.contains('el-avatar--square')).to.be.true;
});
it('icon avatar', () => {
vm = createVue({
template: `
<el-avatar icon="el-icon-user-solid">
</el-avatar>
`
}, true);
const avatarElm = vm.$el;
const iconELm = avatarElm.children[0];
expect(avatarElm.classList.contains('el-avatar--icon')).to.be.true;
expect(iconELm.classList.contains('el-icon-user-solid')).to.be.true;
});
it('image avatar', () => {
vm = createVue({
template: `
<el-avatar src="${IMAGE_SUCCESS}"></el-avatar>
`
}, true);
const imgElm = vm.$el.children[0];
expect(imgElm.tagName.toUpperCase()).to.equal('IMG');
expect(imgElm.src).to.equal(IMAGE_SUCCESS);
});
it('image fallback', async() => {
vm = createVue({
template: `
<el-avatar src="${IMAGE_FAIL}" @error="errorHandler">
fallback
</el-avatar>
`,
methods: {
errorHandler() {
return true;
}
}
}, true);
await wait();
const avatarElm = vm.$el;
expect(avatarElm.textContent.trim()).to.equal('fallback');
});
it('image fit', async() => {
vm = createVue({
template: `
<div>
<el-avatar :src="url"></el-avatar>
<el-avatar :src="url" v-for="fit in fits" :fit="fit" :key="fit"></el-avatar>
</div>
`,
data() {
return {
fits: ['fill', 'contain', 'cover', 'none', 'scale-down'],
url: IMAGE_SUCCESS
};
}
}, true);
await wait();
const containerElm = vm.$el;
expect(containerElm.children[0].children[0].style.objectFit).to.equal('cover');
expect(containerElm.children[1].children[0].style.objectFit).to.equal('fill');
expect(containerElm.children[2].children[0].style.objectFit).to.equal('contain');
expect(containerElm.children[3].children[0].style.objectFit).to.equal('cover');
expect(containerElm.children[4].children[0].style.objectFit).to.equal('none');
expect(containerElm.children[5].children[0].style.objectFit).to.equal('scale-down');
});
});

View File

@@ -0,0 +1,28 @@
import { createVue, destroyVM, wait } from '../util';
describe('Backtop', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', async() => {
vm = createVue({
template: `
<div ref="scrollTarget" class="test-scroll" style="height: 100px; overflow: auto">
<div style="height: 10000px; width: 100%">
<el-backtop target=".test-scroll">
<span>test_up_text</span>
</el-backtop>
</div>
</div>
`
}, true);
expect(vm.$el).to.exist;
expect(vm.$el.innerText).to.be.equal('');
vm.$refs.scrollTarget.scrollTop = 2000;
await wait();
expect(vm.$el.innerText).to.be.equal('test_up_text');
});
});

View File

@@ -0,0 +1,41 @@
import { createTest, createVue, destroyVM } from '../util';
import Badge from 'packages/badge';
describe('Badge', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('value', () => {
vm = createTest(Badge, { value: 80 });
expect(vm.content).to.equal(80);
});
it('is fixed', () => {
vm = createVue(`
<el-badge>
<button>click</button>
</el-badge>
`);
expect(vm.$el.querySelector('.el-badge__content.is-fixed')).to.exist;
});
it('is dot', () => {
vm = createVue(`
<el-badge is-dot>
<button>click</button>
</el-badge>
`);
expect(vm.$el.querySelector('.el-badge__content.is-dot')).to.exist;
});
it('max', () => {
vm = createTest(Badge, { max: 100, value: 200 });
expect(vm.content).to.equal('100+');
vm = createTest(Badge, { max: 100, value: 80 });
expect(vm.content).to.equal(80);
});
});

View File

@@ -0,0 +1,23 @@
import { createVue, destroyVM } from '../util';
describe('Breadcrumb', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', done => {
vm = createVue(`
<el-breadcrumb separator=">">
<el-breadcrumb-item to="/">首页</el-breadcrumb-item>
<el-breadcrumb-item>活动管理</el-breadcrumb-item>
<el-breadcrumb-item>活动列表</el-breadcrumb-item>
<el-breadcrumb-item>活动详情</el-breadcrumb-item>
</el-breadcrumb>
`);
vm.$nextTick(_ => {
expect(vm.$el.querySelector('.el-breadcrumb__separator').innerText).to.equal('>');
done();
});
});
});

View File

@@ -0,0 +1,133 @@
import { createTest, createVue, destroyVM } from '../util';
import Button from 'packages/button';
describe('Button', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', () => {
vm = createTest(Button, {
type: 'primary'
}, true);
let buttonElm = vm.$el;
expect(buttonElm.classList.contains('el-button--primary')).to.be.true;
});
it('icon', () => {
vm = createTest(Button, {
icon: 'el-icon-search'
}, true);
let buttonElm = vm.$el;
expect(buttonElm.querySelector('.el-icon-search')).to.be.ok;
});
it('nativeType', () => {
vm = createTest(Button, {
nativeType: 'submit'
}, true);
let buttonElm = vm.$el;
expect(buttonElm.getAttribute('type')).to.be.equal('submit');
});
it('loading', () => {
vm = createTest(Button, {
loading: true
}, true);
let buttonElm = vm.$el;
expect(buttonElm.classList.contains('is-loading')).to.be.true;
expect(buttonElm.querySelector('.el-icon-loading')).to.be.ok;
});
it('disabled', () => {
vm = createTest(Button, {
disabled: true
}, true);
let buttonElm = vm.$el;
expect(buttonElm.classList.contains('is-disabled')).to.be.true;
});
it('size', () => {
vm = createTest(Button, {
size: 'medium'
}, true);
let buttonElm = vm.$el;
expect(buttonElm.classList.contains('el-button--medium')).to.be.true;
});
it('plain', () => {
vm = createTest(Button, {
plain: true
}, true);
let buttonElm = vm.$el;
expect(buttonElm.classList.contains('is-plain')).to.be.true;
});
it('round', () => {
vm = createTest(Button, {
round: true
}, true);
let buttonElm = vm.$el;
expect(buttonElm.classList.contains('is-round')).to.be.true;
});
it('circle', () => {
vm = createTest(Button, {
circle: true
}, true);
let buttonElm = vm.$el;
expect(buttonElm.classList.contains('is-circle')).to.be.true;
});
it('click', done => {
let result;
vm = createVue({
template: `
<el-button @click="handleClick"></el-button>
`,
methods: {
handleClick(evt) {
result = evt;
}
}
}, true);
vm.$el.click();
setTimeout(_ => {
expect(result).to.exist;
done();
}, 20);
});
it('click inside', done => {
let result;
vm = createVue({
template: `
<el-button @click="handleClick"><span class="inner-slot"></span></el-button>
`,
methods: {
handleClick(evt) {
result = evt;
}
}
}, true);
vm.$el.querySelector('.inner-slot').click();
setTimeout(_ => {
expect(result).to.exist;
done();
}, 20);
});
it('loading implies disabled', done => {
let result;
vm = createVue({
template: `
<el-button loading @click="handleClick"><span class="inner-slot"></span></el-button>
`,
methods: {
handleClick(evt) {
result = evt;
}
}
}, true);
vm.$el.querySelector('.inner-slot').click();
setTimeout(_ => {
expect(result).to.not.exist;
done();
}, 20);
});
});

View File

@@ -0,0 +1,108 @@
import { createVue, destroyVM, waitImmediate } from '../util';
describe('Calendar', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', async() => {
vm = createVue({
template: `
<el-calendar v-model="value"></el-calendar>
`,
data() {
return {
value: new Date('2019-04-01')
};
}
}, true);
const titleEl = vm.$el.querySelector('.el-calendar__title');
expect(/2019.*4/.test(titleEl.innerText)).to.be.true;
expect(vm.$el.querySelectorAll('thead th').length).to.equal(7);
const rows = vm.$el.querySelectorAll('.el-calendar-table__row');
expect(rows.length).to.equal(6);
rows[5].firstElementChild.click();
await waitImmediate();
expect(/2019.*5/.test(titleEl.innerText)).to.be.true;
const value = vm.value;
expect(value.getFullYear()).to.be.equal(2019);
expect(value.getMonth()).to.be.equal(4);
expect(vm.$el.querySelector('.is-selected span').innerText).to.be.equal('6');
});
it('range', () => {
vm = createVue({
template: `
<el-calendar :range="['2019-03-04', '2019-03-24']"></el-calendar>
`
}, true);
const titleEl = vm.$el.querySelector('.el-calendar__title');
expect(/2019.*3/.test(titleEl.innerText)).to.be.true;
const rows = vm.$el.querySelectorAll('.el-calendar-table__row');
expect(rows.length).to.equal(3);
expect(vm.$el.querySelector('.el-calendar__button-group')).to.be.a('null');
});
it('range tow monthes', async() => {
vm = createVue({
template: `
<el-calendar :range="['2019-04-15', '2019-05-19']"></el-calendar>
`
}, true);
const titleEl = vm.$el.querySelector('.el-calendar__title');
expect(/2019.*4/.test(titleEl.innerText)).to.be.true;
const dateTables = vm.$el.querySelectorAll('.el-calendar-table.is-range');
expect(dateTables.length).to.be.equal(2);
const rows = vm.$el.querySelectorAll('.el-calendar-table__row');
expect(rows.length).to.equal(5);
const cell = rows[rows.length - 1].firstElementChild;
cell.click();
await waitImmediate();
expect(/2019.*5/.test(titleEl.innerText)).to.be.true;
expect(cell.classList.contains('is-selected')).to.be.true;
});
it('firstDayOfWeek', async() => {
vm = createVue({
template: `
<el-calendar v-model="value" :first-day-of-week="0"></el-calendar>
`,
data() {
return {
value: new Date('2019-04-01')
};
}
}, true);
const head = vm.$el.querySelector('.el-calendar-table thead');
expect(head.firstElementChild.innerText).to.be.equal('日');
expect(head.lastElementChild.innerText).to.be.equal('六');
const firstRow = vm.$el.querySelector('.el-calendar-table__row');
expect(firstRow.firstElementChild.innerText).to.be.equal('31');
expect(firstRow.lastElementChild.innerText).to.be.equal('6');
});
it('firstDayOfWeek in range mode', async() => {
vm = createVue({
template: `
<el-calendar v-model="value" :first-day-of-week="7" :range="['2019-02-03', '2019-03-23']"></el-calendar>
`,
data() {
return {
value: new Date('2019-03-04')
};
}
}, true);
const head = vm.$el.querySelector('.el-calendar-table thead');
expect(head.firstElementChild.innerText).to.be.equal('日');
expect(head.lastElementChild.innerText).to.be.equal('六');
const firstRow = vm.$el.querySelector('.el-calendar-table__row');
expect(firstRow.firstElementChild.innerText).to.be.equal('3');
expect(firstRow.lastElementChild.innerText).to.be.equal('9');
});
});

View File

@@ -0,0 +1,56 @@
import { createVue, createTest, destroyVM } from '../util';
import Card from 'packages/card';
describe('Card', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('slot:header', () => {
vm = createVue(`
<el-card>
<header slot="header">二师兄叫我埋梗 啦啦啦</header>
</el-card>
`);
expect(vm.$el.querySelector('.el-card__header')).to.property('textContent').to.include('二师兄叫我埋梗 啦啦啦');
});
it('header', () => {
vm = createTest(Card, {
header: '好烦'
});
expect(vm.$el.querySelector('.el-card__header')).to.property('textContent').to.include('好烦');
});
it('bodyStyle', () => {
vm = createTest(Card, {
bodyStyle: { padding: '10px' }
});
expect(vm.$el.querySelector('.el-card__body').style.padding).to.equal('10px');
});
it('shadow', () => {
vm = createTest(Card, {
shadow: 'always'
});
expect(vm.$el.classList.contains('is-always-shadow')).to.be.true;
});
it('shadow', () => {
vm = createTest(Card, {
shadow: 'hover'
});
expect(vm.$el.classList.contains('is-hover-shadow')).to.be.true;
});
it('shadow', () => {
vm = createTest(Card, {
shadow: 'never'
});
expect(vm.$el.classList.contains('is-never-shadow')).to.be.true;
});
});

View File

@@ -0,0 +1,277 @@
import { createVue, destroyVM } from '../util';
describe('Carousel', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', () => {
vm = createVue({
template: `
<div>
<el-carousel ref="carousel">
<el-carousel-item v-for="item in 3" :key="item"></el-carousel-item>
</el-carousel>
</div>
`
});
expect(vm.$refs.carousel.direction).to.be.equal('horizontal');
expect(vm.$el.querySelectorAll('.el-carousel__item').length).to.equal(3);
});
it('auto play', done => {
vm = createVue({
template: `
<div>
<el-carousel :interval="50">
<el-carousel-item v-for="item in 3" :key="item"></el-carousel-item>
</el-carousel>
</div>
`
});
setTimeout(() => {
const items = vm.$el.querySelectorAll('.el-carousel__item');
expect(items[0].classList.contains('is-active')).to.true;
setTimeout(() => {
expect(items[1].classList.contains('is-active')).to.true;
done();
}, 60);
}, 10);
});
it('initial index', done => {
vm = createVue({
template: `
<div>
<el-carousel :autoplay="false" :initial-index="1">
<el-carousel-item v-for="item in 3" :key="item"></el-carousel-item>
</el-carousel>
</div>
`
});
setTimeout(() => {
expect(vm.$el.querySelectorAll('.el-carousel__item')[1].classList.contains('is-active')).to.true;
done();
}, 10);
});
it('reset timer', done => {
vm = createVue({
template: `
<div>
<el-carousel :interval="20">
<el-carousel-item v-for="item in 3" :key="item"></el-carousel-item>
</el-carousel>
</div>
`
});
setTimeout(() => {
const carousel = vm.$children[0];
const items = vm.$el.querySelectorAll('.el-carousel__item');
carousel.handleMouseEnter();
setTimeout(() => {
expect(items[0].classList.contains('is-active')).to.true;
carousel.handleMouseLeave();
setTimeout(() => {
expect(items[1].classList.contains('is-active')).to.true;
done();
}, 30);
}, 20);
}, 10);
});
it('change', done => {
vm = createVue({
template: `
<div>
<el-carousel :interval="50" @change="handleChange">
<el-carousel-item v-for="item in 3" :key="item"></el-carousel-item>
</el-carousel>
</div>
`,
data() {
return {
val: -1,
oldVal: -1
};
},
methods: {
handleChange(val, oldVal) {
this.val = val;
this.oldVal = oldVal;
}
}
});
setTimeout(() => {
expect(vm.val).to.equal(1);
expect(vm.oldVal).to.equal(0);
done();
}, 60);
});
it('label', done => {
vm = createVue({
template: `
<div>
<el-carousel>
<el-carousel-item v-for="item in 3" :key="item" :label="item"></el-carousel-item>
</el-carousel>
</div>
`
});
setTimeout(_ => {
expect(vm.$el.querySelector('.el-carousel__button').innerText).to.equal('1');
done();
}, 10);
});
describe('manual control', () => {
it('hover', done => {
vm = createVue({
template: `
<div>
<el-carousel :autoplay="false">
<el-carousel-item v-for="item in 3" :key="item"></el-carousel-item>
</el-carousel>
</div>
`
});
setTimeout(() => {
vm.$children[0].throttledIndicatorHover(1);
setTimeout(() => {
expect(vm.$el.querySelectorAll('.el-carousel__item')[1].classList.contains('is-active')).to.true;
done();
}, 10);
}, 10);
});
it('click', done => {
vm = createVue({
template: `
<div>
<el-carousel :autoplay="false" trigger="click" ref="carousel">
<el-carousel-item v-for="item in 3" :key="item"></el-carousel-item>
</el-carousel>
</div>
`
});
setTimeout(() => {
const items = vm.$el.querySelectorAll('.el-carousel__item');
const carousel = vm.$refs.carousel;
vm.$el.querySelectorAll('.el-carousel__indicator')[2].click();
setTimeout(() => {
expect(items[2].classList.contains('is-active')).to.true;
carousel.handleButtonEnter('right');
vm.$el.querySelector('.el-carousel__arrow--right').click();
setTimeout(() => {
expect(items[0].classList.contains('is-active')).to.true;
done();
}, 10);
}, 10);
}, 10);
});
});
describe('methods', () => {
it('setActiveItem', done => {
vm = createVue({
template: `
<div>
<el-carousel :autoplay="false">
<el-carousel-item v-for="item in 3" :key="item"></el-carousel-item>
</el-carousel>
</div>
`
});
setTimeout(() => {
vm.$children[0].setActiveItem(1);
setTimeout(() => {
expect(vm.$el.querySelectorAll('.el-carousel__item')[1].classList.contains('is-active')).to.true;
done();
}, 10);
}, 10);
});
it('slide', done => {
vm = createVue({
template: `
<div>
<el-carousel :autoplay="false">
<el-carousel-item v-for="item in 3" :key="item"></el-carousel-item>
</el-carousel>
</div>
`
});
setTimeout(() => {
vm.$children[0].prev(1);
const items = vm.$el.querySelectorAll('.el-carousel__item');
setTimeout(() => {
expect(items[2].classList.contains('is-active')).to.true;
vm.$children[0].next(1);
setTimeout(() => {
expect(items[0].classList.contains('is-active')).to.true;
done();
}, 10);
}, 10);
}, 10);
});
});
it('card', done => {
vm = createVue({
template: `
<div>
<el-carousel :autoplay="false" type="card">
<el-carousel-item v-for="item in 7" :key="item"></el-carousel-item>
</el-carousel>
</div>
`
});
setTimeout(() => {
const items = vm.$el.querySelectorAll('.el-carousel__item');
expect(items[0].classList.contains('is-active')).to.true;
expect(items[1].classList.contains('is-in-stage')).to.true;
expect(items[6].classList.contains('is-in-stage')).to.true;
items[1].click();
setTimeout(() => {
expect(items[1].classList.contains('is-active')).to.true;
vm.$el.querySelector('.el-carousel__arrow--left').click();
setTimeout(() => {
expect(items[0].classList.contains('is-active')).to.true;
items[6].click();
setTimeout(() => {
expect(items[6].classList.contains('is-active')).to.true;
done();
}, 10);
}, 10);
}, 10);
}, 10);
});
it('vertical direction', () => {
vm = createVue({
template: `
<div>
<el-carousel ref="carousel" :autoplay="false" direction="vertical" height="100px">
<el-carousel-item v-for="item in 3" :key="item"></el-carousel-item>
</el-carousel>
</div>
`
});
const items = vm.$el.querySelectorAll('.el-carousel__item');
expect(vm.$refs.carousel.direction).to.be.equal('vertical');
expect(items[0].style.transform.indexOf('translateY') !== -1).to.be.true;
});
});

View File

@@ -0,0 +1,581 @@
import {
createTest,
createVue,
destroyVM,
waitImmediate,
wait,
triggerEvent
} from '../util';
import CascaderPanel from 'packages/cascader-panel';
const selectedValue = ['zhejiang', 'hangzhou', 'xihu'];
const options = [{
value: 'zhejiang',
label: 'Zhejiang',
children: [{
value: 'hangzhou',
label: 'Hangzhou',
children: [{
value: 'xihu',
label: 'West Lake'
}, {
value: 'binjiang',
label: 'Bin Jiang'
}]
}, {
value: 'ningbo',
label: 'NingBo',
children: [{
value: 'jiangbei',
label: 'Jiang Bei'
}, {
value: 'jiangdong',
label: 'Jiang Dong',
disabled: true
}]
}]
}, {
value: 'jiangsu',
label: 'Jiangsu',
disabled: true,
children: [{
value: 'nanjing',
label: 'Nanjing',
children: [{
value: 'zhonghuamen',
label: 'Zhong Hua Men'
}]
}]
}];
const options2 = [{
id: 'zhejiang',
name: 'Zhejiang',
areas: [{
id: 'hangzhou',
name: 'Hangzhou',
areas: [{
id: 'xihu',
name: 'West Lake'
}, {
id: 'binjiang',
name: 'Bin Jiang'
}]
}, {
id: 'ningbo',
name: 'NingBo',
areas: [{
id: 'jiangbei',
label: 'Jiang Bei'
}, {
id: 'jiangdong',
name: 'Jiang Dong',
invalid: true
}]
}]
}, {
id: 'jiangsu',
name: 'Jiangsu',
invalid: true,
areas: [{
id: 'nanjing',
name: 'Nanjing',
areas: [{
id: 'zhonghuamen',
name: 'Zhong Hua Men'
}]
}]
}];
const options3 = [
{
value: 'shanghai',
label: '上海',
children: [
{
value: 'baoshan',
label: '宝山'
}
]
},
{
value: 'beijing',
label: '北京'
}
];
const getMenus = el => el.querySelectorAll('.el-cascader-menu');
const getOptions = (el, menuIndex) => getMenus(el)[menuIndex].querySelectorAll('.el-cascader-node');
const getValidOptions = (el, menuIndex) => getMenus(el)[menuIndex].querySelectorAll('.el-cascader-node[tabindex="-1"]');
const getLabel = el => el.querySelector('.el-cascader-node__label').textContent;
describe('CascaderPanel', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', () => {
vm = createTest(CascaderPanel, true);
expect(vm.$el).to.exist;
});
it('expand and check', async() => {
vm = createVue({
template: `
<el-cascader-panel
ref="panel"
v-model="value"
:options="options"></el-cascader-panel>
`,
data() {
return {
value: [],
options
};
}
}, true);
const el = vm.$el;
const expandHandler = sinon.spy();
const changeHandler = sinon.spy();
vm.$refs.panel.$on('expand-change', expandHandler);
vm.$refs.panel.$on('change', changeHandler);
expect(getMenus(el).length).to.equal(1);
expect(getOptions(el, 0).length).to.equal(2);
const firstOption = getOptions(el, 0)[0];
expect(getLabel(firstOption)).to.equal('Zhejiang');
firstOption.click();
await waitImmediate();
expect(expandHandler.calledOnceWith(['zhejiang'])).to.be.true;
expect(getMenus(el).length).to.equal(2);
getOptions(el, 1)[0].click();
await waitImmediate();
expect(getMenus(el).length).to.equal(3);
getOptions(el, 2)[0].click();
await waitImmediate();
expect(changeHandler.calledOnceWith(selectedValue)).to.be.true;
expect(vm.value).to.deep.equal(selectedValue);
});
it('with default value', async() => {
vm = createVue({
template: `
<el-cascader-panel
ref="panel"
v-model="value"
:options="options"></el-cascader-panel>
`,
data() {
return {
value: selectedValue,
options
};
}
}, true);
const el = vm.$el;
await waitImmediate();
expect(getMenus(el).length).to.equal(3);
expect(getOptions(el, 0)[0].className).to.includes('in-active-path');
expect(getOptions(el, 2)[0].className).to.includes('is-active');
expect(getOptions(el, 2)[0].querySelector('.el-icon-check')).to.exist;
});
it('disabled options', async() => {
vm = createVue({
template: `
<el-cascader-panel
ref="panel"
:value="value"
:options="options"></el-cascader-panel>
`,
data() {
return {
value: [],
options
};
}
}, true);
const el = vm.$el;
const expandHandler = sinon.spy();
vm.$refs.panel.$on('expand-change', expandHandler);
expect(getOptions(el, 0).length).to.equal(2);
expect(getValidOptions(el, 0).length).to.equal(1);
const secondOption = getOptions(el, 0)[1];
expect(secondOption.className).to.includes('is-disabled');
secondOption.click();
await waitImmediate();
expect(expandHandler.called).to.be.false;
expect(getMenus(el).length).to.equal(1);
});
it('expand by hover', async() => {
vm = createVue({
template: `
<el-cascader-panel
:options="options"
:props="props"></el-cascader-panel>
`,
data() {
return {
options,
props: {
expandTrigger: 'hover'
}
};
}
}, true);
const el = vm.$el;
triggerEvent(getOptions(el, 0)[1], 'mouseenter');
await waitImmediate();
expect(getMenus(el).length).to.equal(1);
triggerEvent(getOptions(el, 0)[0], 'mouseenter');
await waitImmediate();
expect(getMenus(el).length).to.equal(2);
triggerEvent(getOptions(el, 1)[0], 'mouseenter');
await waitImmediate();
expect(getMenus(el).length).to.equal(3);
});
it('emit value only', async() => {
vm = createVue({
template: `
<el-cascader-panel
ref="panel"
v-model="value"
:options="options"
:props="props"></el-cascader-panel>
`,
data() {
return {
value: 'xihu',
options,
props: {
emitPath: false
}
};
}
}, true);
const el = vm.$el;
await waitImmediate();
expect(getMenus(el).length).to.equal(3);
expect(getOptions(el, 2)[0].querySelector('.el-icon-check')).to.exist;
getOptions(el, 1)[1].click();
await waitImmediate();
getOptions(el, 2)[0].click();
await waitImmediate();
expect(vm.value).to.equal('jiangbei');
});
it('multiple mode', async() => {
vm = createVue({
template: `
<el-cascader-panel
v-model="value"
:options="options"
:props="props"></el-cascader-panel>
`,
data() {
return {
value: [],
options: options,
props: {
multiple: true
}
};
}
}, true);
const el = vm.$el;
const checkbox = getOptions(el, 0)[0].querySelector('.el-checkbox');
expect(checkbox).to.exist;
expect(checkbox.querySelector('.el-checkbox__input').className).to.not.includes('is-checked');
checkbox.querySelector('input').click();
await waitImmediate();
expect(checkbox.querySelector('.el-checkbox__input').className).to.includes('is-checked');
expect(vm.value.length).to.equal(3);
});
it('multiple mode with disabled default value', async() => {
vm = createVue({
template: `
<el-cascader-panel
v-model="value"
:options="options"
:props="props"></el-cascader-panel>
`,
data() {
return {
value: [['zhejiang', 'ningbo', 'jiangdong']],
options: options,
props: {
multiple: true
}
};
}
}, true);
const el = vm.$el;
const checkbox = getOptions(el, 0)[0].querySelector('.el-checkbox');
await waitImmediate();
expect(checkbox).to.exist;
expect(checkbox.querySelector('.el-checkbox__input').className).to.includes('is-indeterminate');
checkbox.querySelector('input').click();
await waitImmediate();
expect(checkbox.querySelector('.el-checkbox__input').className).to.includes('is-checked');
expect(vm.value.length).to.equal(4);
getOptions(el, 1)[1].click();
await waitImmediate();
getOptions(el, 2)[1].querySelector('input').click();
await waitImmediate();
expect(vm.value.length).to.equal(4);
});
it('check strictly in single mode', async() => {
vm = createVue({
template: `
<el-cascader-panel
v-model="value"
:options="options"
:props="props"></el-cascader-panel>
`,
data() {
return {
value: ['zhejiang'],
options: options,
props: {
checkStrictly: true
}
};
}
}, true);
const el = vm.$el;
const radio = getOptions(el, 0)[0].querySelector('.el-radio');
await waitImmediate();
expect(radio).to.exist;
expect(radio.className).to.includes('is-checked');
getOptions(el, 0)[0].click();
await waitImmediate();
getOptions(el, 1)[0].querySelector('input').click();
await waitImmediate();
expect(vm.value).to.deep.equal(['zhejiang', 'hangzhou']);
expect(getOptions(el, 0)[1].querySelector('.el-radio').className).to.includes('is-disabled');
});
it('check strictly in multiple mode', async() => {
vm = createVue({
template: `
<el-cascader-panel
v-model="value"
:options="options"
:props="props"></el-cascader-panel>
`,
data() {
return {
value: [['zhejiang']],
options: options,
props: {
multiple: true,
checkStrictly: true,
emitPath: false
}
};
}
}, true);
const el = vm.$el;
const checkbox = getOptions(el, 0)[0].querySelector('.el-checkbox');
await waitImmediate();
expect(checkbox).to.exist;
expect(checkbox.className).to.includes('is-checked');
getOptions(el, 0)[0].click();
await waitImmediate();
expect(getOptions(el, 1)[0].querySelector('.el-checkbox').className).to.not.includes('is-checked');
getOptions(el, 1)[0].querySelector('input').click();
await waitImmediate();
expect(vm.value).to.deep.equal(['zhejiang', 'hangzhou']);
expect(getOptions(el, 0)[1].querySelector('.el-checkbox').className).to.includes('is-disabled');
});
it('custom props', async() => {
vm = createVue({
template: `
<el-cascader-panel
v-model="value"
:options="options"
:props="props"></el-cascader-panel>
`,
data() {
return {
value: [],
options: options2,
props: {
value: 'id',
label: 'name',
children: 'areas',
disabled: 'invalid'
}
};
}
}, true);
const el = vm.$el;
expect(getMenus(el).length).to.equal(1);
expect(getOptions(el, 0).length).to.equal(2);
expect(getValidOptions(el, 0).length).to.equal(1);
const firstOption = getOptions(el, 0)[0];
expect(getLabel(firstOption)).to.equal('Zhejiang');
firstOption.click();
await waitImmediate();
expect(getMenus(el).length).to.equal(2);
getOptions(el, 1)[0].click();
await waitImmediate();
expect(getMenus(el).length).to.equal(3);
getOptions(el, 2)[0].click();
await waitImmediate();
expect(vm.value).to.deep.equal(selectedValue);
});
it('value key is same as label key', async() => {
vm = createVue({
template: `
<el-cascader-panel
v-model="value"
:options="options"
:props="props"></el-cascader-panel>
`,
data() {
return {
value: [],
options,
props: {
label: 'value'
}
};
}
}, true);
const el = vm.$el;
expect(getMenus(el).length).to.equal(1);
expect(getOptions(el, 0).length).to.equal(2);
expect(getValidOptions(el, 0).length).to.equal(1);
const firstOption = getOptions(el, 0)[0];
expect(getLabel(firstOption)).to.equal('zhejiang');
firstOption.click();
await waitImmediate();
expect(getMenus(el).length).to.equal(2);
getOptions(el, 1)[0].click();
await waitImmediate();
expect(getMenus(el).length).to.equal(3);
getOptions(el, 2)[0].click();
await waitImmediate();
expect(vm.value).to.deep.equal(selectedValue);
});
it('dynamic loading', async() => {
vm = createVue({
template: `
<el-cascader-panel
v-model="value"
:props="props"></el-cascader-panel>
`,
data() {
let id = 0;
return {
value: [],
props: {
lazy: true,
lazyLoad(node, resolve) {
const { level } = node;
setTimeout(() => {
const nodes = Array.from({ length: level + 1 })
.map(() => ({
value: ++id,
label: `选项${id}`,
leaf: level >= 2
}));
resolve(nodes);
}, 1000);
}
}
};
}
}, true);
const el = vm.$el;
await wait(1000);
const firstOption = getOptions(el, 0)[0];
firstOption.click();
await waitImmediate();
expect(firstOption.querySelector('i').className).to.includes('el-icon-loading');
await wait(1000);
expect(firstOption.querySelector('i').className).to.includes('el-icon-arrow-right');
expect(getMenus(el).length).to.equal(2);
getOptions(el, 1)[0].click();
await wait(1000);
getOptions(el, 2)[0].click();
await waitImmediate();
expect(vm.value.length).to.equal(3);
});
it('click leaf hidden children', async() => {
vm = createVue({
template: `
<el-cascader-panel
ref="panel"
v-model="value"
:options="options"></el-cascader-panel>
`,
data() {
return {
value: [],
options: options3
};
}
}, true);
const el = vm.$el;
const elOptions = getOptions(el, 0);
const firstOption = elOptions[0];
const twoOption = elOptions[1];
firstOption.click();
await waitImmediate();
expect(getMenus(el).length).to.equal(2);
twoOption.click();
await waitImmediate();
expect(getMenus(el).length).to.equal(1);
});
});

View File

@@ -0,0 +1,416 @@
import {
createTest,
createVue,
destroyVM,
waitImmediate,
wait,
triggerEvent
} from '../util';
import Cascader from 'packages/cascader';
const options = [{
value: 'zhejiang',
label: 'Zhejiang',
children: [{
value: 'hangzhou',
label: 'Hangzhou',
children: [{
value: 'xihu',
label: 'West Lake'
}, {
value: 'binjiang',
label: 'Bin Jiang'
}]
}, {
value: 'ningbo',
label: 'NingBo',
children: [{
value: 'jiangbei',
label: 'Jiang Bei'
}, {
value: 'jiangdong',
label: 'Jiang Dong',
disabled: true
}]
}]
}, {
value: 'jiangsu',
label: 'Jiangsu',
disabled: true,
children: [{
value: 'nanjing',
label: 'Nanjing',
children: [{
value: 'zhonghuamen',
label: 'Zhong Hua Men'
}]
}]
}];
const getMenus = el => el.querySelectorAll('.el-cascader-menu');
const getOptions = (el, menuIndex) => getMenus(el)[menuIndex].querySelectorAll('.el-cascader-node');
const selectedValue = ['zhejiang', 'hangzhou', 'xihu'];
const getCloseButton = el => el.querySelectorAll('i.el-tag__close');
describe('Cascader', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', () => {
vm = createTest(Cascader, true);
expect(vm.$el).to.exist;
});
it('toggle dropdown visible', async() => {
vm = createTest(Cascader, true);
expect(vm.$refs.popper.style.display).to.equal('none');
vm.$el.click();
await waitImmediate();
expect(vm.$refs.popper.style.display).to.includes('');
vm.$el.click();
await wait(500);
expect(vm.$refs.popper.style.display).to.includes('none');
});
it('expand and check', async() => {
vm = createTest({
template: `
<el-cascader
ref="cascader"
v-model="value"
:options="options"></el-cascader>
`,
data() {
return {
value: [],
options
};
}
}, true);
const { body } = document;
const expandHandler = sinon.spy();
const changeHandler = sinon.spy();
vm.$refs.cascader.$on('expand-change', expandHandler);
vm.$refs.cascader.$on('change', changeHandler);
getOptions(body, 0)[0].click();
await waitImmediate();
expect(expandHandler.calledOnceWith(['zhejiang'])).to.be.true;
getOptions(body, 1)[0].click();
await waitImmediate();
const checkedOption = getOptions(body, 2)[0];
checkedOption.click();
await waitImmediate();
expect(changeHandler.calledOnceWith(selectedValue)).to.be.true;
expect(vm.value).to.deep.equal(selectedValue);
expect(checkedOption.querySelector('i.el-icon-check')).to.exist;
expect(vm.$el.querySelector('input').value).to.equal('Zhejiang / Hangzhou / West Lake');
});
it('disabled', async() => {
vm = createTest(Cascader, {
disabled: true
}, true);
expect(vm.$el.className).to.includes('is-disabled');
vm.$el.click();
await waitImmediate();
expect(vm.$refs.popper.style.display).to.includes('none');
});
it('with default value', async() => {
vm = createVue({
template: `
<el-cascader
v-model="value"
:options="options"></el-cascader>
`,
data() {
return {
value: selectedValue,
options
};
}
}, true);
const el = vm.$el;
await waitImmediate();
expect(getMenus(el).length).to.equal(3);
expect(getOptions(el, 2)[0].querySelector('i').className).to.includes('el-icon-check');
expect(vm.$el.querySelector('input').value).to.equal('Zhejiang / Hangzhou / West Lake');
});
it('async set selected value', async() => {
vm = createVue({
template: `
<el-cascader
v-model="value"
:options="options"></el-cascader>
`,
data() {
return {
value: [],
options
};
}
}, true);
const el = vm.$el;
vm.value = selectedValue;
await waitImmediate();
expect(getMenus(el).length).to.equal(3);
expect(getOptions(el, 2)[0].querySelector('i').className).to.includes('el-icon-check');
expect(vm.$el.querySelector('input').value).to.equal('Zhejiang / Hangzhou / West Lake');
});
it('default value with async options', async() => {
vm = createVue({
template: `
<el-cascader
v-model="value"
:options="options"></el-cascader>
`,
data() {
return {
value: selectedValue,
options: []
};
}
}, true);
const el = vm.$el;
vm.options = options;
await waitImmediate();
expect(getMenus(el).length).to.equal(3);
expect(getOptions(el, 2)[0].querySelector('i').className).to.includes('el-icon-check');
expect(vm.$el.querySelector('input').value).to.equal('Zhejiang / Hangzhou / West Lake');
});
it('clearable', async() => {
vm = createVue({
template: `
<el-cascader
v-model="value"
:options="options"
clearable></el-cascader>
`,
data() {
return {
value: selectedValue,
options
};
}
}, true);
triggerEvent(vm.$el, 'mouseenter');
await waitImmediate();
const closeBtn = vm.$el.querySelector('i.el-input__icon');
expect(closeBtn).to.exist;
closeBtn.click();
await waitImmediate();
expect(vm.value).to.deep.equal([]);
});
it('show last level label', async() => {
vm = createVue({
template: `
<el-cascader
v-model="value"
:options="options"
:show-all-levels="false"></el-cascader>
`,
data() {
return {
value: selectedValue,
options
};
}
}, true);
const el = vm.$el;
await waitImmediate();
expect(getMenus(el).length).to.equal(3);
expect(getOptions(el, 2)[0].querySelector('i').className).to.includes('el-icon-check');
expect(vm.$el.querySelector('input').value).to.equal('West Lake');
});
it('multiple mode', async() => {
vm = createVue({
template: `
<el-cascader
v-model="value"
:options="options"
:disabled="disabled"
:props="props"></el-cascader>
`,
data() {
return {
value: [],
options,
disabled: false,
props: {
multiple: true
}
};
}
}, true);
getOptions(document.body, 0)[0].querySelector('.el-checkbox input').click();
await waitImmediate();
expect(vm.value.length).to.equal(3);
expect(getCloseButton(vm.$el).length).to.equal(3);
const tags = vm.$el.querySelectorAll('.el-tag');
const closeBtn = tags[0].querySelector('.el-tag__close');
expect(tags.length).to.equal(3);
expect(closeBtn).to.exist;
closeBtn.click();
await waitImmediate();
expect(vm.value.length).to.equal(2);
expect(vm.$el.querySelectorAll('.el-tag').length).to.equal(2);
vm.disabled = true;
await waitImmediate();
expect(getCloseButton(vm.$el).length).to.equal(0);
});
it('clearable in multiple mode', async() => {
vm = createVue({
template: `
<el-cascader
v-model="value"
:options="options"
:props="props"
clearable></el-cascader>
`,
data() {
return {
value: [],
options,
props: {
multiple: true,
emitPath: false
}
};
}
}, true);
vm.value = ['xihu', 'binjiang', 'jiangbei', 'jiangdong'];
await waitImmediate();
expect(getOptions(document.body, 0)[0].querySelector('.el-checkbox.is-checked')).to.exist;
triggerEvent(vm.$el, 'mouseenter');
await waitImmediate();
const closeBtn = vm.$el.querySelector('i.el-input__icon');
expect(closeBtn).to.exist;
closeBtn.click();
await waitImmediate();
expect(vm.value.length).to.equal(1);
});
it('collapse tags', async() => {
vm = createVue({
template: `
<el-cascader
v-model="value"
:options="options"
:props="props"
collapse-tags></el-cascader>
`,
data() {
return {
value: ['xihu', 'binjiang', 'jiangbei', 'jiangdong'],
options,
props: {
multiple: true,
emitPath: false
}
};
}
}, true);
await waitImmediate();
const tags = vm.$el.querySelectorAll('.el-tag');
expect(tags.length).to.equal(2);
expect(tags[0].querySelector('.el-tag__close')).to.exist;
expect(tags[1].querySelector('.el-tag__close')).to.be.null;
tags[0].querySelector('.el-tag__close').click();
expect(tags[1].textContent).to.equal('+ 3');
await waitImmediate();
expect(vm.value.length).to.equal(3);
vm.$el.querySelector('.el-tag .el-tag__close').click();
await waitImmediate();
vm.$el.querySelector('.el-tag .el-tag__close').click();
await waitImmediate();
expect(vm.$el.querySelector('.el-tag')).to.exist;
// disabled tag can not be closed
expect(vm.$el.querySelector('.el-tag .el-tag__close')).to.be.null;
});
it('filterable', async() => {
vm = createVue({
template: `
<el-cascader
v-model="value"
:options="options"
filterable></el-cascader>
`,
data() {
return {
value: [],
options
};
}
}, true);
const el = vm.$el;
const { body } = document;
const input = el.querySelector('input');
el.click();
await waitImmediate();
input.value = 'Zhejiang';
triggerEvent(input, 'input');
await wait(300);
expect(body.querySelector('.el-cascader__suggestion-list')).to.exist;
expect(body.querySelectorAll('.el-cascader__suggestion-item').length).to.equal(3);
body.querySelectorAll('.el-cascader__suggestion-item')[0].click();
await waitImmediate();
expect(vm.value).to.deep.equal(selectedValue);
});
it('filter method', async() => {
vm = createVue({
template: `
<el-cascader
v-model="value"
:options="options"
:filter-method="filterMethod"
filterable></el-cascader>
`,
data() {
return {
value: [],
options
};
},
methods: {
filterMethod(node, keyword) {
const { text, path } = node;
return text.includes(keyword) || path.includes(keyword);
}
}
}, true);
const el = vm.$el;
const { body } = document;
const input = el.querySelector('input');
el.click();
await waitImmediate();
input.value = 'Zhejiang';
triggerEvent(input, 'input');
await wait(300);
expect(body.querySelectorAll('.el-cascader__suggestion-item').length).to.equal(3);
input.value = 'xihu';
triggerEvent(input, 'input');
await wait(300);
expect(body.querySelector('.el-cascader__suggestion-item').textContent).to.equal('Zhejiang / Hangzhou / West Lake');
});
});

View File

@@ -0,0 +1,507 @@
import { createVue, destroyVM } from '../util';
describe('Checkbox', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', done => {
vm = createVue({
template: `
<el-checkbox v-model="checked">
</el-checkbox>
`,
data() {
return {
checked: false
};
}
}, true);
let checkboxElm = vm.$el;
expect(checkboxElm.classList.contains('el-checkbox')).to.be.true;
checkboxElm.click();
vm.$nextTick(_ => {
expect(checkboxElm.querySelector('.is-checked')).to.be.ok;
done();
});
});
it('disabled', () => {
vm = createVue({
template: `
<el-checkbox
v-model="checked"
disabled
>
</el-checkbox>
`,
data() {
return {
checked: false
};
}
}, true);
let checkboxElm = vm.$el;
expect(checkboxElm.querySelector('.is-disabled')).to.be.ok;
});
it('change event', done => {
vm = createVue({
template: `
<el-checkbox v-model="checked" @change="onChange">
</el-checkbox>
`,
methods: {
onChange(val) {
this.data = val;
}
},
data() {
return {
data: '',
checked: false
};
}
}, true);
let checkboxElm = vm.$el;
checkboxElm.click();
setTimeout(_ => {
expect(vm.data).to.true;
vm.checked = false;
setTimeout(_ => {
expect(vm.data).to.true;
done();
}, 10);
}, 10);
});
it('checkbox group', done => {
vm = createVue({
template: `
<el-checkbox-group v-model="checkList">
<el-checkbox label="a" ref="a"></el-checkbox>
<el-checkbox label="b" ref="b"></el-checkbox>
<el-checkbox label="c" ref="c"></el-checkbox>
<el-checkbox label="d" ref="d"></el-checkbox>
</el-checkbox-group>
`,
data() {
return {
checkList: []
};
}
}, true);
expect(vm.checkList.length === 0).to.be.true;
vm.$refs.a.$el.click();
vm.$nextTick(_ => {
expect(vm.checkList.indexOf('a') !== -1).to.be.true;
done();
});
});
it('checkbox group change event', done => {
vm = createVue({
template: `
<el-checkbox-group v-model="checkList" @change="onChange">
<el-checkbox label="a" ref="a"></el-checkbox>
<el-checkbox label="b" ref="b"></el-checkbox>
</el-checkbox-group>
`,
methods: {
onChange(val) {
this.data = val;
}
},
data() {
return {
data: '',
checkList: []
};
}
}, true);
vm.$refs.a.$el.click();
setTimeout(_ => {
expect(vm.data).to.deep.equal(['a']);
vm.checkList = ['b'];
done();
}, 10);
});
it('checkbox group minimum and maximum', done => {
vm = createVue({
template: `
<el-checkbox-group
v-model="checkList"
:min="1"
:max="2"
>
<el-checkbox label="a" ref="a"></el-checkbox>
<el-checkbox label="b" ref="b"></el-checkbox>
<el-checkbox label="c" ref="c"></el-checkbox>
<el-checkbox label="d" ref="d"></el-checkbox>
</el-checkbox-group>
`,
data() {
return {
checkList: ['a'],
lastEvent: null
};
}
}, true);
expect(vm.checkList.length === 1).to.be.true;
expect(vm.$refs.a.isDisabled).to.be.true;
vm.$refs.a.$el.click();
vm.$nextTick(() => {
expect(vm.checkList.indexOf('a') !== -1).to.be.true;
vm.$refs.b.$el.click();
vm.$nextTick(() => {
expect(vm.checkList.indexOf('a') !== -1).to.be.true;
expect(vm.checkList.indexOf('b') !== -1).to.be.true;
vm.$refs.c.$el.click();
vm.$nextTick(() => {
expect(vm.checkList.indexOf('c') !== -1).to.be.false;
expect(vm.checkList.indexOf('d') !== -1).to.be.false;
expect(vm.$refs.c.isDisabled).to.be.true;
expect(vm.$refs.d.isDisabled).to.be.true;
done();
});
});
});
});
it('nested group', done => {
vm = createVue({
template: `
<el-checkbox-group v-model="checkList">
<el-row>
<el-checkbox label="a" ref="a"></el-checkbox>
<el-checkbox label="b" ref="b"></el-checkbox>
<el-checkbox label="c" ref="c"></el-checkbox>
<el-checkbox label="d" ref="d"></el-checkbox>
</el-row>
</el-checkbox-group>
`,
data() {
return {
checkList: []
};
}
}, true);
expect(vm.checkList.length === 0).to.be.true;
vm.$refs.a.$el.click();
vm.$nextTick(_ => {
expect(vm.checkList.indexOf('a') !== -1).to.be.true;
done();
});
});
it('true false label', done => {
vm = createVue({
template: `
<el-checkbox true-label="a" :false-label="3" v-model="checked"></el-checkbox>
`,
data() {
return {
checked: 'a'
};
}
}, true);
vm.$el.click();
vm.$nextTick(_ => {
expect(vm.checked === 3).to.be.true;
done();
});
});
it('checked', () => {
vm = createVue({
template: `
<div>
<el-checkbox v-model="checked" checked></el-checkbox>
<el-checkbox-group v-model="checklist">
<el-checkbox checked label="a"></el-checkbox>
</el-checkbox-group>
</div>
`,
data() {
return {
checked: false,
checklist: []
};
}
}, true);
expect(vm.checked).to.be.true;
expect(vm.checklist.indexOf('a') !== -1).to.be.true;
});
describe('checkbox-button', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', done => {
vm = createVue({
template: `
<el-checkbox-button v-model="checked">
</el-checkbox-button>
`,
data() {
return {
checked: false
};
}
}, true);
let checkboxElm = vm.$el;
expect(checkboxElm.classList.contains('el-checkbox-button')).to.be.true;
checkboxElm.click();
vm.$nextTick(_ => {
expect(checkboxElm.classList.contains('is-checked')).to.be.ok;
done();
});
});
it('disabled', () => {
vm = createVue({
template: `
<el-checkbox-button
v-model="checked"
disabled
>
</el-checkbox-button>
`,
data() {
return {
checked: false
};
}
}, true);
let checkboxElm = vm.$el;
expect(checkboxElm.classList.contains('is-disabled')).to.be.ok;
});
it('change event', done => {
vm = createVue({
template: `
<el-checkbox-button v-model="checked" @change="onChange">
</el-checkbox-button>
`,
methods: {
onChange(val) {
this.data = val;
}
},
data() {
return {
data: '',
checked: false
};
}
}, true);
let checkboxElm = vm.$el;
checkboxElm.click();
setTimeout(_ => {
expect(vm.data).to.true;
vm.checked = false;
setTimeout(_ => {
expect(vm.data).to.true;
done();
}, 10);
}, 10);
});
it('checkbox group', done => {
vm = createVue({
template: `
<el-checkbox-group v-model="checkList">
<el-checkbox-button label="a" ref="a"></el-checkbox-button>
<el-checkbox-button label="b" ref="b"></el-checkbox-button>
<el-checkbox-button label="c" ref="c"></el-checkbox-button>
<el-checkbox-button label="d" ref="d"></el-checkbox-button>
</el-checkbox-group>
`,
data() {
return {
checkList: []
};
}
}, true);
expect(vm.checkList.length === 0).to.be.true;
vm.$refs.a.$el.click();
vm.$nextTick(_ => {
expect(vm.checkList.indexOf('a') !== -1).to.be.true;
vm.$refs.b.$el.click();
vm.$nextTick(_ => {
expect(vm.checkList.indexOf('a') !== -1).to.be.true;
expect(vm.checkList.indexOf('b') !== -1).to.be.true;
done();
});
});
});
it('checkbox-button group change event', done => {
vm = createVue({
template: `
<el-checkbox-group v-model="checkList" @change="onChange">
<el-checkbox-button label="a" ref="a"></el-checkbox-button>
<el-checkbox-button label="b" ref="b"></el-checkbox-button>
<el-checkbox-button label="c" ref="c"></el-checkbox-button>
<el-checkbox-button label="d" ref="d"></el-checkbox-button>
</el-checkbox-group>
`,
methods: {
onChange(val) {
this.data = val;
}
},
data() {
return {
data: '',
checkList: []
};
}
}, true);
vm.$refs.a.$el.click();
setTimeout(_ => {
expect(vm.data).to.deep.equal(['a']);
vm.checkList = ['b'];
setTimeout(_ => {
expect(vm.data).to.deep.equal(['a']);
done();
}, 10);
}, 10);
});
it('checkbox group props', () => {
vm = createVue({
template: `
<el-checkbox-group v-model="checkList" size="large" fill="#FF0000" text-color="#000">
<el-checkbox-button label="a" ref="a"></el-checkbox-button>
<el-checkbox-button label="b" ref="b"></el-checkbox-button>
<el-checkbox-button label="c" ref="c"></el-checkbox-button>
<el-checkbox-button label="d" ref="d"></el-checkbox-button>
</el-checkbox-group>
`,
data() {
return {
checkList: ['a', 'd']
};
}
}, true);
expect(vm.checkList.length === 2).to.be.true;
expect(vm.$refs.a.$el.classList.contains('is-checked')).to.be.true;
expect(vm.$refs.a.$el.classList.contains('el-checkbox-button--large')).to.be.true;
expect(vm.$refs.a.$el.querySelector('.el-checkbox-button__inner').style.backgroundColor).to.be.eql('rgb(255, 0, 0)');
expect(vm.$refs.a.$el.querySelector('.el-checkbox-button__inner').style.boxShadow).to.be.eql('rgb(255, 0, 0) -1px 0px 0px 0px');
expect(vm.$refs.a.$el.querySelector('.el-checkbox-button__inner').style.borderColor).to.be.eql('rgb(255, 0, 0)');
expect(vm.$refs.a.$el.querySelector('.el-checkbox-button__inner').style.color).to.be.eql('rgb(0, 0, 0)');
expect(vm.$refs.b.$el.classList.contains('is-checked')).to.be.false;
expect(vm.$refs.c.$el.classList.contains('is-checked')).to.be.false;
expect(vm.$refs.d.$el.classList.contains('is-checked')).to.be.true;
});
it('checkbox group minimum and maximum', done => {
vm = createVue({
template: `
<el-checkbox-group
v-model="checkList"
:min="1"
:max="2"
>
<el-checkbox-button label="a" ref="a"></el-checkbox-button>
<el-checkbox-button label="b" ref="b"></el-checkbox-button>
<el-checkbox-button label="c" ref="c"></el-checkbox-button>
<el-checkbox-button label="d" ref="d"></el-checkbox-button>
</el-checkbox-group>
`,
data() {
return {
checkList: ['a'],
lastEvent: null
};
}
}, true);
expect(vm.checkList.length === 1).to.be.true;
vm.$refs.a.$el.click();
vm.$nextTick(() => {
expect(vm.checkList.indexOf('a') !== -1).to.be.true;
vm.$refs.b.$el.click();
vm.$nextTick(() => {
expect(vm.checkList.indexOf('a') !== -1).to.be.true;
expect(vm.checkList.indexOf('b') !== -1).to.be.true;
vm.$refs.c.$el.click();
vm.$nextTick(() => {
expect(vm.checkList.indexOf('c') !== -1).to.be.false;
expect(vm.checkList.indexOf('d') !== -1).to.be.false;
done();
});
});
});
});
it('nested group', done => {
vm = createVue({
template: `
<el-checkbox-group v-model="checkList">
<el-row>
<el-checkbox-button label="a" ref="a"></el-checkbox-button>
<el-checkbox-button label="b" ref="b"></el-checkbox-button>
<el-checkbox-button label="c" ref="c"></el-checkbox-button>
<el-checkbox-button label="d" ref="d"></el-checkbox-button>
</el-row>
</el-checkbox-group>
`,
data() {
return {
checkList: []
};
}
}, true);
expect(vm.checkList.length === 0).to.be.true;
vm.$refs.a.$el.click();
vm.$nextTick(_ => {
expect(vm.checkList.indexOf('a') !== -1).to.be.true;
done();
});
});
it('true false label', done => {
vm = createVue({
template: `
<el-checkbox-button
true-label="a"
:false-label="3"
v-model="checked"
></el-checkbox-button>
`,
data() {
return {
checked: 'a'
};
}
}, true);
vm.$el.click();
vm.$nextTick(_ => {
expect(vm.checked === 3).to.be.true;
done();
});
});
it('checked', () => {
vm = createVue({
template: `
<div>
<el-checkbox-button v-model="checked" checked></el-checkbox-button>
<el-checkbox-group v-model="checklist">
<el-checkbox-button checked label="a"></el-checkbox-button>
</el-checkbox-group>
</div>
`,
data() {
return {
checked: false,
checklist: []
};
}
}, true);
expect(vm.checked).to.be.true;
expect(vm.checklist.indexOf('a') !== -1).to.be.true;
});
});
});

View File

@@ -0,0 +1,78 @@
import { createVue, destroyVM } from '../util';
describe('Col', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', () => {
vm = createVue({
template: `
<el-col :span="12">
</el-col>
`
}, true);
let colElm = vm.$el;
expect(colElm.classList.contains('el-col')).to.be.true;
});
it('span', () => {
vm = createVue({
template: `
<el-col :span="12">
</el-col>
`
}, true);
let colElm = vm.$el;
expect(colElm.classList.contains('el-col-12')).to.be.true;
});
it('pull', () => {
vm = createVue({
template: `
<el-col :span="12" :pull="3">
</el-col>
`
}, true);
let colElm = vm.$el;
expect(colElm.classList.contains('el-col-pull-3')).to.be.true;
});
it('push', () => {
vm = createVue({
template: `
<el-col :span="12" :push="3">
</el-col>
`
}, true);
let colElm = vm.$el;
expect(colElm.classList.contains('el-col-push-3')).to.be.true;
});
it('gutter', () => {
vm = createVue({
template: `
<el-row :gutter="20">
<el-col :span="12" ref="col">
</el-col>
</el-row>
`
}, true);
let colElm = vm.$refs.col.$el;
expect(colElm.style.paddingLeft === '10px').to.be.true;
expect(colElm.style.paddingRight === '10px').to.be.true;
});
it('responsive', () => {
vm = createVue({
template: `
<el-row :gutter="20">
<el-col ref="col" :sm="{ span: 4, offset: 2 }" :md="8" :lg="{ span: 6, offset: 3 }">
</el-col>
</el-row>
`
}, true);
let colElm = vm.$refs.col.$el;
expect(colElm.classList.contains('el-col-sm-4')).to.be.true;
expect(colElm.classList.contains('el-col-sm-offset-2')).to.be.true;
expect(colElm.classList.contains('el-col-lg-6')).to.be.true;
expect(colElm.classList.contains('el-col-lg-offset-3')).to.be.true;
expect(colElm.classList.contains('el-col-md-8')).to.be.true;
});
});

View File

@@ -0,0 +1,130 @@
import { createVue, destroyVM } from '../util';
describe('Collapse', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', done => {
vm = createVue({
data() {
return {
activeNames: ['1']
};
},
template: `
<el-collapse v-model="activeNames" ref="collapse">
<el-collapse-item title="一致性 Consistency" name="1" ref="item1">
<div>与现实生活一致:与现实生活的流程、逻辑保持一致,遵循用户习惯的语言和概念;</div>
<div>在界面中一致:所有的元素和结构需保持一致,比如:设计样式、图标和文本、元素的位置等。</div>
</el-collapse-item>
<el-collapse-item title="反馈 Feedback" name="2">
<div>控制反馈:通过界面样式和交互动效让用户可以清晰的感知自己的操作;</div>
<div>页面反馈:操作后,通过页面元素的变化清晰地展现当前状态。</div>
</el-collapse-item>
<el-collapse-item title="效率 Efficiency" name="3" ref="item3">
<div>简化流程:设计简洁直观的操作流程;</div>
<div>清晰明确:语言表达清晰且表意明确,让用户快速理解进而作出决策;</div>
<div>帮助用户识别:界面简单直白,让用户快速识别而非回忆,减少用户记忆负担。</div>
</el-collapse-item>
<el-collapse-item title="可控 Controllability" name="4">
<div>用户决策:根据场景可给予用户操作建议或安全提示,但不能代替用户进行决策;</div>
<div>结果可控:用户可以自由的进行操作,包括撤销、回退和终止当前操作等。</div>
</el-collapse-item>
</el-collapse>
`
}, true);
expect(vm.$refs.item1.isActive).to.be.true;
vm.$refs.item3.$el.querySelector('.el-collapse-item__header').click();
vm.$nextTick(_ => {
expect(vm.$refs.item1.isActive).to.be.true;
expect(vm.$refs.item3.isActive).to.be.true;
vm.$refs.item1.$el.querySelector('.el-collapse-item__header').click();
vm.$nextTick(_ => {
expect(vm.$refs.item1.isActive).to.be.false;
done();
});
});
});
it('accordion', done => {
vm = createVue({
data() {
return {
activeNames: ['1']
};
},
template: `
<el-collapse accordion v-model="activeNames" ref="collapse">
<el-collapse-item title="一致性 Consistency" name="1" ref="item1">
<div>与现实生活一致:与现实生活的流程、逻辑保持一致,遵循用户习惯的语言和概念;</div>
<div>在界面中一致:所有的元素和结构需保持一致,比如:设计样式、图标和文本、元素的位置等。</div>
</el-collapse-item>
<el-collapse-item title="反馈 Feedback" name="2">
<div>控制反馈:通过界面样式和交互动效让用户可以清晰的感知自己的操作;</div>
<div>页面反馈:操作后,通过页面元素的变化清晰地展现当前状态。</div>
</el-collapse-item>
<el-collapse-item title="效率 Efficiency" name="3" ref="item3">
<div>简化流程:设计简洁直观的操作流程;</div>
<div>清晰明确:语言表达清晰且表意明确,让用户快速理解进而作出决策;</div>
<div>帮助用户识别:界面简单直白,让用户快速识别而非回忆,减少用户记忆负担。</div>
</el-collapse-item>
<el-collapse-item title="可控 Controllability" name="4">
<div>用户决策:根据场景可给予用户操作建议或安全提示,但不能代替用户进行决策;</div>
<div>结果可控:用户可以自由的进行操作,包括撤销、回退和终止当前操作等。</div>
</el-collapse-item>
</el-collapse>
`
}, true);
expect(vm.$refs.item1.isActive).to.be.true;
vm.$refs.item3.$el.querySelector('.el-collapse-item__header').click();
vm.$nextTick(_ => {
expect(vm.$refs.item1.isActive).to.be.false;
expect(vm.$refs.item3.isActive).to.be.true;
done();
});
});
it('event:change', done => {
vm = createVue({
data() {
return {
activeNames: ['1']
};
},
template: `
<el-collapse v-model="activeNames" ref="collapse">
<el-collapse-item title="一致性 Consistency" name="1" ref="item1">
<div>与现实生活一致:与现实生活的流程、逻辑保持一致,遵循用户习惯的语言和概念;</div>
<div>在界面中一致:所有的元素和结构需保持一致,比如:设计样式、图标和文本、元素的位置等。</div>
</el-collapse-item>
<el-collapse-item title="反馈 Feedback" name="2">
<div>控制反馈:通过界面样式和交互动效让用户可以清晰的感知自己的操作;</div>
<div>页面反馈:操作后,通过页面元素的变化清晰地展现当前状态。</div>
</el-collapse-item>
<el-collapse-item title="效率 Efficiency" name="3" ref="item3">
<div>简化流程:设计简洁直观的操作流程;</div>
<div>清晰明确:语言表达清晰且表意明确,让用户快速理解进而作出决策;</div>
<div>帮助用户识别:界面简单直白,让用户快速识别而非回忆,减少用户记忆负担。</div>
</el-collapse-item>
<el-collapse-item title="可控 Controllability" name="4">
<div>用户决策:根据场景可给予用户操作建议或安全提示,但不能代替用户进行决策;</div>
<div>结果可控:用户可以自由的进行操作,包括撤销、回退和终止当前操作等。</div>
</el-collapse-item>
</el-collapse>
`
}, true);
const spy = sinon.spy();
vm.$refs.collapse.$on('change', spy);
vm.$refs.item3.$el.querySelector('.el-collapse-item__header').click();
vm.$nextTick(_ => {
expect(spy.withArgs().calledOnce).to.be.true;
done();
});
});
});

View File

@@ -0,0 +1,362 @@
import { createTest, createVue, destroyVM } from '../util';
import ColorPicker from 'packages/color-picker';
describe('ColorPicker', () => {
let vm;
afterEach(() => {
vm.$destroy(true);
destroyVM(vm);
const dropdown = document.querySelector('.el-color-dropdown');
if (dropdown && dropdown.parentNode) dropdown.parentNode.removeChild(dropdown);
});
it('should work', () => {
vm = createTest(ColorPicker, true);
expect(vm.$el).to.exist;
});
it('should show alpha slider when show-alpha=true', (done) => {
const vm = createVue({
template: `
<el-color-picker v-model="color" show-alpha></el-color-picker>
`,
data() {
return {
color: null
};
}
}, true);
const trigger = vm.$el.querySelector('.el-color-picker__trigger');
trigger.click();
setTimeout(() => {
const alphaSlider = document.querySelector('.el-color-alpha-slider');
expect(alphaSlider).to.exist;
done();
}, ANIMATION_TIME);
});
it('should show color picker when click trigger', (done) => {
vm = createTest(ColorPicker, true);
const trigger = vm.$el.querySelector('.el-color-picker__trigger');
trigger.click();
vm.$nextTick(() => {
const dropdown = document.querySelector('.el-color-dropdown');
expect(dropdown).to.exist;
done();
});
});
const ANIMATION_TIME = 300;
it('should pick a color when confirm button click', (done) => {
const vm = createVue({
template: `
<el-color-picker v-model="color"></el-color-picker>
`,
data() {
return {
color: null
};
}
}, true);
const trigger = vm.$el.querySelector('.el-color-picker__trigger');
trigger.click();
setTimeout(() => {
const dropdown = document.querySelector('.el-color-dropdown__btn');
dropdown.click();
vm.$nextTick(() => {
expect(vm.color).to.equal('#FF0000');
done();
});
}, ANIMATION_TIME);
});
it('should show correct rgb value', (done) => {
const vm = createVue({
template: `
<el-color-picker v-model="color"></el-color-picker>
`,
data() {
return {
color: '#20A0FF'
};
}
}, true);
const trigger = vm.$el.querySelector('.el-color-picker__trigger');
trigger.click();
setTimeout(() => {
const input = document.querySelector('.el-color-dropdown__value input');
expect(input.value.trim().toUpperCase()).to.equal('#20A0FF');
done();
}, ANIMATION_TIME);
});
it('should init the right color when open', (done) => {
const vm = createVue({
template: `
<el-color-picker v-model="color"></el-color-picker>
`,
data() {
return {
color: '#0f0'
};
}
}, true);
const trigger = vm.$el.querySelector('.el-color-picker__trigger');
trigger.click();
setTimeout(() => {
const dropdown = document.querySelector('.el-color-dropdown__btn');
dropdown.click();
vm.$nextTick(() => {
const hueBar = document.querySelector('.el-color-hue-slider__thumb');
const top = parseInt(hueBar.style.top, 10);
expect(top > 10).to.be.true;
done();
});
}, ANIMATION_TIME);
});
it('should clear a color when clear button click', (done) => {
const vm = createVue({
template: `
<el-color-picker v-model="color"></el-color-picker>
`,
data() {
return {
color: '#f00'
};
}
}, true);
const trigger = vm.$el.querySelector('.el-color-picker__trigger');
trigger.click();
setTimeout(() => {
const clearBtn = document.querySelector('.el-color-dropdown__link-btn');
clearBtn.click();
setTimeout(() => {
expect(vm.color).to.equal(null);
done();
}, 30);
}, ANIMATION_TIME);
});
it('should change hue when clicking the hue bar', (done) => {
const vm = createVue({
template: `
<el-color-picker v-model="color"></el-color-picker>
`,
data() {
return {
color: '#f00'
};
}
}, true);
const trigger = vm.$el.querySelector('.el-color-picker__trigger');
trigger.click();
setTimeout(() => {
const hueBar = document.querySelector('.el-color-hue-slider');
hueBar.__vue__.handleClick({ target: null, clientX: 0, clientY: 1000 });
vm.$nextTick(() => {
const picker = vm.$children[0];
expect(picker.color._hue > 0).to.true;
done();
});
}, ANIMATION_TIME);
});
it('should change hue when saturation is zero', (done) => {
const vm = createVue({
template: `
<el-color-picker v-model="color"></el-color-picker>
`,
data() {
return {
color: '#FFFFFF'
};
}
}, true);
const trigger = vm.$el.querySelector('.el-color-picker__trigger');
trigger.click();
setTimeout(() => {
const hueBar = document.querySelector('.el-color-hue-slider');
hueBar.__vue__.handleClick({ target: null, clientX: 0, clientY: 1000 });
vm.$nextTick(() => {
const thumb = document.querySelector('.el-color-hue-slider__thumb');
expect(parseInt(thumb.style.top, 10) > 0).to.true;
done();
});
}, ANIMATION_TIME);
});
it('should change alpha when clicking the alpha bar', (done) => {
const vm = createVue({
template: `
<el-color-picker v-model="color" show-alpha></el-color-picker>
`,
data() {
return {
color: '#f00'
};
}
}, true);
const trigger = vm.$el.querySelector('.el-color-picker__trigger');
trigger.click();
setTimeout(() => {
const alphaBar = document.querySelector('.el-color-alpha-slider');
alphaBar.__vue__.handleClick({ target: null, clientX: 50, clientY: 0 });
vm.$nextTick(() => {
const picker = vm.$children[0];
expect(picker.color._alpha < 100).to.true;
done();
});
}, ANIMATION_TIME);
});
it('should change saturation and value when clicking the sv-panel', (done) => {
const vm = createVue({
template: `
<el-color-picker v-model="color" color-format="hsv"></el-color-picker>
`,
data() {
return {
color: 'hsv(0, 50%, 50%)'
};
}
}, true);
const trigger = vm.$el.querySelector('.el-color-picker__trigger');
trigger.click();
setTimeout(() => {
const svPanel = document.querySelector('.el-color-svpanel');
svPanel.__vue__.handleDrag({ clientX: 0, clientY: 0 });
vm.$nextTick(() => {
const picker = vm.$children[0];
expect(picker.color._saturation !== 50).to.true;
expect(picker.color._value !== 50).to.true;
done();
});
}, ANIMATION_TIME);
});
it('should change color to the selected color', done => {
const vm = createVue({
template: `
<el-color-picker v-model="color" show-alpha :predefine="colors"></el-color-picker>
`,
data() {
return {
color: 'hsva(180, 65, 20, 0.5)',
colors: [
'rgba(19, 206, 102, 0.18)',
'rgb(25, 159, 147)',
'hsv(250, 54, 98)',
'hsva(180, 65, 20, 0.5)',
'hsl(170, 32%, 87%)',
'hsla(45, 62%, 47%, 0.13)',
'#7486de',
'#45aa9477',
'#892345'
]
};
}
}, true);
const trigger = vm.$el.querySelector('.el-color-picker__trigger');
trigger.click();
setTimeout(() => {
expect(document.querySelectorAll('.el-color-predefine__color-selector').length === 9).to.be.true;
const selector = document.querySelector('.el-color-predefine__color-selector:nth-child(4)');
selector.click();
vm.$nextTick(() => {
const picker = vm.$children[0];
expect(picker.color._hue === 180).to.be.true;
expect(picker.color._saturation === 65).to.be.true;
expect(picker.color._value === 20).to.be.true;
expect(picker.color._alpha === 50).to.be.true;
const selector2 = document.querySelector('.el-color-predefine__color-selector:nth-child(3)');
selector2.click();
vm.$nextTick(() => {
expect(picker.color._hue === 250).to.be.true;
expect(picker.color._saturation === 54).to.be.true;
expect(picker.color._value === 98).to.be.true;
expect(picker.color._alpha === 100).to.be.true;
done();
});
});
});
});
it('should change selected state of predefined color', done => {
const vm = createVue({
template: `
<el-color-picker v-model="color" show-alpha :predefine="colors"></el-color-picker>
`,
data() {
return {
color: 'hsva(180, 65, 20, 0.5)',
colors: [
'rgba(19, 206, 102, 0.18)',
'rgb(25, 159, 147)',
'hsv(250, 54, 98)',
'hsva(180, 65, 20, 0.5)',
'hsl(170, 32%, 87%)',
'hsla(45, 62%, 47%, 0.13)',
'#7486de',
'#45aa9477',
'#892345'
]
};
}
}, true);
const trigger = vm.$el.querySelector('.el-color-picker__trigger');
trigger.click();
setTimeout(() => {
const selector = document.querySelector('.el-color-predefine__color-selector:nth-child(4)');
selector.click();
vm.$nextTick(() => {
expect(selector.classList.contains('selected')).to.be.true;
const hueBar = document.querySelector('.el-color-hue-slider');
hueBar.__vue__.handleClick({ target: null, clientX: 0, clientY: 1000 });
vm.$nextTick(() => {
expect(selector.classList.contains('selected')).to.be.false;
done();
});
});
});
});
});

View File

@@ -0,0 +1,128 @@
import { createTest, createVue, destroyVM } from '../util';
import Container from 'packages/container';
import Header from 'packages/header';
import Main from 'packages/main';
import Aside from 'packages/aside';
import Footer from 'packages/footer';
describe('Container', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', () => {
vm = createTest(Container, true);
expect(vm.$el).to.exist;
});
it('vertical', () => {
vm = createVue({
template: `
<el-container>
<el-header></el-header>
<el-main></el-main>
</el-container>
`
}, true);
expect(vm.$children[0].$el.classList.contains('is-vertical')).to.true;
});
it('direction', done => {
vm = createVue({
template: `
<el-container :direction="direction">
<el-header></el-header>
<el-main></el-main>
</el-container>
`,
data() {
return {
direction: 'horizontal'
};
}
}, true);
expect(vm.$children[0].$el.classList.contains('is-vertical')).not.to.true;
vm.direction = 'vertical';
vm.$nextTick(() => {
expect(vm.$children[0].$el.classList.contains('is-vertical')).to.true;
done();
});
});
});
describe('Header', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', () => {
vm = createTest(Header, true);
expect(vm.$el).to.exist;
});
it('height', () => {
vm = createVue({
template: `
<el-header height="100px"></el-header>
`
}, true);
expect(vm.$children[0].$el.style.height).to.equal('100px');
});
});
describe('Aside', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', () => {
vm = createTest(Aside, true);
expect(vm.$el).to.exist;
});
it('width', () => {
vm = createVue({
template: `
<el-aside width="200px"></el-aside>
`
}, true);
expect(vm.$children[0].$el.style.width).to.equal('200px');
});
});
describe('Main', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', () => {
vm = createTest(Main, true);
expect(vm.$el).to.exist;
});
});
describe('Footer', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', () => {
vm = createTest(Footer, true);
expect(vm.$el).to.exist;
});
it('height', () => {
vm = createVue({
template: `
<el-footer height="100px"></el-footer>
`
}, true);
expect(vm.$children[0].$el.style.height).to.equal('100px');
});
});

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,319 @@
import { createVue, destroyVM, waitImmediate } from '../util';
describe('Dialog', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', done => {
vm = createVue({
template: `
<div>
<el-dialog :title="title" :visible="visible"></el-dialog>
</div>
`,
data() {
return {
title: 'dialog test',
visible: true
};
}
}, true);
const dialog = vm.$children[0];
setTimeout(() => {
expect(document.querySelector('.v-modal')).to.exist;
expect(vm.$el.querySelector('.el-dialog__title').textContent).to.equal('dialog test');
expect(dialog.$el.style.display).to.not.equal('none');
done();
}, 10);
});
it('render correct content', done => {
vm = createVue({
template: `
<div>
<el-dialog :title="title" :visible="visible">
<span>这是一段信息</span>
<span slot="footer" class="dialog-footer">
<el-button @click.native="dialogVisible = false">取消</el-button>
<el-button type="primary" @click.native="dialogVisible = false">确定</el-button>
</span>
</el-dialog>
</div>
`,
data() {
return {
title: 'dialog test',
visible: true
};
}
}, true);
setTimeout(() => {
const footerBtns = vm.$el.querySelectorAll('.el-dialog__footer .el-button');
expect(vm.$el.querySelector('.el-dialog__body span').textContent).to.equal('这是一段信息');
expect(footerBtns.length).to.equal(2);
expect(footerBtns[0].querySelector('span').textContent).to.equal('取消');
expect(footerBtns[1].querySelector('span').textContent).to.equal('确定');
done();
}, 100);
});
it('append to body', done => {
vm = createVue({
template: `
<div>
<el-dialog :title="title" append-to-body :visible="visible"></el-dialog>
</div>
`,
data() {
return {
title: 'dialog test',
visible: true
};
}
}, true);
const dialog = vm.$children[0];
setTimeout(() => {
expect(dialog.$el.parentNode).to.equal(document.body);
done();
}, 10);
});
it('open and close', done => {
vm = createVue({
template: `
<div>
<el-dialog :title="title" :visible.sync="visible">
<span>这是一段信息</span>
</el-dialog>
</div>
`,
data() {
return {
title: 'dialog test',
visible: false
};
}
}, true);
const dialogEl = vm.$children[0].$el;
expect(getComputedStyle(dialogEl).display).to.equal('none');
vm.visible = true;
setTimeout(() => {
expect(getComputedStyle(dialogEl).display).to.not.equal('none');
vm.visible = false;
setTimeout(() => {
expect(getComputedStyle(dialogEl).display).to.equal('none');
done();
}, 400);
}, 50);
});
describe('props', () => {
const getDialogVm = (props, options) => {
return createVue(Object.assign({
template: `
<div>
<el-dialog ${ props } :title="title" :visible="visible">
<span>这是一段信息</span>
</el-dialog>
</div>
`,
data() {
return {
title: 'dialog test',
visible: true
};
}
}, options), true);
};
it('fullscreen', () => {
vm = getDialogVm('fullscreen width="40%"');
const dialogEl = vm.$el.querySelector('.el-dialog');
expect(dialogEl.classList.contains('is-fullscreen')).to.true;
expect(dialogEl.style.width).to.be.empty;
});
it('top', () => {
vm = getDialogVm('top="100px"');
expect(vm.$el.querySelector('.el-dialog').style.marginTop).to.equal('100px');
});
it('custom-class', () => {
vm = getDialogVm('custom-class="my-dialog"');
expect(vm.$el.querySelector('.el-dialog').classList.contains('my-dialog')).to.true;
});
});
it('events', done => {
vm = createVue({
template: `
<div>
<el-dialog
@open="handleOpen"
@opened="handleOpened"
@close="handleClose"
@closed="handleClosed"
:title="title"
:visible.sync="visible">
<span>这是一段信息</span>
</el-dialog>
</div>
`,
methods: {
handleOpen() {
this.state = 'open';
},
handleOpened() {
this.animationState = 'opened';
},
handleClose() {
this.state = 'close';
},
handleClosed() {
this.animationState = 'closed';
}
},
data() {
return {
state: '',
animationState: '',
title: 'dialog test',
visible: false
};
}
}, true);
vm.visible = true;
setTimeout(() => {
expect(vm.state).to.equal('open');
expect(vm.animationState).to.equal('opened');
vm.visible = false;
setTimeout(() => {
expect(vm.state).to.equal('close');
expect(vm.animationState).to.equal('closed');
done();
}, 400);
}, 400);
});
it('click dialog to close', done => {
vm = createVue({
template: `
<div>
<el-dialog :title="title" :visible.sync="visible">
<span>这是一段信息</span>
</el-dialog>
</div>
`,
data() {
return {
title: 'dialog test',
visible: true
};
}
}, true);
const dialog = vm.$children[0];
setTimeout(() => {
dialog.$el.click();
setTimeout(() => {
expect(vm.visible).to.be.false;
done();
}, 400);
}, 50);
});
it('click header btn', done => {
vm = createVue({
template: `
<div>
<el-dialog :title="title" :visible.sync="visible">
<span>这是一段信息</span>
</el-dialog>
</div>
`,
data() {
return {
title: 'dialog test',
visible: true
};
}
}, true);
const dialog = vm.$children[0];
setTimeout(() => {
dialog.$el.querySelector('.el-dialog__headerbtn').click();
setTimeout(() => {
expect(vm.visible).to.be.false;
done();
}, 500);
}, 50);
});
it('before close', done => {
const spy = sinon.spy();
vm = createVue({
template: `
<div>
<el-dialog :title="title" :visible="visible" :before-close="beforeClose"></el-dialog>
</div>
`,
data() {
return {
title: 'dialog test',
visible: true
};
},
methods: {
beforeClose(done) {
spy();
done();
}
}
}, true);
const dialog = vm.$children[0];
setTimeout(() => {
dialog.$el.click();
setTimeout(() => {
expect(spy.called).to.be.true;
done();
}, 500);
}, 10);
});
it('destroyOnClose', async() => {
vm = createVue({
template: `
<div>
<el-dialog :title="title" :visible.sync="visible" destroy-on-close>
<input />
</el-dialog>
</div>
`,
data() {
return {
title: 'dialog test',
visible: true
};
}
}, true);
const dialog = vm.$children[0];
await waitImmediate();
dialog.$el.querySelector('input').value = '123';
dialog.$el.click();
await waitImmediate();
vm.visible = true;
await waitImmediate();
expect(dialog.$el.querySelector('input').value).to.be.equal('');
});
});

View File

@@ -0,0 +1,37 @@
import { createVue, destroyVM } from '../util';
describe('Divider', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('content', () => {
vm = createVue({
template: `
<el-divider>我是一条完美分割线!</el-divider>
`
});
expect(vm.$el).to.property('textContent').to.include('我是一条完美分割线!');
});
it('direction', () => {
vm = createVue({
template: `
<el-divider direction="vertical">我是一条完美分割线!</el-divider>
`
});
expect(vm.$el.className).to.include('el-divider--vertical');
});
it('apply class to divider', () => {
vm = createVue({
template: `
<el-divider direction="vertical" class="my-divider">我是一条完美分割线!</el-divider>
`
});
expect(vm.$el.className).to.include('my-divider');
});
});

View File

@@ -0,0 +1,350 @@
import { createVue, destroyVM, waitImmediate, wait } from '../util';
const title = '我是测试 title';
const content = 'content';
describe('Drawer', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', async() => {
vm = createVue(
{
template: `
<el-drawer :title='title' :visible='visible'></el-drawer>
`,
data() {
return {
title,
visible: true
};
}
},
true
);
const drawer = vm.$children[0];
await waitImmediate();
expect(document.querySelector('.v-modal')).to.exist;
expect(vm.$el.querySelector('.el-drawer__header').textContent).to.equal(
title
);
expect(drawer.$el.style.display).to.not.equal('none');
});
it('render correct content', async() => {
vm = createVue(
{
template: `
<el-drawer :title='title' :visible='visible'>
<span>这是一段信息</span>
<el-button @click.native='dialogVisible = false'>取消</el-button>
<el-button type='primary' @click.native='dialogVisible = false'>确定</el-button>
</el-drawer>
`,
data() {
return {
title: 'drawer test',
visible: true
};
}
},
true
);
await waitImmediate();
expect(vm.$el.querySelector('.el-drawer__body span').textContent).to.equal(
'这是一段信息'
);
const footerBtns = vm.$el.querySelectorAll('.el-button');
expect(footerBtns.length).to.equal(2);
expect(footerBtns[0].querySelector('span').textContent).to.equal('取消');
expect(footerBtns[1].querySelector('span').textContent).to.equal('确定');
});
it('should append to body, when append-to-body flag is true', async() => {
vm = createVue(
{
template: `
<el-drawer :title='title' :visible='visible' :append-to-body='true'>
<span> content </span>
</el-drawer>
`,
data() {
return {
title,
visible: true
};
}
},
true
);
await waitImmediate();
expect(vm.$el.parentNode).to.equal(document.body);
});
it('should open and close drawer properly', async() => {
vm = createVue({
template: `
<el-drawer :title='title' :visible='visible' ref='drawer'>
<span>${content}</span>
</el-drawer>
`,
data() {
return {
title,
visible: false
};
}
});
let drawer = vm.$children[0].$el;
expect(drawer.style.display).to.equal('none');
vm.visible = true;
await waitImmediate();
expect(drawer.style.display).not.to.equal('none');
vm.visible = false;
await wait(400);
expect(drawer.style.display).to.equal('none');
});
it('should destroy every child after drawer was closed when destroy-on-close flag is true', async() => {
vm = createVue({
template: `
<el-drawer :title='title' :visible='visible' :append-to-body='true' :destroy-on-close='true' ref='drawer'>
<span>${content}</span>
</el-drawer>
`,
data() {
return {
title,
visible: true
};
}
});
await waitImmediate();
expect(vm.$el.querySelector('.el-drawer__body span').textContent).to.equal(
content
);
vm.$refs.drawer.closeDrawer();
await wait(400);
expect(vm.$el.querySelector('.el-drawer__body')).not.to.exist;
});
it('should close dialog by clicking the close button', async() => {
vm = createVue({
template: `
<el-drawer :title='title' :visible.sync='visible' :append-to-body='true' :destroy-on-close='true' ref='drawer'>
<span>${content}</span>
</el-drawer>
`,
data() {
return {
title,
visible: true
};
}
});
await waitImmediate();
vm.$children[0].$el.querySelector('.el-drawer__close-btn').click();
expect(vm.visible).to.equal(false);
});
it('should invoke before-close', async() => {
const beforeClose = sinon.spy();
vm = createVue({
template: `
<el-drawer
:before-close='beforeClose'
:title='title'
:visible.sync='visible'
:append-to-body='true'
:destroy-on-close='true'
ref='drawer'
>
<span>${content}</span>
</el-drawer>
`,
data() {
return {
title,
visible: true,
beforeClose
};
}
});
await waitImmediate();
vm.$refs.drawer.closeDrawer();
await waitImmediate();
expect(beforeClose.called).to.be.true;
});
it('should not show close button when show-close flag is false', async() => {
vm = createVue({
template: `
<el-drawer :title='title' :visible='visible' ref='drawer' :show-close='false'>
<span>${content}</span>
</el-drawer>
`,
data() {
return {
title,
visible: false
};
}
});
expect(vm.$el.querySelector('.el-drawer__close-btn')).not.to.exist;
});
it('should have custom classes when custom classes were given', async() => {
const classes = 'some-custom-class';
vm = createVue({
template: `
<el-drawer :title='title' :visible='visible' ref='drawer' custom-class='${classes}'>
<span>${content}</span>
</el-drawer>
`,
data() {
return {
title,
visible: false
};
}
});
expect(vm.$el.querySelector(`.${classes}`)).to.exist;
});
it('should not render header when withHeader attribute is false', () => {
vm = createVue({
template: `
<el-drawer :title='title' :visible='visible' ref='drawer' :with-header='false'>
<span>${content}</span>
</el-drawer>
`,
data() {
return {
title,
visible: true
};
}
});
expect(vm.$el.querySelector('.el-drawer__header')).to.not.exist;
});
describe('directions', () => {
const renderer = direction => {
return createVue({
template: `
<el-drawer :title='title' :visible='visible' direction='${direction}'>
<span>${content}</span>
</el-drawer>
`,
data: {
visible: true,
title
}
});
};
it('should render from left to right', async() => {
vm = renderer('ltr');
await waitImmediate();
expect(vm.$el.querySelector('.ltr')).to.exist;
});
it('should render from right to left', async() => {
vm = renderer('rtl');
await waitImmediate();
expect(vm.$el.querySelector('.rtl')).to.exist;
});
it('should render from top to bottom', async() => {
vm = renderer('ttb');
await waitImmediate();
expect(vm.$el.querySelector('.ttb')).to.exist;
});
it('should render from bottom to top', async() => {
vm = renderer('btt');
await waitImmediate();
expect(vm.$el.querySelector('.btt')).to.exist;
});
});
it('events', async() => {
const open = sinon.spy();
const opened = sinon.spy();
const close = sinon.spy();
const closed = sinon.spy();
vm = createVue({
template: `
<el-drawer
:title='title'
:visible='visible'
ref="drawer"
@open="open"
@opened="opened"
@close="close"
@closed="closed">
<span>${content}</span>
</el-drawer>
`,
data() {
return {
content,
visible: false,
title
};
},
methods: {
close,
closed,
open,
opened
}
});
vm.visible = true;
await wait(400);
expect(open.called).to.be.true;
expect(opened.called).to.be.true;
expect(close.called).to.be.false;
expect(closed.called).to.be.false;
vm.visible = false;
await wait(500);
expect(close.called).to.be.true;
expect(closed.called).to.be.true;
});
describe('size', () => {
const renderer = (size, isVertical) =>
createVue({
template: `
<el-drawer :title='title' :visible='visible' direction='${isVertical ? 'ltr' : 'ttb'}' size='${size}'>
<span>${content}</span>
</el-drawer>
`,
data: {
visible: true,
title
}
});
it('should effect height when drawer is vertical', async() => {
const size = '50%';
vm = renderer(size, true);
expect(vm.$el.querySelector('.el-drawer').style.width).to.equal('50%');
});
it('should effect width when drawer is horizontal', async() => {
const size = '50%';
vm = renderer(size, false);
expect(vm.$el.querySelector('.el-drawer').style.height).to.equal('50%');
});
});
});

View File

@@ -0,0 +1,283 @@
import { createVue, triggerEvent, destroyVM, triggerKeyDown } from '../util';
describe('Dropdown', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', done => {
vm = createVue({
template: `
<el-dropdown ref="dropdown">
<span class="el-dropdown-link">
下拉菜单<i class="el-icon-caret-bottom el-icon-right"></i>
</span>
<el-dropdown-menu slot="dropdown" class="dropdown-test-creat">
<el-dropdown-item>黄金糕</el-dropdown-item>
<el-dropdown-item>狮子头</el-dropdown-item>
<el-dropdown-item>螺蛳粉</el-dropdown-item>
<el-dropdown-item>双皮奶</el-dropdown-item>
<el-dropdown-item>蚵仔煎</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
`
}, true);
let dropdown = vm.$refs.dropdown;
let dropdownElm = dropdown.$el;
let triggerElm = dropdownElm.children[0];
triggerEvent(triggerElm, 'mouseenter');
setTimeout(_ => {
expect(dropdown.visible).to.be.true;
triggerEvent(triggerElm, 'mouseleave');
setTimeout(_ => {
expect(dropdown.visible).to.not.true;
done();
}, 300);
}, 400);
});
it('menu click', done => {
const myCommandObject = { name: 'CommandC' };
vm = createVue({
template: `
<el-dropdown ref="dropdown">
<span class="el-dropdown-link">
下拉菜单<i class="el-icon-caret-bottom el-icon-right"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="a">黄金糕</el-dropdown-item>
<el-dropdown-item command="b">狮子头</el-dropdown-item>
<el-dropdown-item ref="commandC" :command="myCommandObject">螺蛳粉</el-dropdown-item>
<el-dropdown-item command="d">双皮奶</el-dropdown-item>
<el-dropdown-item command="e">蚵仔煎</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
`,
data() {
return {
myCommandObject
};
}
}, true);
let dropdown = vm.$refs.dropdown;
let dropdownElm = dropdown.$el;
let triggerElm = dropdownElm.children[0];
let callback = sinon.spy();
dropdown.$on('command', callback);
triggerEvent(triggerElm, 'mouseenter');
setTimeout(_ => {
vm.$refs.commandC.$el.click();
setTimeout(_ => {
expect(dropdown.visible).to.not.true;
expect(callback.calledWith(myCommandObject)).to.be.true;
done();
}, 300);
}, 300);
});
it('trigger', done => {
vm = createVue({
template: `
<el-dropdown trigger="click" ref="dropdown">
<span class="el-dropdown-link">
下拉菜单trigger click<i class="el-icon-caret-bottom el-icon-right"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>黄金糕</el-dropdown-item>
<el-dropdown-item @click.native="handleClick">狮子头</el-dropdown-item>
<el-dropdown-item>螺蛳粉</el-dropdown-item>
<el-dropdown-item>双皮奶</el-dropdown-item>
<el-dropdown-item>蚵仔煎</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
`
}, true);
let dropdownElm = vm.$el;
let dropdown = vm.$refs.dropdown;
let triggerElm = dropdownElm.children[0];
triggerEvent(triggerElm, 'mouseenter');
dropdown.$nextTick(_ => {
expect(dropdown.visible).to.not.true;
triggerElm.click();
setTimeout(_ => {
expect(dropdown.visible).to.be.true;
done();
}, 300);
});
});
it('split button', done => {
vm = createVue({
template: `
<el-dropdown split-button type="primary" ref="dropdown">
更多菜单
<el-dropdown-menu slot="dropdown" class="dropdown-test-split-button">
<el-dropdown-item>黄金糕</el-dropdown-item>
<el-dropdown-item>狮子头</el-dropdown-item>
<el-dropdown-item>螺蛳粉</el-dropdown-item>
<el-dropdown-item>双皮奶</el-dropdown-item>
<el-dropdown-item>蚵仔煎</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
`
}, true);
let dropdown = vm.$refs.dropdown;
let dropdownElm = dropdown.$el;
let triggerElm = dropdownElm.querySelector('.el-dropdown__caret-button');
var callback = sinon.spy();
dropdown.$on('click', callback);
dropdownElm.querySelector('.el-button').click();
setTimeout(_ => {
expect(callback.called).to.be.true;
}, 300);
triggerEvent(triggerElm, 'mouseenter');
setTimeout(_ => {
expect(dropdown.visible).to.be.true;
triggerEvent(triggerElm, 'mouseleave');
setTimeout(_ => {
expect(dropdown.visible).to.not.true;
done();
}, 300);
}, 300);
});
it('hide on click', done => {
vm = createVue({
template: `
<el-dropdown ref="dropdown" :hide-on-click="false">
<span class="el-dropdown-link">
下拉菜单<i class="el-icon-caret-bottom el-icon-right"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="a">黄金糕</el-dropdown-item>
<el-dropdown-item command="b">狮子头</el-dropdown-item>
<el-dropdown-item ref="commandC" command="c">螺蛳粉</el-dropdown-item>
<el-dropdown-item command="d">双皮奶</el-dropdown-item>
<el-dropdown-item command="e">蚵仔煎</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
`
}, true);
let dropdown = vm.$refs.dropdown;
let dropdownElm = dropdown.$el;
let triggerElm = dropdownElm.children[0];
let callback = sinon.spy();
dropdown.$on('command', callback);
triggerEvent(triggerElm, 'mouseenter');
setTimeout(_ => {
vm.$refs.commandC.$el.click();
setTimeout(_ => {
expect(dropdown.visible).to.true;
expect(callback.calledWith('c')).to.be.true;
done();
}, 300);
}, 300);
});
it('triggerElm keydown', done => {
vm = createVue({
template: `
<el-dropdown ref="dropdown">
<span class="el-dropdown-link">
下拉菜单<i class="el-icon-caret-bottom el-icon-right"></i>
</span>
<el-dropdown-menu slot="dropdown" class="dropdown-test-creat">
<el-dropdown-item>黄金糕</el-dropdown-item>
<el-dropdown-item>狮子头</el-dropdown-item>
<el-dropdown-item>螺蛳粉</el-dropdown-item>
<el-dropdown-item>双皮奶</el-dropdown-item>
<el-dropdown-item>蚵仔煎</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
`
}, true);
let dropdown = vm.$refs.dropdown;
let dropdownElm = dropdown.$el;
let triggerElm = dropdownElm.children[0];
triggerKeyDown(triggerElm, 13); // enter
setTimeout(() => {
expect(dropdown.visible).to.be.true;
triggerKeyDown(triggerElm, 27); // esc
setTimeout(() => {
expect(dropdown.visible).to.be.false;
done();
}, 300);
}, 400);
});
it('dropdown menu keydown', done => {
vm = createVue({
template: `
<el-dropdown ref="dropdown">
<span class="el-dropdown-link">
下拉菜单<i class="el-icon-caret-bottom el-icon-right"></i>
</span>
<el-dropdown-menu slot="dropdown" class="dropdown-test-creat">
<el-dropdown-item command="a">黄金糕</el-dropdown-item>
<el-dropdown-item command="b">狮子头</el-dropdown-item>
<el-dropdown-item command="c">螺蛳粉</el-dropdown-item>
<el-dropdown-item command="d">双皮奶</el-dropdown-item>
<el-dropdown-item command="e">蚵仔煎</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
`
}, true);
let dropdown = vm.$refs.dropdown;
let dropdownElm = dropdown.$el;
let triggerElm = dropdownElm.children[0];
let dropdownMenu = dropdown.dropdownElm;
triggerEvent(triggerElm, 'mouseenter');
setTimeout(() => {
expect(dropdown.visible).to.be.true;
triggerKeyDown(dropdownMenu, 40); // down
setTimeout(() => {
triggerKeyDown(dropdownMenu, 13); // enter
setTimeout(() => {
expect(dropdown.visible).to.be.false;
done();
}, 100);
}, 100);
}, 300);
});
it('updatePopper', done => {
vm = createVue({
template: `
<el-dropdown ref="dropdown">
<span class="el-dropdown-link">
下拉菜单<i class="el-icon-caret-bottom el-icon-right"></i>
</span>
<el-dropdown-menu slot="dropdown" class="dropdown-test-creat">
<el-dropdown-item>黄金糕</el-dropdown-item>
<el-dropdown-item>狮子头</el-dropdown-item>
<el-dropdown-item>螺蛳粉</el-dropdown-item>
<el-dropdown-item>双皮奶</el-dropdown-item>
<el-dropdown-item>蚵仔煎</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
`
}, true);
let dropdown = vm.$refs.dropdown;
let dropdownElm = dropdown.$el;
let triggerElm = dropdownElm.children[0];
triggerEvent(triggerElm, 'mouseenter');
setTimeout(() => {
const zIndex1 = document.querySelector('.el-dropdown-menu').style.zIndex;
dropdown.broadcast('ElDropdownMenu', 'updatePopper');
setTimeout(() => {
const zIndex2 = document.querySelector('.el-dropdown-menu').style.zIndex;
expect(zIndex2 > zIndex1).to.be.true;
done();
}, 100);
}, 300);
});
});

View File

@@ -0,0 +1,993 @@
import { createVue, destroyVM, waitImmediate } from '../util';
const DELAY = 50;
describe('Form', () => {
let vm;
let hasPromise = true;
before(() => {
if (!window.Promise) {
hasPromise = false;
window.Promise = require('es6-promise').Promise;
}
});
after(() => {
if (!hasPromise) {
window.Promise = undefined;
}
});
afterEach(() => {
destroyVM(vm);
});
it('label width', done => {
vm = createVue({
template: `
<el-form ref="form" :model="form" label-width="80px">
<el-form-item label="活动名称">
<el-input v-model="form.name"></el-input>
</el-form-item>
</el-form>
`,
data() {
return {
form: {
name: ''
}
};
}
}, true);
expect(vm.$el.querySelector('.el-form-item__label').style.width).to.equal('80px');
expect(vm.$el.querySelector('.el-form-item__content').style.marginLeft).to.equal('80px');
done();
});
it('auto label width', async() => {
vm = createVue({
template: `
<el-form ref="form" :model="form" label-width="auto">
<el-form-item label="活动名称">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="活动备注信息" v-if="display">
<el-input v-model="form.name"></el-input>
</el-form-item>
</el-form>
`,
data() {
return {
display: true,
form: {
name: '',
intro: ''
}
};
}
}, true);
await waitImmediate();
const formItems = vm.$el.querySelectorAll('.el-form-item__content');
const marginLeft = parseInt(formItems[0].style.marginLeft, 10);
const marginLeft1 = parseInt(formItems[1].style.marginLeft, 10);
expect(marginLeft === marginLeft1).to.be.true;
vm.display = false;
await waitImmediate();
const formItem = vm.$el.querySelector('.el-form-item__content');
const newMarginLeft = parseInt(formItem.style.marginLeft, 10);
expect(newMarginLeft < marginLeft).to.be.true;
});
it('inline form', done => {
vm = createVue({
template: `
<el-form ref="form" :model="form" inline>
<el-form-item>
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item>
<el-input v-model="form.address"></el-input>
</el-form-item>
</el-form>
`,
data() {
return {
form: {
name: '',
address: ''
}
};
}
}, true);
expect(vm.$el.classList.contains('el-form--inline')).to.be.true;
done();
});
it('label position', done => {
vm = createVue({
template: `
<div>
<el-form :model="form" label-position="top" ref="labelTop">
<el-form-item>
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item>
<el-input v-model="form.address"></el-input>
</el-form-item>
</el-form>
<el-form :model="form" label-position="left" ref="labelLeft">
<el-form-item>
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item>
<el-input v-model="form.address"></el-input>
</el-form-item>
</el-form>
</div>
`,
data() {
return {
form: {
name: '',
address: ''
}
};
}
}, true);
expect(vm.$refs.labelTop.$el.classList.contains('el-form--label-top')).to.be.true;
expect(vm.$refs.labelLeft.$el.classList.contains('el-form--label-left')).to.be.true;
done();
});
it('label size', () => {
vm = createVue({
template: `
<div>
<el-form :model="form" size="mini" ref="labelMini">
<el-form-item>
<el-input v-model="form.name"></el-input>
</el-form-item>
</el-form>
</div>
`,
data() {
return {
form: {
name: ''
}
};
}
}, true);
expect(vm.$refs.labelMini.$el.children[0].classList.contains('el-form-item--mini')).to.be.true;
});
it('show message', done => {
vm = createVue({
template: `
<el-form :model="form" ref="form">
<el-form-item label="活动名称" prop="name" :show-message="false"
:rules="{
required: true,
message: '请输入活动名称',
trigger: 'change',
min: 3,
max: 6
}"
>
<el-input v-model="form.name"></el-input>
</el-form-item>
</el-form>
`,
data() {
return {
form: {
name: ''
}
};
}
}, true);
vm.$refs.form.validate(valid => {
expect(valid).to.not.true;
vm.$refs.form.$nextTick(_ => {
expect(vm.$el.querySelector('.el-form-item__error')).to.not.exist;
done();
});
});
});
it('reset field', done => {
vm = createVue({
template: `
<el-form ref="form" :model="form" :rules="rules">
<el-form-item label="活动名称" prop="name">
<el-input v-model="form.name" ref="fieldName"></el-input>
</el-form-item>
<el-form-item label="活动地址" prop="address">
<el-input v-model="form.address" ref="fieldAddr"></el-input>
</el-form-item>
<el-form-item label="活动性质" prop="type">
<el-checkbox-group v-model="form.type">
<el-checkbox label="美食/餐厅线上活动" name="type"></el-checkbox>
<el-checkbox label="地推活动" name="type"></el-checkbox>
<el-checkbox label="线下主题活动" name="type"></el-checkbox>
<el-checkbox label="单纯品牌曝光" name="type"></el-checkbox>
</el-checkbox-group>
</el-form-item>
</el-form>
`,
data() {
return {
form: {
name: '',
address: '',
type: []
},
rules: {
name: [
{ required: true, message: '请输入活动名称', trigger: 'blur' }
],
address: [
{ required: true, message: '请选择活动区域', trigger: 'change' }
],
type: [
{ type: 'array', required: true, message: '请至少选择一个活动性质', trigger: 'change' }
]
}
};
},
methods: {
setValue() {
this.form.name = 'jack';
this.form.address = 'aaaa';
this.form.type.push('地推活动');
}
}
}, true);
vm.setValue();
vm.$refs.form.resetFields();
vm.$refs.form.$nextTick(_ => {
expect(vm.form.name).to.equal('');
expect(vm.form.address).to.equal('');
expect(vm.form.type.length).to.equal(0);
done();
});
});
it('clear validate', done => {
vm = createVue({
template: `
<el-form ref="form" :model="form" :rules="rules">
<el-form-item label="活动名称" prop="name">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="活动地址" prop="address">
<el-input v-model="form.address"></el-input>
</el-form-item>
<el-form-item label="活动性质" prop="type">
<el-checkbox-group v-model="form.type">
<el-checkbox label="美食/餐厅线上活动" name="type"></el-checkbox>
<el-checkbox label="地推活动" name="type"></el-checkbox>
<el-checkbox label="线下主题活动" name="type"></el-checkbox>
<el-checkbox label="单纯品牌曝光" name="type"></el-checkbox>
</el-checkbox-group>
</el-form-item>
</el-form>
`,
data() {
return {
form: {
name: '',
address: '',
type: []
},
rules: {
name: [
{ required: true, message: '请输入活动名称', trigger: 'blur' }
],
address: [
{ required: true, message: '请选择活动区域', trigger: 'change' }
],
type: [
{ type: 'array', required: true, message: '请至少选择一个活动性质', trigger: 'change' }
]
}
};
}
}, true);
const form = vm.$refs.form;
const nameField = form.fields.filter(field => field.prop === 'name')[0];
const addressField = form.fields.filter(field => field.prop === 'address')[0];
form.validate();
vm.$nextTick(() => {
expect(nameField.validateMessage).to.equal('请输入活动名称');
form.clearValidate(['name']);
vm.$nextTick(() => {
expect(nameField.validateMessage).to.equal('');
form.clearValidate();
vm.$nextTick(() => {
expect(addressField.validateMessage).to.equal('');
done();
});
});
});
});
it('form item nest', done => {
vm = createVue({
template: `
<el-form ref="form" :model="form" :rules="rules">
<el-form-item label="活动时间" required>
<el-col :span="11">
<el-form-item prop="date1">
<el-date-picker type="date" placeholder="选择日期" v-model="form.date1" style="width: 100%;"></el-date-picker>
</el-form-item>
</el-col>
<el-col class="line" :span="2">-</el-col>
<el-col :span="11">
<el-form-item prop="date2">
<el-time-picker placeholder="选择时间" v-model="form.date2" style="width: 100%;"></el-time-picker>
</el-form-item>
</el-col>
</el-form-item>
</el-form>
`,
data() {
return {
form: {
date1: '',
date2: ''
},
rules: {
date1: [
{ type: 'date', required: true, message: '请选择日期', trigger: 'change' }
]
}
};
},
methods: {
setValue() {
this.name = 'jack';
this.address = 'aaaa';
}
}
}, true);
vm.$refs.form.validate(valid => {
expect(valid).to.not.true;
done();
});
});
describe('validate', () => {
it('input', done => {
vm = createVue({
template: `
<el-form :model="form" :rules="rules" ref="form">
<el-form-item label="活动名称" prop="name" ref="field">
<el-input v-model="form.name"></el-input>
</el-form-item>
</el-form>
`,
data() {
return {
form: {
name: ''
},
rules: {
name: [
{ required: true, message: '请输入活动名称', trigger: 'change', min: 3, max: 6 }
]
}
};
},
methods: {
setValue(value) {
this.form.name = value;
}
}
}, true);
vm.$refs.form.validate(valid => {
let field = vm.$refs.field;
expect(valid).to.not.true;
vm.$refs.form.$nextTick(_ => {
expect(field.validateMessage).to.equal('请输入活动名称');
vm.setValue('aaaaa');
vm.$refs.form.$nextTick(_ => {
expect(field.validateMessage).to.equal('');
vm.setValue('aa');
vm.$refs.form.$nextTick(_ => {
expect(field.validateMessage).to.equal('请输入活动名称');
done();
});
});
});
});
});
it('textarea', done => {
vm = createVue({
template: `
<el-form :model="form" :rules="rules" ref="form">
<el-form-item label="活动名称" prop="name" ref="field">
<el-input type="textarea" v-model="form.name"></el-input>
</el-form-item>
</el-form>
`,
data() {
return {
form: {
name: ''
},
rules: {
name: [
{ required: true, message: '请输入活动名称', trigger: 'change', min: 3, max: 6 }
]
}
};
},
methods: {
setValue(value) {
this.form.name = value;
}
}
}, true);
vm.$refs.form.validate(valid => {
let field = vm.$refs.field;
expect(valid).to.not.true;
vm.$refs.form.$nextTick(_ => {
expect(field.validateMessage).to.equal('请输入活动名称');
vm.setValue('aaaaa');
vm.$refs.form.$nextTick(_ => {
expect(field.validateMessage).to.equal('');
vm.setValue('aa');
vm.$refs.form.$nextTick(_ => {
expect(field.validateMessage).to.equal('请输入活动名称');
done();
});
});
});
});
});
it('selector', done => {
vm = createVue({
template: `
<el-form :model="form" :rules="rules" ref="form">
<el-form-item label="记住密码" prop="region" ref="field">
<el-select v-model="form.region" placeholder="请选择活动区域">
<el-option label="区域一" value="shanghai"></el-option>
<el-option label="区域二" ref="opt" value="beijing"></el-option>
</el-select>
</el-form-item>
</el-form>
`,
data() {
return {
form: {
region: ''
},
rules: {
region: [
{required: true, message: '请选择活动区域', trigger: 'change' }
]
}
};
}
}, true);
vm.$refs.form.validate(valid => {
let field = vm.$refs.field;
expect(valid).to.false;
setTimeout(_ => {
expect(field.validateMessage).to.equal('请选择活动区域');
// programatic modification triggers change validation
vm.form.region = 'shanghai';
setTimeout(_ => {
expect(field.validateMessage).to.equal('');
vm.form.region = '';
setTimeout(_ => {
expect(field.validateMessage).to.equal('请选择活动区域');
// user modification of bound value triggers change validation
vm.$refs.opt.$el.click();
setTimeout(_ => {
expect(field.validateMessage).to.equal('');
done();
}, 100);
}, 100);
}, 100);
}, 100);
});
});
it('datepicker', done => {
vm = createVue({
template: `
<el-form :model="form" :rules="rules" ref="form">
<el-form-item label="记住密码" prop="date" ref="field">
<el-date-picker type="date" ref="picker" placeholder="选择日期" v-model="form.date" style="width: 100%;"></el-date-picker>
</el-form-item>
</el-form>
`,
data() {
return {
form: {
date: ''
},
rules: {
date: [
{type: 'date', required: true, message: '请选择日期', trigger: 'change' }
]
}
};
}
}, true);
vm.$refs.form.validate(valid => {
let field = vm.$refs.field;
expect(valid).to.not.true;
setTimeout(_ => {
expect(field.validateMessage).to.equal('请选择日期');
// programatic modification triggers change validation
vm.form.date = new Date();
setTimeout(_ => {
expect(field.validateMessage).to.equal('');
vm.form.date = '';
// user modification triggers change
const input = vm.$refs.picker.$el.querySelector('input');
input.blur();
input.focus();
setTimeout(_ => {
const keyDown = (el, keyCode) => {
const evt = document.createEvent('Events');
evt.initEvent('keydown', true, true);
evt.keyCode = keyCode;
el.dispatchEvent(evt);
};
keyDown(input, 37);
setTimeout(_ => {
keyDown(input, 13);
setTimeout(_ => {
expect(field.validateMessage).to.equal('');
done();
}, DELAY);
}, DELAY);
}, DELAY);
}, DELAY);
}, DELAY);
});
});
it('timepicker', done => {
vm = createVue({
template: `
<el-form :model="form" :rules="rules" ref="form">
<el-form-item label="记住密码" prop="date" ref="field">
<el-time-picker ref="picker" placeholder="选择时间" v-model="form.date" style="width: 100%;"></el-time-picker>
</el-form-item>
</el-form>
`,
data() {
return {
form: {
date: ''
},
rules: {
date: [
{type: 'date', required: true, message: '请选择时间', trigger: 'change' }
]
}
};
}
}, true);
vm.$refs.form.validate(valid => {
let field = vm.$refs.field;
expect(valid).to.not.true;
setTimeout(_ => {
expect(field.validateMessage).to.equal('请选择时间');
// programatic modification does not trigger change
vm.value = new Date();
setTimeout(_ => {
expect(field.validateMessage).to.equal('请选择时间');
vm.value = '';
// user modification triggers change
const input = vm.$refs.picker.$el.querySelector('input');
input.blur();
input.focus();
setTimeout(_ => {
vm.$refs.picker.picker.$el.querySelector('.confirm').click();
setTimeout(_ => {
expect(field.validateMessage).to.equal('');
done();
}, DELAY);
}, DELAY);
}, DELAY);
}, DELAY);
});
});
it('checkbox', done => {
vm = createVue({
template: `
<el-form :model="form" :rules="rules" ref="form">
<el-form-item label="是否接受协议" prop="accept" ref="field">
<el-checkbox v-model="form.accept">
<span>接受协议</span>
</el-checkbox>
</el-form-item>
</el-form>
`,
data() {
return {
form: {
accept: true
},
rules: {
accept: [
{
validator: (rule, value, callback) => {
value ? callback() : callback(new Error('您需要接受用户协议'));
},
trigger: 'change'
}
]
}
};
},
methods: {
setValue(value) {
this.form.accept = value;
}
}
}, true);
vm.form.accept = false;
vm.$nextTick(_ => {
expect(vm.$refs.field.validateMessage).to.equal('您需要接受用户协议');
});
vm.$refs.form.validate(valid => {
let field = vm.$refs.field;
expect(valid).to.not.true;
expect(field.validateMessage).to.equal('您需要接受用户协议');
vm.$refs.form.$nextTick(_ => {
vm.setValue(true);
vm.$refs.form.$nextTick(_ => {
expect(field.validateMessage).to.equal('');
done();
});
});
});
});
it('checkbox group', done => {
vm = createVue({
template: `
<el-form :model="form" :rules="rules" ref="form">
<el-form-item label="活动名称" prop="type" ref="field">
<el-checkbox-group v-model="form.type">
<el-checkbox label="美食/餐厅线上活动" name="type"></el-checkbox>
<el-checkbox label="地推活动" name="type"></el-checkbox>
<el-checkbox label="线下主题活动" name="type"></el-checkbox>
<el-checkbox label="单纯品牌曝光" name="type"></el-checkbox>
</el-checkbox-group>
</el-form-item>
</el-form>
`,
data() {
return {
form: {
type: []
},
rules: {
type: [
{ type: 'array', required: true, message: '请选择活动类型', trigger: 'change' }
]
}
};
},
methods: {
setValue(value) {
this.form.type = value;
}
}
}, true);
vm.$refs.form.validate(valid => {
let field = vm.$refs.field;
expect(valid).to.not.true;
vm.$refs.form.$nextTick(_ => {
expect(field.validateMessage).to.equal('请选择活动类型');
vm.setValue(['地推活动']);
vm.$refs.form.$nextTick(_ => {
expect(field.validateMessage).to.equal('');
done();
});
});
});
});
it('radio group', done => {
vm = createVue({
template: `
<el-form :model="form" :rules="rules" ref="form">
<el-form-item label="活动名称" prop="type" ref="field">
<el-radio-group v-model="form.type">
<el-radio label="线上品牌商赞助"></el-radio>
<el-radio label="线下场地免费"></el-radio>
</el-radio-group>
</el-form-item>
</el-form>
`,
data() {
return {
form: {
type: ''
},
rules: {
type: [
{ required: true, message: '请选择活动类型', trigger: 'change' }
]
}
};
},
methods: {
setValue(value) {
this.form.type = value;
}
}
}, true);
vm.$refs.form.validate(valid => {
let field = vm.$refs.field;
expect(valid).to.not.true;
vm.$refs.form.$nextTick(_ => {
expect(field.validateMessage).to.equal('请选择活动类型');
vm.setValue('线下场地免费');
vm.$refs.form.$nextTick(_ => {
expect(field.validateMessage).to.equal('');
done();
});
});
});
});
it('validate field', done => {
vm = createVue({
template: `
<el-form :model="form" :rules="rules" ref="form">
<el-form-item label="活动名称" prop="name" ref="field">
<el-input v-model="form.name"></el-input>
</el-form-item>
</el-form>
`,
data() {
return {
form: {
name: ''
},
rules: {
name: [
{ required: true, message: '请输入活动名称', trigger: 'change', min: 3, max: 6 }
]
}
};
},
methods: {
setValue(value) {
this.form.name = value;
}
}
}, true);
vm.$refs.form.validateField('name', valid => {
expect(valid).to.not.true;
done();
});
});
it('custom validate', done => {
var checkName = (rule, value, callback) => {
if (value.length < 5) {
callback(new Error('长度至少为5'));
} else {
callback();
}
};
vm = createVue({
template: `
<el-form :model="form" :rules="rules" ref="form">
<el-form-item label="活动名称" prop="name" ref="field">
<el-input v-model="form.name"></el-input>
</el-form-item>
</el-form>
`,
data() {
return {
form: {
name: ''
},
rules: {
name: [
{ validator: checkName, trigger: 'change' }
]
}
};
},
methods: {
setValue(value) {
this.form.name = value;
}
}
}, true);
vm.$refs.form.validate(valid => {
let field = vm.$refs.field;
expect(valid).to.not.true;
vm.$refs.form.$nextTick(_ => {
expect(field.validateMessage).to.equal('长度至少为5');
vm.setValue('aaaaaa');
vm.$refs.form.$nextTick(_ => {
expect(field.validateMessage).to.equal('');
done();
});
});
});
});
it('error', done => {
vm = createVue({
template: `
<el-form :model="form" :rules="rules" ref="form">
<el-form-item label="活动名称" prop="name" :error="error" ref="field">
<el-input v-model="form.name"></el-input>
</el-form-item>
</el-form>
`,
data() {
return {
error: 'dsad',
form: {
name: 'sada'
},
rules: {
name: [
{ required: true, message: '请输入活动名称', trigger: 'change', min: 3, max: 6 }
]
}
};
},
methods: {
setValue(value) {
this.form.name = value;
}
}
}, true);
vm.$refs.form.validate(valid => {
let field = vm.$refs.field;
expect(valid).to.true;
vm.error = '输入不合法';
vm.$refs.field.$nextTick(_ => {
expect(field.validateState).to.equal('error');
expect(field.validateMessage).to.equal('输入不合法');
done();
});
});
});
it('invalid fields', done => {
var checkName = (rule, value, callback) => {
if (value.length < 5) {
callback(new Error('长度至少为5'));
} else {
callback();
}
};
vm = createVue({
template: `
<el-form :model="form" :rules="rules" ref="form">
<el-form-item label="活动名称" prop="name" ref="field">
<el-input v-model="form.name"></el-input>
</el-form-item>
</el-form>
`,
data() {
return {
form: {
name: ''
},
rules: {
name: [
{ validator: checkName, trigger: 'change' }
]
}
};
}
}, true);
vm.$refs.form.validate((valid, invalidFields) => {
expect(invalidFields.name.length).to.equal(1);
done();
});
});
it('validate return promise', done => {
var checkName = (rule, value, callback) => {
if (value.length < 5) {
callback(new Error('长度至少为5'));
} else {
callback();
}
};
vm = createVue({
template: `
<el-form :model="form" :rules="rules" ref="form">
<el-form-item label="活动名称" prop="name" ref="field">
<el-input v-model="form.name"></el-input>
</el-form-item>
</el-form>
`,
data() {
return {
form: {
name: ''
},
rules: {
name: [
{ validator: checkName, trigger: 'change' }
]
}
};
}
}, true);
vm.$refs.form.validate().catch(validFailed => {
expect(validFailed).to.false;
done();
});
});
});
it('validate event', done => {
vm = createVue({
template: `
<el-form :model="form" :rules="rules" ref="form" @validate="onValidate">
<el-form-item label="活动名称" prop="name" ref="name">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="活动地点" prop="addr" ref="addr">
<el-input v-model="form.addr"></el-input>
</el-form-item>
</el-form>
`,
data() {
return {
form: {
name: '',
addr: ''
},
valid: {
name: null,
addr: null
},
error: {
name: null,
addr: null
},
rules: {
name: [
{ required: true, message: '请输入活动名称', trigger: 'change', min: 3, max: 6 }
],
addr: [
{ required: true, message: '请输入活动名称', trigger: 'change' }
]
}
};
},
methods: {
onValidate(prop, valid, msg) {
this.valid[prop] = valid;
this.error[prop] = msg;
},
setValue(prop, value) {
this.form[prop] = value;
}
}
}, true);
vm.setValue('name', '1');
setTimeout(() => {
expect(vm.valid.name).to.equal(false);
expect(vm.error.name).to.equal('请输入活动名称');
vm.setValue('addr', '1');
setTimeout(() => {
expect(vm.valid.addr).to.equal(true);
expect(vm.error.addr).to.equal(null);
vm.setValue('name', '111');
setTimeout(() => {
expect(vm.valid.name).to.equal(true);
expect(vm.error.name).to.equal(null);
done();
}, DELAY);
}, DELAY);
}, DELAY);
});
});

View File

@@ -0,0 +1,137 @@
import { createTest, createVue, destroyVM, wait } from '../util';
import Image from 'packages/image';
import { IMAGE_SUCCESS, IMAGE_FAIL } from '../mocks/uri';
const src = IMAGE_SUCCESS;
describe('Image', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', async() => {
vm = createTest(Image, {
src,
fit: 'fill'
}, true);
const placeholder = vm.$el.querySelector('.el-image__placeholder');
const error = vm.$el.querySelector('.el-image__error');
let img = vm.$el.querySelector('.el-image__inner');
expect(placeholder).to.exist;
expect(error).to.be.null;
expect(img).to.be.null;
await wait();
img = vm.$el.querySelector('.el-image__inner');
expect(img.style.objectFit).to.equal('fill');
});
it('load failed', async() => {
vm = createTest(Image, {
src: IMAGE_FAIL
}, true);
await wait();
const error = vm.$el.querySelector('.el-image__error');
expect(error).to.be.exist;
});
it('lazy load', async() => {
vm = createVue({
template: `
<div ref="wrapper" style="height: 200px; overflow: auto;">
<el-image
v-for="item in 2"
:key="item"
:src="src"
ref="image"
style="display: block; height: 200px;"
lazy></el-image>
</div>
`,
data() {
return {
src
};
}
}, true);
const { image, wrapper } = vm.$refs;
const [image1, image2] = image;
await wait();
expect(image1.loading).to.be.false;
expect(image2.loading).to.be.true;
wrapper.scrollTop = 10;
await wait();
expect(image2.loading).to.be.false;
});
it('$attrs', async() => {
vm = createVue({
template: `
<el-image
alt="$attrs test"
referrerpolicy="origin"
:src="src"></el-image>
`,
data() {
return {
src
};
}
}, true);
await wait();
const $img = vm.$el.querySelector('.el-image__inner');
expect($img.getAttribute('alt')).to.be.equal('$attrs test');
expect($img.getAttribute('referrerpolicy')).to.be.equal('origin');
});
it('pass event listeners', async() => {
let result;
vm = createVue({
template: `
<el-image @click="handleClick" :src="src"></el-image>
`,
data() {
return {
src
};
},
methods: {
handleClick(e) {
result = e;
}
}
}, true);
await wait();
vm.$el.querySelector('.el-image__inner').click();
await wait();
expect(result).to.exist;
});
it('big image preview', async() => {
vm = createVue({
template: `
<el-image :src="src" :preview-src-list="srcList"></el-image>
`,
data() {
return {
src: src,
srcList: [src]
};
}
}, true);
await wait();
vm.$el.querySelector('.el-image__inner').click();
await wait();
expect(document.querySelector('.el-image-viewer__wrapper')).to.exist;
document.querySelector('.el-image-viewer__close').click();
await wait(1000);
expect(document.querySelector('.el-image-viewer__wrapper')).to.not.exist;
});
});

View File

@@ -0,0 +1,58 @@
import { createVue, wait, destroyVM } from '../util';
describe('InfiniteScroll', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', async() => {
vm = createVue({
template: `
<ul ref="scrollTarget" v-infinite-scroll="load" style="height: 300px;overflow: auto;">
<li v-for="i in count" style="display: flex;height: 50px;">{{ i }}</li>
</ul>
`,
data() {
return {
count: 0
};
},
methods: {
load() {
this.count += 2;
}
}
}, true);
vm.$refs.scrollTarget.scrollTop = 2000;
await wait();
expect(vm.$el.innerText.indexOf('2') > -1).to.be.true;
});
it('invisible element not trigger', async() => {
vm = createVue({
template: `
<div v-show="false">
<ul ref="scrollTarget" v-infinite-scroll="load" style="height: 300px;overflow: auto;">
<li v-for="i in count" style="display: flex;height: 50px;">{{ i }}</li>
</ul>
</div>
`,
data() {
return {
count: 0
};
},
methods: {
load() {
this.count += 2;
}
}
}, true);
vm.$refs.scrollTarget.scrollTop = 2000;
await wait();
expect(vm.$el.innerText.indexOf('2') > -1).to.be.false;
});
});

View File

@@ -0,0 +1,453 @@
import {createVue, triggerEvent, triggerClick, destroyVM, waitImmediate} from '../util';
const DELAY = 1;
describe('InputNumber', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', () => {
vm = createVue({
template: `
<el-input-number v-model="value">
</el-input-number>
`,
data() {
return {
value: 1
};
}
}, true);
let input = vm.$el.querySelector('input');
expect(vm.value).to.be.equal(1);
expect(input.value).to.be.equal('1');
});
it('decrease', done => {
vm = createVue({
template: `
<el-input-number v-model="value" ref="input">
</el-input-number>
`,
data() {
return {
value: 5
};
}
}, true);
let input = vm.$el.querySelector('input');
let btnDecrease = vm.$el.querySelector('.el-input-number__decrease');
triggerEvent(btnDecrease, 'mousedown');
triggerClick(document, 'mouseup');
vm.$nextTick(_ => {
expect(vm.value).to.be.equal(4);
expect(input.value).to.be.equal('4');
done();
});
});
it('increase', done => {
vm = createVue({
template: `
<el-input-number v-model="value">
</el-input-number>
`,
data() {
return {
value: 1.5
};
}
}, true);
let input = vm.$el.querySelector('input');
let btnIncrease = vm.$el.querySelector('.el-input-number__increase');
triggerEvent(btnIncrease, 'mousedown');
triggerClick(document, 'mouseup');
vm.$nextTick(_ => {
expect(vm.value).to.be.equal(2.5);
expect(input.value).to.be.equal('2.5');
done();
});
});
it('disabled', done => {
vm = createVue({
template: `
<el-input-number v-model="value" disabled>
</el-input-number>
`,
data() {
return {
value: 2
};
}
}, true);
let input = vm.$el.querySelector('input');
let btnDecrease = vm.$el.querySelector('.el-input-number__decrease');
let btnIncrease = vm.$el.querySelector('.el-input-number__increase');
triggerEvent(btnDecrease, 'mousedown');
triggerClick(document, 'mouseup');
vm.$nextTick(_ => {
expect(vm.value).to.be.equal(2);
expect(input.value).to.be.equal('2');
triggerEvent(btnIncrease, 'mousedown');
triggerClick(document, 'mouseup');
vm.$nextTick(_ => {
expect(vm.value).to.be.equal(2);
expect(input.value).to.be.equal('2');
done();
});
});
});
it('step', done => {
vm = createVue({
template: `
<el-input-number v-model="value" :step="3.2">
</el-input-number>
`,
data() {
return {
value: 5
};
}
}, true);
let input = vm.$el.querySelector('input');
let btnIncrease = vm.$el.querySelector('.el-input-number__increase');
let btnDecrease = vm.$el.querySelector('.el-input-number__decrease');
triggerEvent(btnIncrease, 'mousedown');
triggerClick(document, 'mouseup');
vm.$nextTick(_ => {
expect(vm.value).to.be.equal(8.2);
expect(input.value).to.be.equal('8.2');
triggerEvent(btnDecrease, 'mousedown');
triggerClick(document, 'mouseup');
vm.$nextTick(_ => {
expect(vm.value).to.be.equal(5);
expect(input.value).to.be.equal('5');
done();
});
});
});
it('step strictly', async() => {
vm = createVue({
template: `
<el-input-number v-model="value" :step="1.2" step-strictly>
</el-input-number>
`,
data() {
return {
value: 5
};
}
}, true);
let input = vm.$el.querySelector('input');
await waitImmediate();
expect(vm.value).to.be.equal(4.8);
expect(input.value).to.be.equal('4.8');
vm.value = '8';
await waitImmediate();
expect(vm.value).to.be.equal(8.4);
expect(input.value).to.be.equal('8.4');
});
it('min', done => {
vm = createVue({
template: `
<el-input-number v-model="value" :min="6">
</el-input-number>
`,
data() {
return {
value: 6
};
}
}, true);
const vm2 = createVue({
template: `
<el-input-number v-model="value" :min="6">
</el-input-number>
`,
data() {
return {
value: 3
};
}
}, true);
expect(vm2.value === 6);
expect(vm2.$el.querySelector('input').value).to.be.equal('6');
let input = vm.$el.querySelector('input');
let btnDecrease = vm.$el.querySelector('.el-input-number__decrease');
triggerEvent(btnDecrease, 'mousedown');
triggerClick(document, 'mouseup');
vm.$nextTick(_ => {
expect(vm.value).to.be.equal(6);
expect(input.value).to.be.equal('6');
done();
});
});
it('max', done => {
vm = createVue({
template: `
<el-input-number v-model="value" :max="8">
</el-input-number>
`,
data() {
return {
value: 8
};
}
}, true);
const vm2 = createVue({
template: `
<el-input-number v-model="value" :max="8">
</el-input-number>
`,
data() {
return {
value: 100
};
}
}, true);
expect(vm2.value === 8);
expect(vm2.$el.querySelector('input').value).to.be.equal('8');
let input = vm.$el.querySelector('input');
let btnIncrease = vm.$el.querySelector('.el-input-number__increase');
triggerEvent(btnIncrease, 'mousedown');
triggerClick(document, 'mouseup');
vm.$nextTick(_ => {
expect(vm.value).to.be.equal(8);
expect(input.value).to.be.equal('8');
done();
});
});
describe('precision', () => {
it('precision is 2', () => {
vm = createVue({
template: `
<el-input-number v-model="value" :max="8" :precision="2">
</el-input-number>
`,
data() {
return {
value: 6.999
};
}
}, true);
expect(vm.value === 7);
expect(vm.$el.querySelector('input').value).to.be.equal('7.00');
});
it('precision greater than the precision of step', done => {
vm = createVue({
template: `
<el-input-number v-model="value" :max="8" :precision="0" :step="0.1">
</el-input-number>
`,
data() {
return {
value: 6.999
};
}
}, true);
const input = vm.$el.querySelector('input');
const btnIncrease = vm.$el.querySelector('.el-input-number__increase');
expect(vm.value === 7);
expect(input.value).to.be.equal('7');
triggerEvent(btnIncrease, 'mousedown');
triggerClick(document, 'mouseup');
vm.$nextTick(_ => {
expect(vm.value).to.be.equal(7);
expect(input.value).to.be.equal('7');
done();
});
});
});
it('controls', () => {
vm = createVue({
template: `
<el-input-number :controls="false" v-model="value" :max="8">
</el-input-number>
`,
data() {
return {
value: 8
};
}
}, true);
expect(vm.$el.querySelector('.el-input-number__decrease')).to.not.exist;
expect(vm.$el.querySelector('.el-input-number__increase')).to.not.exist;
});
it('invalid value reset', done => {
vm = createVue({
template: `
<el-input-number v-model="value" :min="5" :max="10" ref="inputNumber">
</el-input-number>
`,
data() {
return {
value: 5
};
}
}, true);
const inputNumber = vm.$refs.inputNumber;
vm.value = 100;
vm.$nextTick(_ => {
expect(inputNumber.currentValue).to.be.equal(10);
vm.value = 4;
vm.$nextTick(_ => {
expect(inputNumber.currentValue).to.be.equal(5);
vm.value = 'dsajkhd';
vm.$nextTick(_ => {
expect(inputNumber.currentValue).to.be.equal(5);
done();
});
});
});
});
describe('event:change', () => {
let spy;
beforeEach(() => {
vm = createVue({
template: `
<el-input-number v-model="value" ref="compo" :min='2' :max='3' :step='1'>
</el-input-number>
`,
data() {
return {
value: 2
};
}
}, true);
spy = sinon.spy();
vm.$refs.compo.$on('change', spy);
});
it('emit on input', done => {
vm.$refs.compo.handleInputChange('3');
setTimeout(_ => {
expect(spy.calledOnce).to.be.true;
expect(spy.args[0][0]).to.equal(3);
done();
}, DELAY);
});
it('emit on button', done => {
const btnIncrease = vm.$el.querySelector('.el-input-number__increase');
triggerEvent(btnIncrease, 'mousedown');
triggerClick(document, 'mouseup');
setTimeout(_ => {
expect(spy.calledOnce).to.be.true;
expect(spy.args[0][0]).to.equal(3);
done();
}, DELAY);
});
it('does not emit on programatic change', done => {
vm.value = 3;
setTimeout(_ => {
expect(spy.notCalled).to.be.true;
done();
}, DELAY);
});
});
it('event:focus & blur', done => {
vm = createVue({
template: `
<el-input-number ref="input">
</el-input-number>
`
}, true);
const spyFocus = sinon.spy();
const spyBlur = sinon.spy();
vm.$refs.input.$on('focus', spyFocus);
vm.$refs.input.$on('blur', spyBlur);
vm.$el.querySelector('input').focus();
vm.$el.querySelector('input').blur();
vm.$nextTick(_ => {
expect(spyFocus.calledOnce).to.be.true;
expect(spyBlur.calledOnce).to.be.true;
done();
});
});
it('focus', done => {
vm = createVue({
template: `
<el-input-number ref="input"></el-input-number>
`
}, true);
const spy = sinon.spy();
vm.$refs.input.$on('focus', spy);
vm.$refs.input.focus();
vm.$nextTick(_ => {
expect(spy.calledOnce).to.be.true;
done();
});
});
describe('InputNumber Methods', () => {
it('method:select', done => {
const testContent = '123';
vm = createVue({
template: `
<el-input-number
ref="inputNumComp"
:value="${testContent}"
/>
`
}, true);
expect(vm.$refs.inputNumComp.$refs.input.$refs.input.selectionStart)
.to.equal(testContent.length);
expect(vm.$refs.inputNumComp.$refs.input.$refs.input.selectionEnd)
.to.equal(testContent.length);
vm.$refs.inputNumComp.select();
vm.$nextTick(_ => {
expect(vm.$refs.inputNumComp.$refs.input.$refs.input.selectionStart)
.to.equal(0);
expect(vm.$refs.inputNumComp.$refs.input.$refs.input.selectionEnd)
.to.equal(testContent.length);
done();
});
});
});
});

View File

@@ -0,0 +1,483 @@
import { createVue, destroyVM, triggerEvent, wait, waitImmediate } from '../util';
describe('Input', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', async() => {
vm = createVue({
template: `
<el-input
:minlength="3"
:maxlength="5"
placeholder="请输入内容"
@focus="handleFocus"
:value="input">
</el-input>
`,
data() {
return {
input: 'input',
inputFocus: false
};
},
methods: {
handleFocus() {
this.inputFocus = true;
}
}
}, true);
let inputElm = vm.$el.querySelector('input');
inputElm.focus();
expect(vm.inputFocus).to.be.true;
expect(inputElm.getAttribute('placeholder')).to.equal('请输入内容');
expect(inputElm.value).to.equal('input');
expect(inputElm.getAttribute('minlength')).to.equal('3');
expect(inputElm.getAttribute('maxlength')).to.equal('5');
vm.input = 'text';
await waitImmediate();
expect(inputElm.value).to.equal('text');
});
it('default to empty', () => {
vm = createVue({
template: '<el-input/>'
}, true);
let inputElm = vm.$el.querySelector('input');
expect(inputElm.value).to.equal('');
});
it('disabled', () => {
vm = createVue({
template: `
<el-input disabled>
</el-input>
`
}, true);
expect(vm.$el.querySelector('input').getAttribute('disabled')).to.ok;
});
it('suffixIcon', () => {
vm = createVue({
template: `
<el-input suffix-icon="time"></el-input>
`
}, true);
var icon = vm.$el.querySelector('.el-input__icon');
expect(icon).to.be.exist;
});
it('prefixIcon', () => {
vm = createVue({
template: `
<el-input prefix-icon="time"></el-input>
`
}, true);
var icon = vm.$el.querySelector('.el-input__icon');
expect(icon).to.be.exist;
});
it('size', () => {
vm = createVue({
template: `
<el-input size="large">
</el-input>
`
}, true);
expect(vm.$el.classList.contains('el-input--large')).to.true;
});
it('type', () => {
vm = createVue({
template: `
<el-input type="textarea">
</el-input>
`
}, true);
expect(vm.$el.classList.contains('el-textarea')).to.true;
});
it('rows', () => {
vm = createVue({
template: `
<el-input type="textarea" :rows="3">
</el-input>
`
}, true);
expect(vm.$el.querySelector('.el-textarea__inner').getAttribute('rows')).to.be.equal('3');
});
// Github issue #2836
it('resize', async() => {
vm = createVue({
template: `
<div>
<el-input type="textarea" :resize="resize"></el-input>
</div>
`,
data: {
resize: 'none'
}
}, true);
await waitImmediate();
expect(vm.$el.querySelector('.el-textarea__inner').style.resize).to.be.equal(vm.resize);
vm.resize = 'horizontal';
await waitImmediate();
expect(vm.$el.querySelector('.el-textarea__inner').style.resize).to.be.equal(vm.resize);
});
it('autosize', async() => {
vm = createVue({
template: `
<div>
<el-input
ref="limitSize"
type="textarea"
:autosize="{minRows: 3, maxRows: 5}"
v-model="textareaValue"
>
</el-input>
<el-input
ref="limitlessSize"
type="textarea"
autosize
v-model="textareaValue"
>
</el-input>
</div>
`,
data() {
return {
textareaValue: 'sda\ndasd\nddasdsda\ndasd\nddasdsda\ndasd\nddasdsda\ndasd\nddasd'
};
}
}, true);
var limitSizeInput = vm.$refs.limitSize;
var limitlessSizeInput = vm.$refs.limitlessSize;
expect(limitSizeInput.textareaStyle.height).to.be.equal('117px');
expect(limitlessSizeInput.textareaStyle.height).to.be.equal('201px');
vm.textareaValue = '';
await wait();
expect(limitSizeInput.textareaStyle.height).to.be.equal('75px');
expect(limitlessSizeInput.textareaStyle.height).to.be.equal('33px');
});
it('focus', async() => {
vm = createVue({
template: `
<el-input ref="input">
</el-input>
`
}, true);
const spy = sinon.spy();
vm.$refs.input.$on('focus', spy);
vm.$refs.input.focus();
await waitImmediate();
expect(spy.calledOnce).to.be.true;
});
it('Input contains Select and append slot', async() => {
vm = createVue({
template: `
<el-input v-model="value" clearable class="input-with-select" ref="input">
<el-select v-model="select" slot="prepend" placeholder="请选择">
<el-option label="餐厅名" value="1"></el-option>
<el-option label="订单号" value="2"></el-option>
<el-option label="用户电话" value="3"></el-option>
</el-select>
<el-button slot="append" icon="el-icon-search"></el-button>
</el-input>
`,
data() {
return {
value: '1234',
select: '1'
};
}
}, true);
vm.$refs.input.hovering = true;
await wait();
const suffixEl = document.querySelector('.input-with-select > .el-input__suffix');
expect(suffixEl).to.not.be.null;
expect(suffixEl.style.transform).to.not.be.empty;
});
it('validateEvent', async() => {
const spy = sinon.spy();
vm = createVue({
template: `
<el-form :model="model" :rules="rules">
<el-form-item prop="input">
<el-input v-model="model.input" :validate-event="false">
</el-input>
</el-form-item>
</el-form>
`,
data() {
const validator = (rule, value, callback) => {
spy();
callback();
};
return {
model: {
input: ''
},
rules: {
input: [
{ validator }
]
}
};
}
}, true);
vm.model.input = '123';
await waitImmediate();
expect(spy.called).to.be.false;
});
describe('Input Events', () => {
it('event:focus & blur', async() => {
vm = createVue({
template: `
<el-input
ref="input"
placeholder="请输入内容"
value="input">
</el-input>
`
}, true);
const spyFocus = sinon.spy();
const spyBlur = sinon.spy();
vm.$refs.input.$on('focus', spyFocus);
vm.$refs.input.$on('blur', spyBlur);
vm.$el.querySelector('input').focus();
vm.$el.querySelector('input').blur();
await waitImmediate();
expect(spyFocus.calledOnce).to.be.true;
expect(spyBlur.calledOnce).to.be.true;
});
it('event:change', async() => {
// NOTE: should be same as native's change behavior
vm = createVue({
template: `
<el-input
ref="input"
placeholder="请输入内容"
:value="input">
</el-input>
`,
data() {
return {
input: 'a'
};
}
}, true);
const inputElm = vm.$el.querySelector('input');
const simulateEvent = (text, event) => {
inputElm.value = text;
inputElm.dispatchEvent(new Event(event));
};
const spy = sinon.spy();
vm.$refs.input.$on('change', spy);
// simplified test, component should emit change when native does
simulateEvent('1', 'input');
simulateEvent('2', 'change');
await waitImmediate();
expect(spy.calledWith('2')).to.be.true;
expect(spy.calledOnce).to.be.true;
});
it('event:clear', async() => {
vm = createVue({
template: `
<el-input
ref="input"
placeholder="请输入内容"
clearable
:value="input">
</el-input>
`,
data() {
return {
input: 'a'
};
}
}, true);
const spyClear = sinon.spy();
const inputElm = vm.$el.querySelector('input');
// focus to show clear button
inputElm.focus();
vm.$refs.input.$on('clear', spyClear);
await waitImmediate();
vm.$el.querySelector('.el-input__clear').click();
await waitImmediate();
expect(spyClear.calledOnce).to.be.true;
});
it('event:input', async() => {
vm = createVue({
template: `
<el-input
ref="input"
placeholder="请输入内容"
clearable
:value="input">
</el-input>
`,
data() {
return {
input: 'a'
};
}
}, true);
const spy = sinon.spy();
vm.$refs.input.$on('input', spy);
const nativeInput = vm.$refs.input.$el.querySelector('input');
nativeInput.value = '1';
triggerEvent(nativeInput, 'compositionstart');
triggerEvent(nativeInput, 'input');
await waitImmediate();
nativeInput.value = '2';
triggerEvent(nativeInput, 'compositionupdate');
triggerEvent(nativeInput, 'input');
await waitImmediate();
triggerEvent(nativeInput, 'compositionend');
await waitImmediate();
// input event does not fire during composition
expect(spy.calledOnce).to.be.true;
// native input value is controlled
expect(vm.input).to.equal('a');
expect(nativeInput.value).to.equal('a');
});
});
describe('Input Methods', () => {
it('method:select', async() => {
const testContent = 'test';
vm = createVue({
template: `
<el-input
ref="inputComp"
value="${testContent}"
/>
`
}, true);
expect(vm.$refs.inputComp.$refs.input.selectionStart).to.equal(testContent.length);
expect(vm.$refs.inputComp.$refs.input.selectionEnd).to.equal(testContent.length);
vm.$refs.inputComp.select();
await waitImmediate();
expect(vm.$refs.inputComp.$refs.input.selectionStart).to.equal(0);
expect(vm.$refs.inputComp.$refs.input.selectionEnd).to.equal(testContent.length);
});
});
it('sets value on textarea / input type change', async() => {
vm = createVue({
template: `
<el-input :type="type" v-model="val" />
`,
data() {
return {
type: 'text',
val: '123'
};
}
}, true);
expect(vm.$el.querySelector('input').value).to.equal('123');
vm.type = 'textarea';
await waitImmediate();
expect(vm.$el.querySelector('textarea').value).to.equal('123');
vm.type = 'password';
await waitImmediate();
expect(vm.$el.querySelector('input').value).to.equal('123');
});
it('limit input and show word count', async() => {
vm = createVue({
template: `
<div>
<el-input
class="test-text"
type="text"
v-model="input1"
maxlength="10"
:show-word-limit="show">
</el-input>
<el-input
class="test-textarea"
type="textarea"
v-model="input2"
maxlength="10"
show-word-limit>
</el-input>
<el-input
class="test-password"
type="password"
v-model="input3"
maxlength="10"
show-word-limit>
</el-input>
<el-input
class="test-initial-exceed"
type="text"
v-model="input4"
maxlength="2"
show-word-limit>
</el-input>
</div>
`,
data() {
return {
input1: '',
input2: '',
input3: '',
input4: 'exceed',
show: false
};
}
}, true);
const inputElm1 = vm.$el.querySelector('.test-text');
const inputElm2 = vm.$el.querySelector('.test-textarea');
const inputElm3 = vm.$el.querySelector('.test-password');
const inputElm4 = vm.$el.querySelector('.test-initial-exceed');
expect(inputElm1.querySelectorAll('.el-input__count').length).to.equal(0);
expect(inputElm2.querySelectorAll('.el-input__count').length).to.equal(1);
expect(inputElm3.querySelectorAll('.el-input__count').length).to.equal(0);
expect(inputElm4.classList.contains('is-exceed')).to.true;
vm.show = true;
await waitImmediate();
expect(inputElm1.querySelectorAll('.el-input__count').length).to.equal(1);
vm.input4 = '1';
await waitImmediate();
expect(inputElm4.classList.contains('is-exceed')).to.false;
});
});

View File

@@ -0,0 +1,66 @@
import { createTest, createVue, destroyVM, wait } from '../util';
import Link from 'packages/link';
describe('Link', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', () => {
vm = createTest(Link, {
type: 'primary'
}, true);
let linkElm = vm.$el;
expect(linkElm.classList.contains('el-link--primary')).to.be.true;
});
it('icon', () => {
vm = createTest(Link, {
icon: 'el-icon-search'
}, true);
let linkElm = vm.$el;
expect(linkElm.querySelector('.el-icon-search')).to.be.ok;
});
it('href', () => {
vm = createTest(Link, {
href: 'https://element.eleme.io/'
}, true);
let linkElm = vm.$el;
expect(linkElm.getAttribute('href')).to.be.equal('https://element.eleme.io/');
});
it('target', () => {
vm = createVue(`
<el-link href="https://element.eleme.io" target="_blank">
default
</el-link>
`);
let linkElm = vm.$el;
expect(linkElm.getAttribute('target')).to.be.equal('_blank');
});
it('disabled', () => {
vm = createTest(Link, {
disabled: true
}, true);
let linkElm = vm.$el;
expect(linkElm.classList.contains('is-disabled')).to.be.true;
});
it('click', async() => {
let result;
vm = createVue({
template: `
<el-link @click="handleClick"></el-link>
`,
methods: {
handleClick(evt) {
result = evt;
}
}
}, true);
vm.$el.click();
await wait();
expect(result).to.exist;
});
});

View File

@@ -0,0 +1,282 @@
import { getStyle } from '../../../src/utils/dom';
import { createVue, destroyVM } from '../util';
import Vue from 'vue';
import LoadingRaw from 'packages/loading';
const Loading = LoadingRaw.service;
describe('Loading', () => {
let vm, loadingInstance, loadingInstance2;
afterEach(() => {
destroyVM(vm);
if (loadingInstance) {
loadingInstance.close();
loadingInstance.$el &&
loadingInstance.$el.parentNode &&
loadingInstance.$el.parentNode.removeChild(loadingInstance.$el);
}
if (loadingInstance2) {
loadingInstance2.close();
loadingInstance2.$el &&
loadingInstance2.$el.parentNode &&
loadingInstance2.$el.parentNode.removeChild(loadingInstance2.$el);
}
});
describe('as a directive', () => {
it('create', done => {
vm = createVue({
template: `
<div v-loading="loading"></div>
`,
data() {
return {
loading: true
};
}
});
Vue.nextTick(() => {
const mask = vm.$el.querySelector('.el-loading-mask');
expect(mask).to.exist;
vm.loading = false;
setTimeout(() => {
expect(mask.style.display).to.equal('none');
done();
}, 100);
});
});
it('unbind', done => {
const vm1 = createVue({
template: `
<div v-if="show" v-loading="loading"></div>
`,
data() {
return {
show: true,
loading: true
};
}
});
const vm2 = createVue({
template: `
<div v-if="show" v-loading.body="loading"></div>
`,
data() {
return {
show: true,
loading: true
};
}
});
Vue.nextTick(() => {
vm1.loading = false;
vm2.loading = false;
Vue.nextTick(() => {
vm1.show = false;
vm2.show = false;
Vue.nextTick(() => {
expect(document.querySelector('.el-loading-mask')).to.not.exist;
done();
});
});
});
});
it('body', done => {
vm = createVue({
template: `
<div v-loading.body="loading"></div>
`,
data() {
return {
loading: true
};
}
}, true);
Vue.nextTick(() => {
const mask = document.querySelector('.el-loading-mask');
expect(mask.parentNode === document.body).to.true;
vm.loading = false;
document.body.removeChild(mask);
document.body.removeChild(vm.$el);
done();
});
});
it('fullscreen', done => {
vm = createVue({
template: `
<div v-loading.fullscreen="loading"></div>
`,
data() {
return {
loading: true
};
}
}, true);
Vue.nextTick(() => {
const mask = document.querySelector('.el-loading-mask');
expect(mask.parentNode === document.body).to.true;
expect(mask.classList.contains('is-fullscreen')).to.true;
vm.loading = false;
document.body.removeChild(mask);
document.body.removeChild(vm.$el);
done();
});
});
it('lock', done => {
vm = createVue({
template: `
<div v-loading.fullscreen.lock="loading"></div>
`,
data() {
return {
loading: true
};
}
}, true);
Vue.nextTick(() => {
expect(getStyle(document.body, 'overflow')).to.equal('hidden');
vm.loading = false;
document.body.removeChild(document.querySelector('.el-loading-mask'));
document.body.removeChild(vm.$el);
done();
});
});
it('text', done => {
vm = createVue({
template: `
<div v-loading="loading" element-loading-text="拼命加载中"></div>
`,
data() {
return {
loading: true
};
}
}, true);
Vue.nextTick(() => {
const mask = document.querySelector('.el-loading-mask');
const text = mask.querySelector('.el-loading-text');
expect(text).to.exist;
expect(text.textContent).to.equal('拼命加载中');
done();
});
});
it('customClass', done => {
vm = createVue({
template: `
<div v-loading="loading" element-loading-custom-class="loading-custom-class"></div>
`,
data() {
return {
loading: true
};
}
}, true);
Vue.nextTick(() => {
const mask = document.querySelector('.el-loading-mask');
expect(mask.classList.contains('loading-custom-class')).to.true;
done();
});
});
});
describe('as a service', () => {
it('create', () => {
loadingInstance = Loading();
expect(document.querySelector('.el-loading-mask')).to.exist;
});
it('close', () => {
loadingInstance = Loading();
loadingInstance.close();
expect(loadingInstance.visible).to.false;
});
it('target', done => {
vm = createVue({
template: `
<div class="loading-container"></div>
`
}, true);
loadingInstance = Loading({ target: '.loading-container' });
let mask = document.querySelector('.el-loading-mask');
let container = document.querySelector('.loading-container');
expect(mask).to.exist;
expect(mask.parentNode).to.equal(container);
loadingInstance.close();
setTimeout(() => {
expect(getStyle(container, 'position')).to.equal('relative');
done();
}, 200);
});
it('body', () => {
vm = createVue({
template: `
<div class="loading-container"></div>
`
}, true);
loadingInstance = Loading({
target: '.loading-container',
body: true
});
let mask = document.querySelector('.el-loading-mask');
expect(mask).to.exist;
expect(mask.parentNode).to.equal(document.body);
});
it('fullscreen', () => {
loadingInstance = Loading({ fullScreen: true });
const mask = document.querySelector('.el-loading-mask');
expect(mask.parentNode).to.equal(document.body);
expect(mask.classList.contains('is-fullscreen')).to.true;
});
it('fullscreen singleton', done => {
loadingInstance = Loading({ fullScreen: true });
setTimeout(() => {
loadingInstance2 = Loading({ fullScreen: true });
setTimeout(() => {
let masks = document.querySelectorAll('.el-loading-mask');
expect(masks.length).to.equal(1);
loadingInstance2.close();
setTimeout(() => {
masks = document.querySelectorAll('.el-loading-mask');
expect(masks.length).to.equal(0);
done();
}, 350);
}, 50);
}, 50);
});
it('lock', () => {
loadingInstance = Loading({ lock: true });
expect(getStyle(document.body, 'overflow')).to.equal('hidden');
});
it('text', () => {
loadingInstance = Loading({ text: 'Loading...' });
const text = document.querySelector('.el-loading-text');
expect(text).to.exist;
expect(text.textContent).to.equal('Loading...');
});
it('customClass', () => {
loadingInstance = Loading({ customClass: 'el-loading-custom-class' });
const customClass = document.querySelector('.el-loading-custom-class');
expect(customClass).to.exist;
});
});
});

View File

@@ -0,0 +1,424 @@
import { createVue, triggerEvent, destroyVM } from '../util';
describe('Menu', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', done => {
vm = createVue({
template: `
<el-menu>
<el-menu-item index="1" ref="item1">处理中心</el-menu-item>
<el-menu-item index="2" ref="item2">订单管理</el-menu-item>
</el-menu>
`
}, true);
var item1 = vm.$refs.item1;
var item2 = vm.$refs.item2;
item1.$el.click();
setTimeout(_ => {
expect(item1.$el.classList.contains('is-active')).to.be.true;
item2.$el.click();
setTimeout(_ => {
expect(item2.$el.classList.contains('is-active')).to.be.true;
done();
}, 20);
}, 20);
});
it('background-color', done => {
vm = createVue({
template: `
<el-menu default-active="2"
background-color="#f00"
text-color="#000"
active-text-color="#0f0">
<el-menu-item index="1" ref="item1">处理中心</el-menu-item>
<el-menu-item index="2" ref="item2">订单管理</el-menu-item>
</el-menu>
`
}, true);
expect(vm.$el.style.backgroundColor).to.equal('rgb(255, 0, 0)');
expect(vm.$refs.item1.$el.style.backgroundColor).to.equal('rgb(255, 0, 0)');
expect(vm.$refs.item1.$el.style.color).to.equal('rgb(0, 0, 0)');
expect(vm.$refs.item2.$el.style.color).to.equal('rgb(0, 255, 0)');
triggerEvent(vm.$refs.item1.$el, 'mouseenter');
setTimeout(_ => {
expect(vm.$refs.item1.$el.style.backgroundColor).to.equal('rgb(204, 0, 0)');
done();
}, 20);
});
it('menu-item click', done => {
vm = createVue({
template: `
<el-menu>
<el-menu-item @click="onMenuItemClick" index="1" ref="item1">处理中心</el-menu-item>
<el-menu-item index="2" ref="item2">订单管理</el-menu-item>
</el-menu>
`,
methods: {
onMenuItemClick(el) {
expect(el).to.be.equal(vm.$refs.item1);
this.clicksCount = this.clicksCount + 1;
}
},
data() {
return {
clicksCount: 0
};
}
}, true);
var item1 = vm.$refs.item1;
item1.$el.click();
setTimeout(_ => {
expect(vm.clicksCount).to.be.equal(1);
done();
}, 20);
});
it('menu-item disabled', done => {
vm = createVue({
template: `
<el-menu default-active="2">
<el-menu-item index="1" ref="item1" disabled>处理中心</el-menu-item>
<el-menu-item index="2" ref="item2">订单管理</el-menu-item>
</el-menu>
`
}, true);
expect(vm.$refs.item2.$el.classList.contains('is-active')).to.be.true;
vm.$refs.item1.$el.click();
setTimeout(_ => {
expect(vm.$refs.item1.$el.classList.contains('is-active')).to.be.false;
done();
}, 20);
});
describe('default active', () => {
it('normal active', done => {
vm = createVue({
template: `
<el-menu default-active="2">
<el-menu-item index="1" ref="item1">处理中心</el-menu-item>
<el-menu-item index="2" ref="item2">订单管理</el-menu-item>
</el-menu>
`
}, true);
expect(vm.$refs.item2.$el.classList.contains('is-active')).to.be.true;
vm.$refs.item1.$el.click();
setTimeout(_ => {
expect(vm.$refs.item1.$el.classList.contains('is-active')).to.be.true;
done();
}, 20);
});
it('dynamic active', done => {
vm = createVue({
template: `
<el-menu :default-active="active">
<el-menu-item index="1" ref="item1">active watch处理中心</el-menu-item>
<el-menu-item index="2" ref="item2">active watch订单管理</el-menu-item>
</el-menu>
`,
data() {
return {
active: '2'
};
}
}, true);
setTimeout(_ => {
vm.active = '1';
setTimeout(_ => {
expect(vm.$refs.item1.$el.classList.contains('is-active')).to.be.true;
done();
}, 20);
}, 100);
});
it('vertical submenu item active', done => {
vm = createVue({
template: `
<div>
<el-menu default-active="2-2">
<el-menu-item index="1" ref="item1">处理中心</el-menu-item>
<el-submenu index="2" ref="submenu">
<template slot="title">我的工作台</template>
<el-menu-item index="2-1">选项1</el-menu-item>
<el-menu-item index="2-2" ref="submenuItem2">选项2</el-menu-item>
<el-menu-item index="2-3">选项3</el-menu-item>
</el-submenu>
<el-menu-item index="3">订单管理</el-menu-item>
</el-menu>
</div>
`
}, true);
expect(vm.$refs.submenuItem2.$el.classList.contains('is-active')).to.be.true;
setTimeout(_ => {
expect(vm.$refs.submenu.$el.classList.contains('is-opened')).to.be.true;
expect(vm.$refs.submenu.$el.classList.contains('is-active')).to.be.true;
done();
}, 20);
});
it('horizontal submenu item active', done => {
vm = createVue({
template: `
<div>
<el-menu default-active="2-2">
<el-menu-item index="1" ref="item1">处理中心</el-menu-item>
<el-submenu index="2" ref="submenu">
<template slot="title">我的工作台</template>
<el-menu-item index="2-1">选项1</el-menu-item>
<el-menu-item index="2-2" ref="submenuItem2">选项2</el-menu-item>
<el-menu-item index="2-3">选项3</el-menu-item>
</el-submenu>
<el-menu-item index="3">订单管理</el-menu-item>
</el-menu>
</div>
`
}, true);
expect(vm.$refs.submenuItem2.$el.classList.contains('is-active')).to.be.true;
setTimeout(_ => {
expect(vm.$refs.submenu.$el.classList.contains('is-opened')).to.be.true;
expect(vm.$refs.submenu.$el.classList.contains('is-active')).to.be.true;
done();
}, 20);
});
});
describe('submenu', function() {
it('toggle', done => {
vm = createVue({
template: `
<el-menu>
<el-menu-item index="1" ref="item1">处理中心</el-menu-item>
<el-submenu index="2" ref="submenu">
<template slot="title">我的工作台</template>
<el-menu-item index="2-1">选项1</el-menu-item>
<el-menu-item index="2-2" ref="submenuItem2">选项2</el-menu-item>
<el-menu-item index="2-3">选项3</el-menu-item>
</el-submenu>
<el-menu-item index="3">订单管理</el-menu-item>
</el-menu>
`,
data() {
return {
};
}
}, true);
var submenuItem2 = vm.$refs.submenuItem2;
var submenu = vm.$refs.submenu;
submenu.$el.querySelector('.el-submenu__title').click();
setTimeout(_ => {
expect(submenu.$el.classList.contains('is-opened')).to.be.true;
submenuItem2.$el.click();
setTimeout(_ => {
expect(submenuItem2.$el.classList.contains('is-active')).to.be.true;
submenu.$el.querySelector('.el-submenu__title').click();
setTimeout(_ => {
expect(submenu.$el.classList.contains('is-opened')).to.not.true;
done();
}, 20);
}, 20);
}, 20);
});
it('default opened', done => {
vm = createVue({
template: `
<el-menu :default-openeds="defaultOpeneds">
<el-menu-item index="1">default opened处理中心</el-menu-item>
<el-submenu index="2" ref="submenu1">
<template slot="title">default opened我的工作台</template>
<el-menu-item index="2-1">选项1</el-menu-item>
<el-menu-item index="2-2" ref="submenu1Item2">选项2</el-menu-item>
<el-menu-item index="2-3">选项3</el-menu-item>
</el-submenu>
<el-submenu index="3" ref="submenu2">
<template slot="title">default opened订单管理</template>
<el-menu-item index="3-1">选项1</el-menu-item>
<el-menu-item index="3-2" ref="submenu2Item2">选项2</el-menu-item>
<el-menu-item index="3-3">选项3</el-menu-item>
</el-submenu>
</el-menu>
`,
data() {
return {
defaultOpeneds: ['2', '3']
};
}
}, true);
expect(vm.$refs.submenu1.$el.classList.contains('is-opened')).to.be.true;
expect(vm.$refs.submenu2.$el.classList.contains('is-opened')).to.be.true;
vm.defaultOpeneds = ['2'];
setTimeout(_ => {
expect(vm.$refs.submenu1.$el.classList.contains('is-opened')).to.be.true;
expect(vm.$refs.submenu2.$el.classList.contains('is-opened')).to.not.true;
done();
}, 20);
});
it('disabled', done => {
vm = createVue({
template: `
<el-menu>
<el-menu-item index="1" ref="item1">处理中心</el-menu-item>
<el-submenu index="2" ref="submenu" disabled>
<template slot="title">我的工作台</template>
<el-menu-item index="2-1">选项1</el-menu-item>
<el-menu-item index="2-2" ref="submenuItem2">选项2</el-menu-item>
<el-menu-item index="2-3">选项3</el-menu-item>
</el-submenu>
<el-menu-item index="3">订单管理</el-menu-item>
</el-menu>
`
}, true);
var submenu = vm.$refs.submenu;
submenu.$el.querySelector('.el-submenu__title').click();
setTimeout(_ => {
expect(submenu.$el.classList.contains('is-opened')).to.be.false;
done();
}, 20);
});
});
it('unique-opened', done => {
vm = createVue({
template: `
<el-menu unique-opened default-active="2-2">
<el-menu-item index="1">处理中心</el-menu-item>
<el-submenu index="2" ref="submenu1">
<template slot="title">我的工作台</template>
<el-menu-item index="2-1">选项1</el-menu-item>
<el-menu-item index="2-2" ref="submenu1Item2">选项2</el-menu-item>
<el-menu-item index="2-3">选项3</el-menu-item>
</el-submenu>
<el-submenu index="3" ref="submenu2">
<template slot="title">订单管理</template>
<el-menu-item index="3-1">选项1</el-menu-item>
<el-menu-item index="3-2" ref="submenu2Item2">选项2</el-menu-item>
<el-menu-item index="3-3">选项3</el-menu-item>
</el-submenu>
</el-menu>
`,
data() {
return {
};
}
}, true);
vm.$refs.submenu2.$el.querySelector('.el-submenu__title').click();
setTimeout(_ => {
expect(vm.$refs.submenu1.$el.classList.contains('is-opened')).to.not.true;
done();
}, 20);
});
it('horizontal mode', done => {
vm = createVue({
template: `
<el-menu mode="horizontal">
<el-menu-item index="1">处理中心</el-menu-item>
<el-submenu index="2" ref="submenu">
<template slot="title">我的工作台</template>
<el-menu-item index="2-1">选项1</el-menu-item>
<el-menu-item index="2-2" ref="submenuItem2">选项2</el-menu-item>
<el-menu-item index="2-3">选项3</el-menu-item>
</el-submenu>
<el-menu-item index="3">订单管理</el-menu-item>
</el-menu>
`,
data() {
return {
};
}
}, true);
expect(vm.$el.classList.contains('el-menu--horizontal')).to.be.true;
var submenu = vm.$refs.submenu;
triggerEvent(submenu.$el, 'mouseenter');
setTimeout(_ => {
expect(document.body.querySelector('.el-menu--popup').parentElement.style.display).to.not.ok;
done();
}, 500);
});
it('menu trigger click', done => {
vm = createVue({
template: `
<el-menu mode="horizontal" menu-trigger="click">
<el-menu-item index="1">处理中心</el-menu-item>
<el-submenu index="2" ref="submenu">
<template slot="title">我的工作台</template>
<el-menu-item index="2-1">选项1</el-menu-item>
<el-menu-item index="2-2" ref="submenuItem2">选项2</el-menu-item>
<el-menu-item index="2-3">选项3</el-menu-item>
</el-submenu>
<el-menu-item index="3">订单管理</el-menu-item>
</el-menu>
`,
data() {
return {
};
}
}, true);
expect(vm.$el.classList.contains('el-menu--horizontal')).to.be.true;
var submenu = vm.$refs.submenu;
var triggerElm = submenu.$el.querySelector('.el-submenu__title');
triggerEvent(submenu.$el, 'mouseenter');
triggerElm.click();
setTimeout(_ => {
expect(document.body.querySelector('.el-menu--popup').parentElement.style.display).to.not.ok;
triggerElm.click();
setTimeout(_ => {
expect(document.body.querySelector('.el-menu--popup').parentElement.style.display).to.be.equal('none');
done();
}, 1000);
}, 500);
});
it('menu group', () => {
vm = createVue({
template: `
<el-menu mode="vertical" default-active="1">
<el-menu-item-group title="分组一" ref="group1">
<el-menu-item index="1"><i class="el-icon-message"></i>导航一</el-menu-item>
<el-menu-item index="2"><i class="el-icon-message"></i>导航二</el-menu-item>
</el-menu-item-group>
<el-submenu index="5">
<template slot="title">导航五</template>
<el-menu-item-group title="分组二">
<el-menu-item index="5-1">选项1</el-menu-item>
<el-menu-item index="5-2">选项2</el-menu-item>
</el-menu-item-group>
</el-submenu>
</el-menu>
`
}, true);
expect(vm.$refs.group1.$el.querySelector('.el-menu-item-group__title').innerText).to.be.equal('分组一');
});
it('dynamic menus, issue 9092', done => {
vm = createVue({
template: `
<el-menu :default-active="active">
<el-menu-item
v-for="menu in menus"
:index="menu.name"
:key="menu.name">
{{menu.description}}
</el-menu-item>
</el-menu>
`,
data() {
return {
active: '',
menus: []
};
}
}, true);
setTimeout(_ => {
vm.active = '2';
vm.menus = [
{name: '1', description: 'happy'},
{name: '2', description: 'new'},
{name: '3', description: 'year'}
];
setTimeout(_ => {
expect(vm.$el.querySelector('.el-menu-item.is-active').innerText).to.equal('new');
done();
}, 20);
}, 100);
});
});

View File

@@ -0,0 +1,263 @@
import MessageBox from 'packages/message-box';
describe('MessageBox', () => {
let hasPromise = true;
before(() => {
if (!window.Promise) {
hasPromise = false;
window.Promise = require('es6-promise').Promise;
}
});
after(() => {
if (!hasPromise) {
window.Promise = undefined;
}
});
afterEach(() => {
const el = document.querySelector('.el-message-box__wrapper');
if (!el) return;
if (el.parentNode) {
el.parentNode.removeChild(el);
}
MessageBox.close();
});
it('create and close', done => {
MessageBox({
type: 'success',
title: '消息',
message: '这是一段内容'
});
setTimeout(() => {
const msgbox = document.querySelector('.el-message-box__wrapper');
expect(msgbox.__vue__.$parent.visible).to.true;
expect(msgbox.querySelector('.el-message-box__title span').textContent).to.equal('消息');
expect(msgbox.querySelector('.el-message-box__message')
.querySelector('p').textContent).to.equal('这是一段内容');
MessageBox.close();
expect(msgbox.__vue__.$parent.visible).to.false;
done();
}, 300);
});
it('invoke with strings', done => {
MessageBox('消息', '这是一段内容', 'success');
setTimeout(() => {
expect(document.querySelector('.el-message-box__wrapper')).to.exist;
done();
}, 300);
});
it('custom icon', done => {
MessageBox({
type: 'warning',
iconClass: 'el-icon-question',
message: '这是一段内容'
});
setTimeout(() => {
const icon = document.querySelector('.el-message-box__status');
expect(icon.classList.contains('el-icon-question')).to.true;
done();
}, 300);
});
it('html string', done => {
MessageBox({
title: 'html string',
dangerouslyUseHTMLString: true,
message: '<strong>html string</strong>'
});
setTimeout(() => {
const message = document.querySelector('.el-message-box__message strong');
expect(message.textContent).to.equal('html string');
done();
}, 300);
});
it('distinguish cancel and close', done => {
let msgAction = '';
MessageBox({
title: '消息',
message: '这是一段内容',
distinguishCancelAndClose: true
}, action => {
msgAction = action;
});
setTimeout(() => {
document.querySelector('.el-message-box__close').click();
setTimeout(() => {
expect(msgAction).to.equal('close');
done();
}, 10);
}, 10);
});
it('alert', done => {
MessageBox.alert('这是一段内容', {
title: '标题名称',
type: 'warning'
});
setTimeout(() => {
document.querySelector('.v-modal').click();
expect(document.querySelector('.el-message-box__wrapper')
.__vue__.$parent.visible).to.true;
expect(document.querySelector('.el-message-box__wrapper')
.__vue__.$parent.type).to.equal('warning');
done();
}, 300);
});
it('confirm', done => {
MessageBox.confirm('这是一段内容', {
title: '标题名称',
type: 'warning'
});
setTimeout(() => {
document.querySelector('.el-message-box__wrapper')
.querySelector('.el-button--primary').click();
expect(document.querySelector('.el-message-box__wrapper')
.__vue__.$parent.visible).to.false;
done();
}, 200);
});
it('prompt', done => {
MessageBox.prompt('这是一段内容', {
title: '标题名称',
inputPattern: /test/,
inputErrorMessage: 'validation failed'
});
setTimeout(() => {
const messageBox = document.querySelector('.el-message-box__wrapper').__vue__.$parent;
expect(messageBox.$el.querySelector('.el-message-box__input')).to.exist;
const haveFocus = messageBox.$el.querySelector('input').isSameNode(document.activeElement);
expect(haveFocus).to.true;
messageBox.inputValue = 'no';
setTimeout(() => {
expect(messageBox.$el.querySelector('.el-message-box__errormsg')
.textContent).to.equal('validation failed');
done();
}, 100);
}, 700);
});
it('prompt: focus on textarea', done => {
MessageBox.prompt('这是一段内容', {
inputType: 'textarea',
title: '标题名称'
});
setTimeout(() => {
const messageBox = document.querySelector('.el-message-box__wrapper').__vue__.$parent;
const haveFocus = messageBox.$el.querySelector('textarea').isSameNode(document.activeElement);
expect(haveFocus).to.true;
done();
}, 700);
});
describe('custom validator', () => {
it('returns a string', done => {
const validator = value => {
if (value !== 'test') return 'wrong';
return true;
};
MessageBox.prompt('这是一段内容', {
title: '标题名称',
inputValidator: validator
});
setTimeout(() => {
const messageBox = document.querySelector('.el-message-box__wrapper').__vue__.$parent;
messageBox.inputValue = 'no';
setTimeout(() => {
expect(document.querySelector('.el-message-box__errormsg')
.textContent).to.equal('wrong');
messageBox.inputValue = 'test';
setTimeout(() => {
expect(document.querySelector('.el-message-box__errormsg')
.textContent).to.equal('');
done();
}, 100);
}, 100);
}, 200);
});
it('returns false', done => {
const validator = value => false;
MessageBox.prompt('这是一段内容', {
title: '标题名称',
inputValidator: validator
});
setTimeout(() => {
const messageBox = document.querySelector('.el-message-box__wrapper').__vue__.$parent;
messageBox.inputValue = 'no';
setTimeout(() => {
expect(document.querySelector('.el-message-box__errormsg')
.textContent).to.equal('输入的数据不合法!');
done();
}, 100);
}, 200);
});
});
it('callback', done => {
let msgAction = '';
MessageBox({
title: '消息',
message: '这是一段内容'
}, action => {
msgAction = action;
});
setTimeout(() => {
document.querySelector('.el-message-box__close').click();
setTimeout(() => {
expect(msgAction).to.equal('cancel');
done();
}, 10);
}, 10);
});
it('beforeClose', done => {
let msgAction = '';
MessageBox({
title: '消息',
message: '这是一段内容',
beforeClose: (action, instance) => {
instance.close();
}
}, action => {
msgAction = action;
});
setTimeout(() => {
document.querySelector('.el-message-box__wrapper .el-button--primary').click();
setTimeout(() => {
expect(msgAction).to.equal('confirm');
done();
}, 10);
}, 10);
});
describe('promise', () => {
it('resolve', done => {
MessageBox.confirm('此操作将永久删除该文件, 是否继续?', '提示')
.then(action => {
expect(action).to.equal('confirm');
done();
});
setTimeout(() => {
document.querySelector('.el-message-box__wrapper .el-button--primary').click();
}, 50);
});
it('reject', done => {
MessageBox.confirm('此操作将永久删除该文件, 是否继续?', '提示')
.catch(action => {
expect(action).to.equal('cancel');
done();
});
setTimeout(() => {
document.querySelector('.el-message-box__wrapper .el-button').click();
}, 50);
});
});
});

View File

@@ -0,0 +1,115 @@
import { triggerEvent } from '../util';
import Message from 'packages/message';
describe('Message', () => {
afterEach(() => {
const el = document.querySelector('.el-message');
if (!el) return;
if (el.parentNode) {
el.parentNode.removeChild(el);
}
if (el.__vue__) {
el.__vue__.$destroy();
}
});
it('automatically close', done => {
Message({
message: '灰风',
duration: 500
});
const message = document.querySelector('.el-message__content');
expect(document.querySelector('.el-message')).to.exist;
expect(message.textContent).to.equal('灰风');
setTimeout(() => {
expect(document.querySelector('.el-message')).to.not.exist;
done();
}, 1000);
});
it('manually close', done => {
Message({
message: '夏天',
showClose: true
});
setTimeout(() => {
document.querySelector('.el-message__closeBtn').click();
setTimeout(() => {
expect(document.querySelector('.el-message')).to.not.exist;
done();
}, 500);
}, 500);
});
it('custom icon', done => {
Message({
message: '夏天',
iconClass: 'el-icon-close'
});
setTimeout(() => {
const icon = document.querySelector('.el-message i');
expect(icon.classList.contains('el-icon-close')).to.true;
done();
}, 500);
});
it('html string', () => {
Message({
message: '<strong>夏天</strong>',
dangerouslyUseHTMLString: true
});
const message = document.querySelector('.el-message strong');
expect(message.textContent).to.equal('夏天');
});
it('close all', done => {
Message({
message: '夏天',
duration: 0
});
Message({
message: '淑女',
duration: 0
});
setTimeout(() => {
Message.closeAll();
setTimeout(() => {
expect(document.querySelector('.el-message')).to.not.exist;
done();
}, 500);
}, 500);
});
it('create', () => {
Message('娜梅莉亚');
expect(document.querySelector('.el-message')).to.exist;
});
it('invoke with type', () => {
Message.success('毛毛狗');
expect(document.querySelector('.el-message').__vue__.type).to.equal('success');
});
it('center', () => {
Message({
message: '夏天',
center: true,
duration: 0
});
expect(document.querySelector('.el-message').classList.contains('is-center')).to.true;
});
it('reset timer', done => {
Message({
message: '白灵',
duration: 1000
});
setTimeout(() => {
triggerEvent(document.querySelector('.el-message'), 'mouseenter');
setTimeout(() => {
expect(document.querySelector('.el-message')).to.exist;
done();
}, 700);
}, 500);
});
});

View File

@@ -0,0 +1,74 @@
import VuePopup from 'element-ui/src/utils/popup';
import { createTest, destroyVM } from '../util';
const Popup = Object.assign({}, VuePopup, {
render(h) {
return h('div');
},
created() {
this.rendered = true;
}
});
describe('Mixin:vue-popup', () => {
let vm;
before(() => {
const modals = document.querySelectorAll('.v-modal');
[].forEach.call(modals, modal => {
modal &&
modal.parentNode &&
modal.parentNode.removeChild(modal);
});
});
afterEach(() => {
vm.close && vm.close();
destroyVM(vm);
const modal = document.querySelector('.v-modal');
modal &&
modal.parentNode &&
modal.parentNode.removeChild(modal);
});
it('show modal', () => {
vm = createTest(Popup);
vm.open();
expect(document.querySelector('.v-modal')).to.not.exist;
vm.close();
destroyVM(vm);
vm = createTest(Popup, { modal: true });
vm.open();
expect(document.querySelector('.v-modal')).to.exist;
});
it('custom modal class', () => {
vm = createTest(Popup, { modal: true, modalClass: 'custom-class' });
vm.open();
expect(document.querySelector('.v-modal').classList.contains('custom-class')).to.true;
});
it('lock scroll', done => {
vm = createTest(Popup, { modal: true });
vm.open();
expect(document.body.classList.contains('el-popup-parent--hidden')).to.be.true;
vm.close();
destroyVM(vm);
setTimeout(() => {
vm = createTest(Popup, { modal: true, lockScroll: false });
vm.open();
expect(document.body.classList.contains('el-popup-parent--hidden')).to.be.false;
done();
}, 200);
});
it('z-index should increase', () => {
vm = createTest(Popup, { modal: true });
vm.open();
const zIndex1 = document.querySelector('.v-modal').style.zIndex;
vm.close();
destroyVM(vm);
vm = createTest(Popup, { modal: true });
vm.open();
const zIndex2 = document.querySelector('.v-modal').style.zIndex;
expect(zIndex2 > zIndex1).to.true;
});
});

View File

@@ -0,0 +1,121 @@
import Vue from 'vue';
import { triggerEvent } from '../util';
import Notification from 'packages/notification';
describe('Notification', () => {
afterEach(() => {
const el = document.querySelector('.el-notification');
if (!el) return;
if (el.parentNode) {
el.parentNode.removeChild(el);
}
if (el.__vue__) {
el.__vue__.$destroy();
}
});
it('automatically close', done => {
Notification({
message: '玻璃蜡烛',
duration: 500
});
expect(document.querySelector('.el-notification')).to.exist;
setTimeout(() => {
expect(document.querySelector('.el-notification')).to.not.exist;
done();
}, 1000);
});
it('manually close', done => {
Notification({
message: '苍白母马'
});
setTimeout(() => {
document.querySelector('.el-notification__closeBtn').click();
setTimeout(() => {
expect(document.querySelector('.el-notification')).to.not.exist;
done();
}, 500);
}, 500);
});
it('create', () => {
Notification({
title: '狮子',
message: '狮鹫',
duration: 0
});
const group = document.querySelector('.el-notification__group');
const title = group.querySelector('.el-notification__title');
const message = group.querySelector('.el-notification__content p');
expect(document.querySelector('.el-notification')).to.exist;
expect(title.textContent).to.equal('狮子');
expect(message.textContent).to.equal('狮鹫');
});
it('html string as message', () => {
Notification({
title: '狮子',
message: '<strong>狮鹫</strong>',
dangerouslyUseHTMLString: true,
duration: 0
});
const message = document.querySelector('.el-notification__content strong');
expect(message.textContent).to.equal('狮鹫');
});
it('create by vnode', () => {
const fakeVM = new Vue();
const h = fakeVM.$createElement;
Notification({
message: h('p', { style: { color: 'red' } }, '大美兴,川普王')
});
const group = document.querySelector('.el-notification__group');
const message = group.querySelector('.el-notification__content');
expect(message.innerHTML).to.equal('<p style="color: red;">大美兴,川普王</p>');
});
it('alias by vnode', () => {
const fakeVM = new Vue();
const h = fakeVM.$createElement;
Notification.error(h('p', { style: { color: 'green' } }, '+1s'));
const group = document.querySelector('.el-notification__group');
const message = group.querySelector('.el-notification__content');
expect(message.innerHTML).to.equal('<p style="color: green;">+1s</p>');
});
it('invoke with type', () => {
Notification.success('太阳之子');
expect(document.querySelector('.el-notification').__vue__.type).to.equal('success');
});
it('reset timer', done => {
Notification({
message: '芳香总管',
duration: 1000
});
setTimeout(() => {
triggerEvent(document.querySelector('.el-notification'), 'mouseenter');
setTimeout(() => {
triggerEvent(document.querySelector('.el-notification'), 'mouseleave');
expect(document.querySelector('.el-notification')).to.exist;
done();
}, 700);
}, 500);
});
it('no close button', done => {
Notification({
message: 'Hello',
showClose: false
});
setTimeout(() => {
expect(document.querySelector('.el-notification__closeBtn')).to.not.exist;
done();
}, 500);
});
});

View File

@@ -0,0 +1,24 @@
import { createVue, destroyVM, waitImmediate } from '../util';
import PageHeader from 'packages/page-header';
describe('PageHeader', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('render well and trigger back event', async() => {
vm = createVue(PageHeader, {
content: 'content'
});
expect(vm.$el).to.exist;
const spy = sinon.spy();
vm.$on('back', spy);
vm.$el.querySelector('.el-page-header__left').click();
await waitImmediate();
expect(spy.calledOnce).to.be.true;
});
});

View File

@@ -0,0 +1,491 @@
import { createTest, createVue, triggerEvent, destroyVM } from '../util';
import Pagination from 'packages/pagination';
describe('Pagination', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', () => {
vm = createTest(Pagination);
const elm = vm.$el;
// prev
expect(elm.querySelector('button.btn-prev')).to.exist;
// pager
expect(elm.querySelector('ul.el-pager')).to.exist;
// next
expect(elm.querySelector('button.btn-next')).to.exist;
// jumper
expect(elm.querySelector('.el-pagination__jump')).to.exist;
// ->
expect(elm.querySelector('.el-pagination__rightwrapper')).to.exist;
});
it('set layout', () => {
vm = createTest(Pagination, {
layout: 'prev, pager, next'
});
const elm = vm.$el;
// prev
expect(elm.querySelector('button.btn-prev')).to.exist;
// pager
expect(elm.querySelector('ul.el-pager')).to.exist;
// next
expect(elm.querySelector('button.btn-next')).to.exist;
// not found jumper
expect(elm.querySelector('.el-pagination__jump')).to.not.exist;
// not found ->
expect(elm.querySelector('.el-pagination__rightwrapper')).to.not.exist;
// not found total
expect(elm.querySelector('.el-pagination__total')).to.not.exist;
});
it('layout: all in right, need clear float', () => {
vm = createTest(Pagination, {
layout: '->, prev, pager, next',
total: 100
}, true);
const elm = vm.$el;
let right_div = elm.querySelector('.el-pagination__rightwrapper');
expect(elm.clientHeight > 0 && right_div.clientHeight > 0).to.equal(true);
// elm 将来 padding 可能会变化, 所以使用 >= 来判定
expect(elm.clientHeight >= right_div.clientHeight).to.equal(true);
});
it('custom slot', () => {
vm = createVue({
template: `
<el-pagination
layout="slot, prev, pager, next"
:page-size="25"
:total="100">
<span class="slot-test">slot test</span>
</el-pagination>
`
});
expect(vm.$el.querySelector('.slot-test')).to.exist;
});
it('small', () => {
vm = createTest(Pagination, {
small: true
});
expect(vm.$el.classList.contains('el-pagination--small')).to.true;
});
it('pageSize', () => {
vm = createTest(Pagination, {
pageSize: 25,
total: 100
});
expect(vm.$el.querySelectorAll('li.number')).to.length(4);
});
it('pageSize: NaN', () => {
vm = createTest(Pagination, {
pageSize: NaN,
total: 100
});
const pagers = vm.$el.querySelectorAll('li.number');
expect(pagers).to.length(7);
});
it('pageCount', () => {
const vm = createTest(Pagination, {
pageSize: 25,
pageCount: 4
});
expect(vm.$el.querySelectorAll('li.number')).to.length(4);
});
it('pagerCount', () => {
const vm = createTest(Pagination, {
pageSize: 25,
total: 1000,
pagerCount: 21
});
expect(vm.$el.querySelectorAll('li.number')).to.length(21);
});
it('will work without total & page-count', (done) => {
const vm = createTest(Pagination, {
pageSize: 25,
currentPage: 2
});
vm.$el.querySelector('.btn-prev').click();
setTimeout(() => {
vm.internalCurrentPage.should.be.equal(1);
vm.$el.querySelector('.btn-prev').click();
vm.internalCurrentPage.should.be.equal(1);
done();
}, 20);
});
it('currentPage', () => {
vm = createTest(Pagination, {
pageSize: 20,
total: 200,
currentPage: 3
});
expect(vm.$el.querySelector('li.number.active')).to.have.property('textContent').to.equal('3');
});
it('currentPage: NaN', () => {
vm = createTest(Pagination, {
pageSize: 20,
total: 200,
currentPage: NaN
});
expect(vm.$el.querySelector('li.number.active')).to.have.property('textContent').to.equal('1');
expect(vm.$el.querySelectorAll('li.number')).to.length(7);
});
it('set currentPage & total', (done) => {
vm = createVue({
template: `
<el-pagination
@current-change="handleChange"
:current-page="currentPage"
:page-size="10"
:total="100" />
`,
methods: {
handleChange(val) {
this.currentPage = val;
this.page = val;
},
resetTotal() {
this.total = 30;
this.currentPage = 1;
}
},
data() {
return {
currentPage: 10
};
}
}, true);
expect(vm.$el.querySelector('li.number.active')).to.have.property('textContent').to.equal('10');
vm.resetTotal();
setTimeout(() => {
expect(vm.$el.querySelector('li.number.active')).to.have.property('textContent').to.equal('1');
done();
}, 50);
});
it('pageSizes', () => {
vm = createTest(Pagination, {
pageSizes: [10, 15, 35, 50],
pageSize: 35,
total: 1000,
layout: 'sizes, prev, pager, next'
});
expect(vm.$el.querySelector('.el-select-dropdown__item.selected')).to.property('textContent').include('35');
expect([].slice.call(vm.$el.querySelectorAll('.el-select-dropdown__item'))
.map(node => parseInt(node.textContent, 10)))
.to.deep.equal([10, 15, 35, 50]);
});
it('pageSizes:not found pageSize', () => {
vm = createTest(Pagination, {
pageSizes: [10, 15, 35, 50],
pageSize: 24,
total: 1000,
layout: 'sizes, prev, pager, next'
});
expect(vm.$el.querySelector('.el-select-dropdown__item.selected')).to.property('textContent').include('10');
});
it('layout is empty', () => {
vm = createTest(Pagination, {
layout: ''
});
expect(vm.$el.textContent).to.empty;
});
it('jumper: change value', (done) => {
vm = createVue({
template: `
<el-pagination
@current-change="handleChange"
:page-size="10"
layout="pager, jumper"
:total="100" />
`,
methods: {
handleChange(val) {
this.page = val;
}
},
data() {
return {
page: 1,
inputer: null
};
},
mounted() {
this.inputer = this.$children[0].$children[1].$children[0];
}
}, true);
const input = vm.inputer;
const changeValue = (value) => {
input.$emit('input', value);
input.$emit('change', value);
};
changeValue(1);
setTimeout(() => {
expect(input.value).to.equal(1);
// 多次输入不在min-max区间内的数字
changeValue(0);
setTimeout(() => {
expect(input.value).to.equal(1);
changeValue(0);
setTimeout(() => {
expect(input.value).to.equal(1);
changeValue(1000);
setTimeout(() => {
expect(input.value).to.equal(10);
changeValue(1000);
setTimeout(() => {
expect(input.value).to.equal(10);
done();
}, 50);
}, 50);
}, 50);
}, 50);
}, 50);
});
it('event:current-change', (done) => {
vm = createVue({
template: `
<el-pagination
:total="1000"
@current-change="change = true" />
`,
data() {
return { change: false };
}
});
const next = vm.$el.querySelector('button.btn-next');
const prev = vm.$el.querySelector('button.btn-prev');
expect(vm.change).to.false;
// click 9
let count = 9;
while (--count) {
next.click();
}
prev.click();
setTimeout(() => {
expect(vm.change).to.true;
done();
}, 50);
});
it('event:current-change after current page is manually updated', (done) => {
vm = createVue({
template: `
<el-pagination
:total="15"
:current-page.sync="currentPage"
@current-change="emitCount++" />
`,
data() {
return {
emitCount: 0,
currentPage: 1
};
}
});
const next = vm.$el.querySelector('button.btn-next');
next.click();
setTimeout(() => {
expect(vm.emitCount).to.equal(1);
vm.currentPage = 1;
setTimeout(() => {
expect(vm.emitCount).to.equal(1);
next.click();
setTimeout(() => {
expect(vm.emitCount).to.equal(2);
done();
}, 50);
}, 50);
}, 50);
});
it('event:size-change', done => {
vm = createVue({
template: `
<el-pagination
:total="100"
layout="sizes, prev, pager, next"
@size-change="trigger = true"
:pageSize="10" />
`,
data() {
return { trigger: false };
}
}, true);
expect(vm.trigger).to.false;
setTimeout(_ => {
vm.$el.querySelectorAll('li.el-select-dropdown__item')[1].click();
setTimeout(_ => {
expect(vm.trigger).to.true;
done();
}, 50);
}, 50);
});
it('event: prev and next click', done => {
vm = createVue({
template: `
<el-pagination
:total="100"
layout="sizes, prev, pager, next"
@prev-click="trigger = true"
@next-click="trigger = true"
:pageSize="10" />
`,
data() {
return { trigger: false };
}
}, true);
const prev = vm.$el.querySelector('.btn-prev');
const next = vm.$el.querySelector('.btn-next');
prev.click();
setTimeout(_ => {
expect(vm.trigger).to.false;
next.click();
setTimeout(_ => {
expect(vm.trigger).to.true;
done();
}, 50);
}, 50);
});
it('pageSize > total', () => {
vm = createVue({
template: `
<el-pagination
@current-change="handleChange"
:page-size="1000"
:total="0" />
`,
methods: {
handleChange(val) {
this.page = val;
}
},
data() {
return { page: 1 };
}
});
const input = vm.$el.querySelector('.el-pagination__jump input');
input.value = 2;
triggerEvent(input, 'change');
expect(vm.page).to.equal(1);
input.value = '我好帅';
triggerEvent(input, 'change');
expect(vm.page).to.equal(1);
});
it('hideOnSinglePage', () => {
vm = createVue({
template: `
<el-pagination
hide-on-single-page
:total="1" />
`
});
expect(vm.$el.nodeType).to.be.equal(window.Node.COMMENT_NODE);
});
describe('click pager', () => {
it('click ul', () => {
vm = createTest(Pagination, {
total: 1000
}, true);
vm.$el.querySelector('.el-pager').click();
expect(vm.internalCurrentPage).to.equal(1);
});
it('click li', () => {
vm = createTest(Pagination, {
total: 1000
}, true);
vm.$el.querySelectorAll('.el-pager li.number')[1].click();
expect(vm.internalCurrentPage).to.equal(2);
});
it('click next icon-more', () => {
vm = createTest(Pagination, {
total: 1000
}, true);
vm.$el.querySelector('.el-pager .more').click();
expect(vm.internalCurrentPage).to.equal(6);
});
it('click prev icon-more', done => {
vm = createTest(Pagination, {
total: 1000
}, true);
vm.$el.querySelector('.btn-quicknext.more').click();
setTimeout(_ => {
expect(vm.$el.querySelector('.btn-quickprev.more')).to.exist;
vm.$el.querySelector('.btn-quickprev.more').click();
expect(vm.internalCurrentPage).to.equal(1);
done();
}, 50);
});
it('click last page', done => {
vm = createTest(Pagination, {
total: 1000
}, true);
const nodes = vm.$el.querySelectorAll('li.number');
nodes[nodes.length - 1].click();
setTimeout(_ => {
expect(vm.$el.querySelector('.btn-quickprev.more')).to.exist;
expect(vm.$el.querySelector('.btn-quicknext.more')).to.not.exist;
done();
}, 50);
});
});
});

View File

@@ -0,0 +1,29 @@
import { createVue, destroyVM } from '../util';
describe('Popconfirm', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
describe('trigger', () => {
const createVM = () => {
return createVue(`
<div>
<el-popconfirm
ref="popover"
title="content">
<button slot="reference">trigger</button>
</el-popconfirm>
</div>
`, true);
};
it('click', () => {
vm = createVM();
vm.$el.querySelector('button').click();
document.body.click();
expect(document.body.querySelector('.el-popconfirm__action').style.display).to.equal('');
});
});
});

View File

@@ -0,0 +1,309 @@
import { createVue, triggerEvent, createTest, destroyVM, wait } from '../util';
import Popover from 'packages/popover';
describe('Popover', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
describe('trigger', () => {
const createVM = (trigger) => {
return createVue(`
<div>
<el-popover
ref="popover"
trigger="${trigger}"
content="content">
<button slot="reference">trigger ${trigger}</button>
</el-popover>
</div>
`, true);
};
it('click', () => {
vm = createVM('click');
const compo = vm.$refs.popover;
vm.$el.querySelector('button').click();
expect(compo.showPopper).to.true;
document.body.click();
expect(compo.showPopper).to.false;
});
it('hover', done => {
vm = createVM('hover');
const compo = vm.$refs.popover;
const button = vm.$el.querySelector('button');
triggerEvent(button, 'mouseenter');
expect(compo.showPopper).to.true;
triggerEvent(button, 'mouseleave');
setTimeout(_ => {
expect(compo.showPopper).to.false;
done();
}, 250); // 代码里是 200ms
});
it('manual', done => {
vm = createVM('manual');
const compo = vm.$refs.popover;
const button = vm.$el.querySelector('button');
triggerEvent(button, 'mouseenter');
expect(compo.showPopper).to.false;
triggerEvent(button, 'mouseleave');
setTimeout(_ => {
expect(compo.showPopper).to.false;
done();
}, 250); // 代码里是 200ms
});
it('focus input in children node', () => {
vm = createVue(`
<div>
<el-popover
ref="popover"
trigger="focus"
content="content">
<div slot="reference">
<input type="text" value="trigger focus" />
</div>
</el-popover>
</div>
`, true);
const compo = vm.$refs.popover;
const input = vm.$el.querySelector('input');
input.focus();
expect(compo.showPopper).to.true;
input.blur();
expect(compo.showPopper).to.false;
});
it('focus textarea in children node', () => {
vm = createVue(`
<div>
<el-popover
ref="popover"
trigger="focus"
content="content">
<div slot="reference">
<textarea></textarea>
</div>
</el-popover>
</div>
`, true);
const compo = vm.$refs.popover;
const textarea = vm.$el.querySelector('textarea');
textarea.focus();
expect(compo.showPopper).to.true;
textarea.blur();
expect(compo.showPopper).to.false;
});
it('focus input', () => {
vm = createVue(`
<div>
<el-popover
ref="popover"
trigger="focus"
content="content">
<input type="text" slot="reference" value="trigger focus" />
</el-popover>
</div>
`, true);
const compo = vm.$refs.popover;
const input = vm.$el.querySelector('input');
input.focus();
expect(compo.showPopper).to.true;
input.blur();
expect(compo.showPopper).to.false;
});
it('focus button', () => {
vm = createVM('focus');
const compo = vm.$refs.popover;
const button = vm.$el.querySelector('button');
triggerEvent(button, 'mousedown');
expect(compo.showPopper).to.true;
triggerEvent(button, 'mouseup');
expect(compo.showPopper).to.false;
});
});
describe('create by directive', () => {
const vm = createVue({
template: `
<div>
<el-popover
ref="popover1"
trigger="click"
content="content">
</el-popover>
<button v-popover:popover1>create by directive</button>
</div>
`,
directives: {
Popover: Popover.directive
}
}, true);
const compo = vm.$refs.popover1;
it('render', () => {
expect(vm.$el.querySelector('.el-popover')).to.have.deep.property('textContent').include('content');
});
it('triggering click', done => {
vm.$el.querySelector('button').click();
expect(compo.popperElm).to.not.exist;
vm.$nextTick(_ => {
const popperElm = compo.popperElm;
expect(getComputedStyle(popperElm).display).to.not.equal('none');
done();
});
});
it('click outside', () => {
document.body.click();
expect(compo.showPopper).to.false;
});
});
describe('create by slot', () => {
const vm = createVue(`
<div>
<el-popover
ref="popover"
trigger="click"
content="content">
<button slot="reference">create by slot</button>
</el-popover>
</div>
`, true);
const compo = vm.$refs.popover;
it('render', () => {
expect(vm.$el.querySelector('.el-popover')).to.have.deep.property('textContent').include('content');
});
it('triggering click', done => {
vm.$el.querySelector('button').click();
expect(compo.popperElm).to.not.exist;
vm.$nextTick(_ => {
const popperElm = compo.popperElm;
expect(getComputedStyle(popperElm).display).to.not.equal('none');
done();
});
});
it('click outside', () => {
document.body.click();
expect(compo.showPopper).to.false;
});
});
it('show/hide events', done => {
vm = createVue({
template: `
<div>
<el-popover
ref="popover"
trigger="click"
@show="handleShow"
@hide="handleHide"
content="content">
<button slot="reference">trigger</button>
</el-popover>
</div>
`,
methods: {
handleShow() {
this.trigger = true;
},
handleHide() {
this.trigger = false;
}
},
data() {
return {
trigger: false
};
}
}, true);
vm.$el.querySelector('button').click();
setTimeout(_ => {
expect(vm.trigger).to.true;
document.body.click();
setTimeout(_ => {
expect(vm.trigger).to.false;
done();
}, 50);
}, 50);
});
describe('open/close delays', () => {
it('100ms open / instant close', async() => {
vm = createVue(`
<div>
<el-popover
ref="popover"
content="content"
trigger="hover"
:open-delay="100"
:close-delay="0">
<button slot="reference">reference</button>
</el-popover>
</div>
`, true);
const compo = vm.$refs.popover;
const button = vm.$el.querySelector('button');
triggerEvent(button, 'mouseenter');
expect(compo.showPopper).to.false;
await wait(150);
expect(compo.showPopper).to.true;
triggerEvent(button, 'mouseleave');
expect(compo.showPopper).to.false;
});
it('instant open / 100ms close', async() => {
vm = createVue(`
<div>
<el-popover
ref="popover"
content="content"
trigger="hover"
:open-delay="0"
:close-delay="100">
<button slot="reference">reference</button>
</el-popover>
</div>
`, true);
const compo = vm.$refs.popover;
const button = vm.$el.querySelector('button');
triggerEvent(button, 'mouseenter');
expect(compo.showPopper).to.true;
triggerEvent(button, 'mouseleave');
expect(compo.showPopper).to.true;
await wait(150);
expect(compo.showPopper).to.false;
});
});
it('destroy event', () => {
vm = createTest(Popover, {
reference: document.createElement('div'),
popper: document.createElement('div')
});
expect(() => vm.$destroy(true)).not.throw();
});
});

View File

@@ -0,0 +1,191 @@
import { createVue, destroyVM, waitImmediate } from '../util';
describe('Progress', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', () => {
vm = createVue({
template: `
<div>
<el-progress ref="percent0" :percentage="0"></el-progress>
<el-progress ref="percent50" :percentage="50"></el-progress>
<el-progress ref="percent100" :percentage="100"></el-progress>
</div>
`
}, true);
expect(vm.$refs.percent0.$el.querySelector('.el-progress__text').innerText).to.be.equal('0%');
expect(vm.$refs.percent0.$el.querySelector('.el-progress-bar__inner').style.width).to.be.equal('0%');
expect(vm.$refs.percent50.$el.querySelector('.el-progress__text').innerText).to.be.equal('50%');
expect(vm.$refs.percent50.$el.querySelector('.el-progress-bar__inner').style.width).to.be.equal('50%');
expect(vm.$refs.percent100.$el.querySelector('.el-progress__text').innerText).to.be.equal('100%');
expect(vm.$refs.percent100.$el.querySelector('.el-progress-bar__inner').style.width).to.be.equal('100%');
});
it('status', () => {
vm = createVue({
template: `
<div>
<el-progress ref="lineSuccess" :percentage="100" status="success"></el-progress>
<el-progress ref="lineException" :percentage="0" status="exception"></el-progress>
<el-progress type="circle" ref="circleSuccess" :percentage="100" status="success"></el-progress>
<el-progress type="circle" ref="circleException" :percentage="0" status="exception"></el-progress>
</div>
`
}, true);
expect(vm.$refs.lineSuccess.$el.classList.contains('is-success')).to.be.true;
expect(vm.$refs.lineSuccess.$el.querySelector('.el-progress__text .el-icon-circle-check')).to.be.exist;
expect(vm.$refs.lineException.$el.classList.contains('is-exception')).to.be.true;
expect(vm.$refs.lineException.$el.querySelector('.el-progress__text .el-icon-circle-close')).to.be.exist;
expect(vm.$refs.circleSuccess.$el.classList.contains('is-success')).to.be.true;
expect(vm.$refs.circleSuccess.$el.querySelector('.el-progress__text .el-icon-check')).to.be.exist;
expect(vm.$refs.circleException.$el.classList.contains('is-exception')).to.be.true;
expect(vm.$refs.circleException.$el.querySelector('.el-progress__text .el-icon-close')).to.be.exist;
});
it('text inside', () => {
vm = createVue({
template: `
<el-progress :percentage="50" text-inside></el-progress>
`
}, true);
expect(vm.$el.classList.contains('el-progress--text-inside')).to.be.true;
});
it('stroke width', () => {
vm = createVue({
template: `
<el-progress :percentage="50" :stroke-width="8"></el-progress>
`
}, true);
expect(vm.$el.querySelector('.el-progress-bar__outer').style.height).to.be.equal('8px');
});
it('show text', () => {
vm = createVue({
template: `
<el-progress :percentage="50" :show-text="false"></el-progress>
`
}, true);
expect(vm.$el.querySelector('.el-progress__text')).to.not.exist;
});
it('circle', () => {
vm = createVue({
template: `
<el-progress type="circle" :percentage="50"></el-progress>
`
}, true);
expect(vm.$el.classList.contains('el-progress--circle')).to.be.true;
});
it('dashboard', () => {
vm = createVue({
template: `
<el-progress type="dashboard" :percentage="50"></el-progress>
`
}, true);
expect(vm.$el.classList.contains('el-progress--dashboard')).to.be.true;
});
it('width', () => {
vm = createVue({
template: `
<el-progress type="circle" :percentage="50" :width="120"></el-progress>
`
}, true);
expect(vm.$el.querySelector('.el-progress-circle').style.height).to.be.equal('120px');
expect(vm.$el.querySelector('.el-progress-circle').style.width).to.be.equal('120px');
});
it('should work with stroke-width', () => {
vm = createVue({
template: `
<el-progress :text-inside="true" :stroke-width="36" :percentage="0"></el-progress>
`
}, true);
expect(vm.$el.querySelector('.el-progress-bar__innerText').offsetTop).to.be.equal(12);
});
it('color', () => {
vm = createVue({
template: `
<el-progress :percentage="50" color="rgb(0, 0, 0)"></el-progress>
`
}, true);
expect(vm.$el.querySelector('.el-progress-bar__inner').style.backgroundColor).to.equal('rgb(0, 0, 0)');
});
it('color is function', async() => {
vm = createVue({
template: `
<el-progress :percentage="percentage" :color="customColor"></el-progress>
`,
data() {
return {
percentage: 50
};
},
methods: {
customColor(percentage) {
if (percentage > 50) {
return '#13ce66';
} else {
return '#20a0ff';
}
},
increase() {
this.percentage = 60;
}
}
}, true);
expect(vm.$el.querySelector('.el-progress-bar__inner').style.backgroundColor).to.equal('rgb(32, 160, 255)');
vm.increase();
await waitImmediate();
expect(vm.$el.querySelector('.el-progress-bar__inner').style.backgroundColor).to.equal('rgb(19, 206, 102)');
});
it('color is array', async() => {
vm = createVue({
template: `
<el-progress :percentage="percentage" :color="colors"></el-progress>
`,
data() {
return {
percentage: 50,
colors: [
{color: '#f56c6c', percentage: 20},
{color: '#e6a23c', percentage: 40},
{color: '#20a0ff', percentage: 60},
{color: '#13ce66', percentage: 80},
{color: '#6f7ad3', percentage: 100}
]
};
},
methods: {
increase() {
this.percentage = 70;
}
}
}, true);
// #20a0ff
expect(vm.$el.querySelector('.el-progress-bar__inner').style.backgroundColor).to.equal('rgb(32, 160, 255)');
vm.increase();
await waitImmediate();
// #13ce66
expect(vm.$el.querySelector('.el-progress-bar__inner').style.backgroundColor).to.equal('rgb(19, 206, 102)');
});
it('format content', () => {
vm = createVue({
template: `
<el-progress :percentage="50" :format="format"></el-progress>
`,
methods: {
format(percentage) {
return `占比${percentage}%`;
}
}
}, true);
expect(vm.$el.querySelector('.el-progress__text').innerHTML).to.equal('占比50%');
});
});

View File

@@ -0,0 +1,425 @@
import { createVue, destroyVM, triggerKeyDown } from '../util';
describe('Radio', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', done => {
vm = createVue({
template: `
<el-radio v-model="radio" label="a">
</el-radio>
`,
data() {
return {
radio: ''
};
}
}, true);
let radioElm = vm.$el;
expect(radioElm.classList.contains('el-radio')).to.be.true;
radioElm.click();
setTimeout(_ => {
expect(radioElm.querySelector('.is-checked')).to.be.ok;
done();
}, 10);
});
it('disabled', done => {
vm = createVue({
template: `
<el-radio
v-model="radio"
label="3"
disabled
>
</el-radio>
`,
data() {
return {
radio: ''
};
}
}, true);
let radioElm = vm.$el;
radioElm.click();
setTimeout(_ => {
expect(vm.radio === '').to.be.true;
expect(radioElm.querySelector('.is-disabled')).to.be.ok;
done();
}, 10);
});
it('border', () => {
vm = createVue({
template: `
<el-radio
v-model="radio"
label="3"
border
>
</el-radio>
`,
data() {
return {
radio: ''
};
}
}, true);
let radioElm = vm.$el;
expect(radioElm.classList.contains('is-bordered')).to.be.true;
});
it('change event', done => {
vm = createVue({
template: `
<el-radio
v-model="radio"
label="3"
@change="handleChange"
>
</el-radio>
`,
data() {
return {
radio: '',
data: ''
};
},
methods: {
handleChange(val) {
this.data = val;
}
}
}, true);
let radioElm = vm.$el;
radioElm.click();
setTimeout(_ => {
expect(vm.data).to.equal('3');
done();
}, 10);
});
it('change event only triggers on user input', done => {
vm = createVue({
template: `
<el-radio
v-model="radio"
label="3"
@change="handleChange"
>
</el-radio>
`,
data() {
return {
radio: '',
data: ''
};
},
methods: {
handleChange(val) {
this.data = val;
}
}
}, true);
vm.radio = '3';
setTimeout(_ => {
expect(vm.data).to.equal('');
done();
}, 10);
});
describe('Radio group', () => {
it('create', done => {
vm = createVue({
template: `
<el-radio-group v-model="radio">
<el-radio :label="3" ref="radio1">备选项</el-radio>
<el-radio :label="6" ref="radio2">备选项</el-radio>
<el-radio :label="9">备选项</el-radio>
</el-radio-group>
`,
data() {
return {
radio: 3
};
}
}, true);
setTimeout(_ => {
expect(vm.$refs.radio1.$el.querySelector('.is-checked')).to.be.ok;
let radioElm = vm.$refs.radio2.$el;
radioElm.click();
setTimeout(_ => {
expect(radioElm.querySelector('.is-checked')).to.be.ok;
expect(vm.radio === 6).to.be.true;
done();
}, 10);
}, 50);
});
it('disabled', done => {
vm = createVue({
template: `
<el-radio-group v-model="radio" disabled>
<el-radio :label="3" ref="radio1">备选项</el-radio>
<el-radio :label="6" ref="radio2">备选项</el-radio>
<el-radio :label="9">备选项</el-radio>
</el-radio-group>
`,
data() {
return {
radio: 3
};
}
}, true);
let radio2 = vm.$refs.radio2;
expect(vm.$el.querySelectorAll('label.is-disabled').length).to.be.equal(3);
expect(vm.$refs.radio1.$el.querySelector('.is-checked')).to.be.exist;
radio2.$el.click();
setTimeout(_ => {
expect(vm.radio === 3).to.be.true;
expect(vm.$refs.radio1.$el.querySelector('.is-checked')).to.be.exist;
done();
}, 10);
});
it('change event', done => {
vm = createVue({
template: `
<el-radio-group v-model="radio" @change="onChange">
<el-radio :label="3">备选项</el-radio>
<el-radio :label="6" ref="radio2">备选项</el-radio>
<el-radio :label="9">备选项</el-radio>
</el-radio-group>
`,
methods: {
onChange(val) {
this.data = val;
}
},
data() {
return {
radio: 3,
data: 0
};
}
}, true);
let radio2 = vm.$refs.radio2;
radio2.$el.click();
setTimeout(_ => {
expect(vm.data).to.equal(6);
done();
}, 10);
});
it('change event only triggers on user input', done => {
vm = createVue({
template: `
<el-radio-group v-model="radio" @change="onChange">
<el-radio :label="3">备选项</el-radio>
<el-radio :label="6">备选项</el-radio>
<el-radio :label="9">备选项</el-radio>
</el-radio-group>
`,
methods: {
onChange(val) {
this.data = val;
}
},
data() {
return {
radio: 3,
data: 0
};
}
}, true);
vm.radio = 6;
setTimeout(_ => {
expect(vm.data).to.equal(0);
done();
}, 10);
});
it('disabled when children is radio button', done => {
vm = createVue({
template: `
<el-radio-group v-model="radio" disabled>
<el-radio-button :label="3" ref="radio1">备选项</el-radio-button>
<el-radio-button :label="6" ref="radio2">备选项</el-radio-button>
<el-radio-button :label="9">备选项</el-radio-button>
</el-radio-group>
`,
data() {
return {
radio: 3
};
}
}, true);
let radio2 = vm.$refs.radio2;
expect(vm.$el.querySelectorAll('.is-disabled').length).to.be.equal(3);
expect(vm.$refs.radio1.$el.classList.contains('is-active')).to.be.true;
radio2.$el.click();
setTimeout(_ => {
expect(vm.radio === 3).to.be.true;
expect(vm.$refs.radio1.$el.classList.contains('is-active')).to.be.true;
done();
}, 10);
});
it('keyboard event', done => {
vm = createVue({
template: `
<el-radio-group v-model="radio">
<el-radio-button ref="radio1" :label="3">备选项</el-radio-button>
<el-radio-button ref="radio2" :label="6">备选项</el-radio-button>
<el-radio-button ref="radio3" :label="9">备选项</el-radio-button>
</el-radio-group>
`,
data() {
return {
radio: 6
};
}
}, true);
expect(vm.radio).to.be.equal(6);
vm.$nextTick(() => {
triggerKeyDown(vm.$refs.radio2.$el, 37);
expect(vm.radio).to.be.equal(3);
triggerKeyDown(vm.$refs.radio1.$el, 37);
expect(vm.radio).to.be.equal(9);
vm.$nextTick(() => {
triggerKeyDown(vm.$refs.radio3.$el, 39);
expect(vm.radio).to.be.equal(3);
triggerKeyDown(vm.$refs.radio1.$el, 39);
expect(vm.radio).to.be.equal(6);
vm.$nextTick(() => {
triggerKeyDown(vm.$refs.radio1.$el, 13);
expect(vm.radio).to.be.equal(6);
done();
});
});
});
});
describe('Radio Button', () => {
it('create', done => {
vm = createVue({
template: `
<el-radio-group v-model="radio">
<el-radio-button :label="3" ref="radio1">备选项</el-radio-button>
<el-radio-button :label="6" ref="radio2">备选项</el-radio-button>
<el-radio-button :label="9">备选项</el-radio-button>
</el-radio-group>
`,
data() {
return {
radio: 3
};
}
}, true);
expect(vm.$refs.radio1.$el.classList.contains('is-active')).to.be.true;
let radio = vm.$refs.radio2;
radio.$el.click();
setTimeout(_ => {
expect(radio.$el.classList.contains('is-active')).to.be.true;
expect(vm.radio === 6).to.be.true;
done();
}, 10);
});
it('custom color', done => {
vm = createVue({
template: `
<el-radio-group v-model="radio" fill="#000" text-color="#ff0">
<el-radio-button :label="3" ref="radio1">备选项</el-radio-button>
<el-radio-button :label="6" ref="radio2">备选项</el-radio-button>
<el-radio-button :label="9">备选项</el-radio-button>
</el-radio-group>
`,
data() {
return {
radio: 3
};
}
}, true);
setTimeout(_ => {
expect(vm.$refs.radio1.activeStyle.backgroundColor).to.equal('#000');
expect(vm.$refs.radio1.activeStyle.borderColor).to.equal('#000');
expect(vm.$refs.radio1.activeStyle.color).to.equal('#ff0');
done();
}, 10);
});
it('change event', done => {
vm = createVue({
template: `
<el-radio-group v-model="radio" @change="onChange">
<el-radio-button :label="3">备选项</el-radio-button>
<el-radio-button :label="6" ref="radio2">备选项</el-radio-button>
<el-radio-button :label="9">备选项</el-radio-button>
</el-radio-group>
`,
methods: {
onChange(val) {
this.data = val;
}
},
data() {
return {
data: 0,
radio: 3
};
}
}, true);
let radio = vm.$refs.radio2;
radio.$el.click();
setTimeout(_ => {
expect(vm.data).to.equal(6);
done();
}, 10);
});
it('change event only triggers on user input', done => {
vm = createVue({
template: `
<el-radio-group v-model="radio" @change="onChange">
<el-radio-button :label="3">备选项</el-radio-button>
<el-radio-button :label="6" ref="radio2">备选项</el-radio-button>
<el-radio-button :label="9">备选项</el-radio-button>
</el-radio-group>
`,
methods: {
onChange(val) {
this.data = val;
}
},
data() {
return {
data: 0,
radio: 3
};
}
}, true);
vm.radio = 6;
setTimeout(_ => {
expect(vm.data).to.equal(0);
done();
}, 10);
});
it('size', done => {
vm = createVue({
template: `
<el-radio-group v-model="radio" size="large">
<el-radio-button :label="3" ref="radio1">备选项</el-radio-button>
<el-radio-button :label="6" ref="radio2">备选项</el-radio-button>
<el-radio-button :label="9">备选项</el-radio-button>
</el-radio-group>
`,
data() {
return {
radio: 3
};
}
}, true);
setTimeout(_ => {
expect(vm.$el.querySelectorAll('.el-radio-button--large').length).to.be.equal(3);
done();
}, 10);
});
});
});
});

View File

@@ -0,0 +1,229 @@
import { createTest, createVue, destroyVM } from '../util';
import Rate from 'packages/rate';
import Vue from 'vue';
describe('Rate', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', () => {
vm = createTest(Rate, { max: 10 }, true);
const stars = vm.$el.querySelectorAll('.el-rate__item');
expect(stars.length).to.equal(10);
});
it('with texts', () => {
vm = createVue({
template: `
<div>
<el-rate
v-model="value"
show-text
:texts="['1', '2', '3', '4', '5']"></el-rate>
</div>
`,
data() {
return {
value: 4
};
}
}, true);
const text = vm.$el.querySelector('.el-rate__text');
expect(text.textContent).to.equal('4');
});
it('value change', done => {
vm = createVue({
template: `
<div>
<el-rate v-model="value"></el-rate>
</div>
`,
data() {
return {
value: 0
};
}
}, true);
const rate = vm.$children[0];
expect(rate.value).to.equal(0);
vm.value = 3;
Vue.nextTick(() => {
expect(rate.value).to.equal(3);
done();
});
});
it('click', () => {
vm = createVue({
template: `
<div>
<el-rate v-model="value"></el-rate>
</div>
`,
data() {
return {
value: 0
};
}
}, true);
const thirdStar = vm.$el.querySelectorAll('.el-rate__item')[2];
thirdStar.click();
expect(vm.value).to.equal(3);
});
it('colors', () => {
vm = createVue({
template: `
<div>
<el-rate v-model="value" :colors="['#99A9BF', '#F7BA2A', '#FF9900']"></el-rate>
</div>
`,
data() {
return {
value: 4
};
}
}, true);
const thirdIcon = vm.$el.querySelectorAll('.el-rate__item')[2].querySelector('.el-rate__icon');
expect(thirdIcon.style.color).to.equal('rgb(255, 153, 0)');
});
it('colors are updated after prop is changed', done => {
vm = createVue({
template: `
<div>
<el-rate v-model="value" :colors="colors"></el-rate>
</div>
`,
computed: {
colors() {
if (this.muted) {
return ['#999', '#999', '#999'];
} else {
return ['#99A9BF', '#F7BA2A', '#FF9900'];
}
}
},
data() {
return {
value: 4,
muted: false
};
}
}, true);
setTimeout(() => {
vm.muted = true;
vm.$nextTick(() => {
const thirdIcon = vm.$el.querySelectorAll('.el-rate__item')[2].querySelector('.el-rate__icon');
expect(thirdIcon.style.color).to.equal('rgb(153, 153, 153)');
done();
});
}, 10);
});
it('threshold', () => {
vm = createVue({
template: `
<div>
<el-rate v-model="value" :low-threshold="3"></el-rate>
</div>
`,
data() {
return {
value: 3
};
}
}, true);
const thirdIcon = vm.$el.querySelectorAll('.el-rate__item')[2].querySelector('.el-rate__icon');
expect(thirdIcon.style.color).to.equal('rgb(247, 186, 42)');
});
it('disabled', () => {
const vm1 = createVue({
template: `
<div>
<el-rate v-model="value" disabled show-text></el-rate>
</div>
`,
data() {
return {
value: 3.7
};
}
}, true);
const vm2 = createVue({
template: `
<div>
<el-rate v-model="value" disabled show-text></el-rate>
</div>
`,
data() {
return {
value: 3.4
};
}
}, true);
const firstStar = vm1.$el.querySelectorAll('.el-rate__item')[0];
firstStar.click();
vm1.$children[0].resetCurrentValue();
expect(vm1.value).to.equal(3.7);
const fourthStar = vm2.$el.querySelectorAll('.el-rate__item')[3];
const halfStar = fourthStar.querySelector('.el-rate__decimal');
expect(halfStar.style.width).to.equal('40%');
});
it('allow half', () => {
vm = createVue({
template: `
<div>
<el-rate v-model="value" allow-half></el-rate>
</div>
`,
data() {
return {
value: 0
};
}
}, true);
const rate = vm.$children[0];
const secondStar = vm.$el.querySelectorAll('.el-rate__item')[1];
rate.setCurrentValue(1, { target: secondStar, offsetX: 2 });
secondStar.click();
rate.resetCurrentValue();
expect(vm.value).to.equal(0.5);
});
it('custom icon classes by passing object', () => {
vm = createVue({
template: `
<div>
<el-rate
v-model="value"
:icon-classes="{ 2: 'icon-rate-face-1', 4: { value: 'icon-rate-face-2', excluded: true }, 5: 'icon-rate-face-3' }"></el-rate>
</div>
`,
data() {
return {
value: 4
};
}
}, true);
const thirdIcon = vm.$el.querySelectorAll('.el-rate__item')[3].querySelector('.el-rate__icon');
expect(thirdIcon.className).to.include('icon-rate-face-3');
});
});

View File

@@ -0,0 +1,44 @@
import { createTest, destroyVM } from '../util';
import Row from 'packages/row';
describe('Row', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', () => {
vm = createTest(Row, true);
let rowElm = vm.$el;
expect(rowElm.classList.contains('el-row')).to.be.true;
});
it('gutter', () => {
vm = createTest(Row, {
gutter: 20
}, true);
let rowElm = vm.$el;
expect(rowElm.style.marginLeft).to.be.equal('-10px');
expect(rowElm.style.marginRight).to.be.equal('-10px');
});
it('type', () => {
vm = createTest(Row, {
type: 'flex'
}, true);
let rowElm = vm.$el;
expect(rowElm.classList.contains('el-row--flex')).to.be.true;
});
it('justify', () => {
vm = createTest(Row, {
justify: 'end'
}, true);
let rowElm = vm.$el;
expect(rowElm.classList.contains('is-justify-end')).to.be.true;
});
it('align', () => {
vm = createTest(Row, {
align: 'bottom'
}, true);
let rowElm = vm.$el;
expect(rowElm.classList.contains('is-align-bottom')).to.be.true;
});
});

View File

@@ -0,0 +1,910 @@
import { createTest, createVue, triggerEvent, destroyVM, waitImmediate } from '../util';
import Select from 'packages/select';
describe('Select', () => {
const getSelectVm = (configs = {}, options) => {
['multiple', 'clearable', 'filterable', 'allowCreate', 'remote', 'collapseTags', 'automaticDropdown'].forEach(config => {
configs[config] = configs[config] || false;
});
configs.multipleLimit = configs.multipleLimit || 0;
if (!options) {
options = [{
value: '选项1',
label: '黄金糕',
disabled: false
}, {
value: '选项2',
label: '双皮奶',
disabled: false
}, {
value: '选项3',
label: '蚵仔煎',
disabled: false
}, {
value: '选项4',
label: '龙须面',
disabled: false
}, {
value: '选项5',
label: '北京烤鸭',
disabled: false
}];
}
const vm = createVue({
template: `
<div>
<el-select
ref="select"
v-model="value"
:multiple="multiple"
:multiple-limit="multipleLimit"
:popper-class="popperClass"
:clearable="clearable"
:filterable="filterable"
:collapse-tags="collapseTags"
:allow-create="allowCreate"
:filterMethod="filterMethod"
:remote="remote"
:loading="loading"
:remoteMethod="remoteMethod"
:automatic-dropdown="automaticDropdown">
<el-option
v-for="item in options"
:label="item.label"
:key="item.value"
:disabled="item.disabled"
:value="item.value">
</el-option>
</el-select>
</div>
`,
data() {
return {
options,
multiple: configs.multiple,
multipleLimit: configs.multipleLimit,
clearable: configs.clearable,
filterable: configs.filterable,
collapseTags: configs.collapseTags,
allowCreate: configs.allowCreate,
popperClass: configs.popperClass,
automaticDropdown: configs.automaticDropdown,
loading: false,
filterMethod: configs.filterMethod && configs.filterMethod(this),
remote: configs.remote,
remoteMethod: configs.remoteMethod && configs.remoteMethod(this),
value: configs.multiple ? [] : ''
};
}
}, true);
return vm;
};
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', () => {
vm = createTest(Select, true);
expect(vm.$el.className).to.equal('el-select');
expect(vm.$el.querySelector('.el-input__inner').placeholder).to.equal('请选择');
vm.toggleMenu();
expect(vm.visible).to.true;
});
it('options rendered correctly', () => {
vm = getSelectVm();
const options = vm.$el.querySelectorAll('.el-select-dropdown__item');
const result = [].every.call(options, (option, index) => {
let text = option.querySelector('span').textContent;
return text === vm.options[index].label;
});
expect(result).to.true;
});
it('custom dropdown class', () => {
vm = getSelectVm({ popperClass: 'custom-dropdown' });
const dropdown = vm.$el.querySelector('.el-select-dropdown');
expect(dropdown.classList.contains('custom-dropdown')).to.true;
});
it('default value', done => {
vm = createVue({
template: `
<div>
<el-select v-model="value">
<el-option
v-for="item in options"
:label="item.label"
:key="item.value"
:value="item.value">
</el-option>
</el-select>
</div>
`,
data() {
return {
options: [{
value: '选项1',
label: '黄金糕'
}, {
value: '选项2',
label: '双皮奶'
}],
value: '选项2'
};
}
}, true);
setTimeout(() => {
expect(vm.$el.querySelector('.el-input__inner').value).to.equal('双皮奶');
done();
}, 100);
});
it('single select', done => {
vm = createVue({
template: `
<div>
<el-select v-model="value" @change="handleChange">
<el-option
v-for="item in options"
:label="item.label"
:key="item.value"
:value="item.value">
<p>{{item.label}} {{item.value}}</p>
</el-option>
</el-select>
</div>
`,
data() {
return {
options: [{
value: '选项1',
label: '黄金糕'
}, {
value: '选项2',
label: '双皮奶'
}, {
value: '选项3',
label: '蚵仔煎'
}, {
value: '选项4',
label: '龙须面'
}, {
value: '选项5',
label: '北京烤鸭'
}],
value: '',
count: 0
};
},
methods: {
handleChange() {
this.count++;
}
}
}, true);
const options = vm.$el.querySelectorAll('.el-select-dropdown__item');
expect(vm.value).to.equal('');
triggerEvent(options[2], 'mouseenter');
options[2].click();
setTimeout(() => {
expect(vm.value).to.equal('选项3');
expect(vm.count).to.equal(1);
triggerEvent(options[2], 'mouseenter');
options[4].click();
setTimeout(() => {
expect(vm.value).to.equal('选项5');
expect(vm.count).to.equal(2);
done();
}, 100);
}, 100);
});
it('disabled option', done => {
vm = getSelectVm();
vm.options[1].disabled = true;
setTimeout(() => {
const options = vm.$el.querySelectorAll('.el-select-dropdown__item');
expect(options[1].classList.contains('is-disabled')).to.true;
options[1].click();
setTimeout(() => {
expect(vm.value).to.equal('');
done();
}, 100);
}, 100);
});
it('disabled select', () => {
vm = createTest(Select, { disabled: true }, true);
expect(vm.$el.querySelector('.el-input').classList.contains('is-disabled')).to.true;
});
it('visible event', done => {
vm = createVue({
template: `
<div>
<el-select v-model="value" @visible-change="handleVisibleChange">
<el-option
v-for="item in options"
:label="item.label"
:key="item.value"
:value="item.value">
</el-option>
</el-select>
</div>
`,
data() {
return {
options: [],
value: '',
visible: ''
};
},
methods: {
handleVisibleChange(val) {
this.visible = val;
}
}
}, true);
vm.$children[0].visible = true;
setTimeout(() => {
expect(vm.visible).to.true;
done();
}, 50);
});
it('keyboard operations', done => {
vm = getSelectVm();
const select = vm.$children[0];
let i = 8;
while (i--) {
select.navigateOptions('next');
}
select.navigateOptions('prev');
setTimeout(() => {
expect(select.hoverIndex).to.equal(0);
select.selectOption();
setTimeout(() => {
expect(select.value).to.equal('选项1');
done();
}, 100);
}, 100);
});
it('clearable', done => {
vm = getSelectVm({ clearable: true });
const select = vm.$children[0];
vm.value = '选项1';
select.inputHovering = true;
setTimeout(() => {
const iconClear = vm.$el.querySelector('.el-input__icon.el-icon-circle-close');
expect(iconClear).to.exist;
iconClear.click();
expect(vm.value).to.equal('');
done();
}, 100);
});
it('object typed value', done => {
vm = createVue({
template: `
<div>
<el-select v-model="value" value-key="id">
<el-option
v-for="item in options"
:label="item.label"
:key="item.id"
:value="item">
</el-option>
</el-select>
</div>
`,
data() {
return {
options: [{
id: 1,
label: 'label1'
}, {
id: 2,
label: 'label2'
}],
value: {
id: 1,
label: 'label1'
}
};
}
}, true);
setTimeout(() => {
expect(vm.$el.querySelector('.el-input__inner').value).to.equal('label1');
expect(vm.$el.querySelector('.el-select-dropdown__item').classList.contains('selected'));
done();
}, 100);
});
it('prefixed icon', () => {
vm = createTest({
template: `
<div>
<el-select v-model="value">
<el-option
v-for="item in options"
:label="item.label"
:key="item.value"
:value="item.value">
</el-option>
<i slot="prefix" class="el-input__icon el-icon-search"></i>
</el-select>
</div>
`,
data() {
return {
options: [],
value: ''
};
}
});
expect(vm.$el.querySelector('.el-input__icon').classList.contains('el-icon-search')).to.be.true;
});
it('custom el-option template', () => {
vm = createVue({
template: `
<div>
<el-select v-model="value">
<el-option
v-for="item in options"
:label="item.label"
:key="item.value"
:value="item.value">
<p>{{item.label}} {{item.value}}</p>
</el-option>
</el-select>
</div>
`,
data() {
return {
options: [{
value: 'value',
label: 'label'
}],
value: ''
};
}
}, true);
expect(vm.$el.querySelector('.el-select-dropdown__item p').textContent).to.equal('label value');
});
it('option group', () => {
vm = createVue({
template: `
<div>
<el-select v-model="value">
<el-option-group
v-for="group in options"
:key="group.label"
:disabled="group.disabled"
:label="group.label">
<el-option
v-for="item in group.options"
:label="item.label"
:key="item.value"
:value="item.value">
</el-option>
</el-option-group>
</el-select>
</div>
`,
data() {
return {
options: [{
label: '热门城市',
options: [{
value: 'Shanghai',
label: '上海'
}, {
value: 'Beijing',
label: '北京'
}]
}, {
label: '城市名',
disabled: true,
options: [{
value: 'Chengdu',
label: '成都'
}, {
value: 'Shenzhen',
label: '深圳'
}, {
value: 'Guangzhou',
label: '广州'
}, {
value: 'Dalian',
label: '大连'
}]
}],
value: ''
};
}
}, true);
const groups = vm.$el.querySelectorAll('.el-select-group__wrap');
const options = groups[1].querySelectorAll('.el-select-dropdown__item');
expect(groups.length).to.equal(2);
expect(options.length).to.equal(4);
expect(options[0].querySelector('span').textContent).to.equal('成都');
});
it('filterable', done => {
vm = getSelectVm({ filterable: true });
const select = vm.$children[0];
setTimeout(() => {
select.selectedLabel = '面';
select.onInputChange();
select.visible = true;
setTimeout(() => {
expect(select.filteredOptionsCount).to.equal(1);
done();
}, 10);
}, 10);
});
it('filterable with custom filter-method', done => {
const filterMethod = vm => {
return query => {
vm.options = vm.options.filter(option => option.label.indexOf(query) === -1);
};
};
vm = getSelectVm({ filterable: true, filterMethod });
const select = vm.$children[0];
select.$el.click();
setTimeout(() => {
select.selectedLabel = '面';
select.onInputChange();
setTimeout(() => {
expect(select.filteredOptionsCount).to.equal(4);
done();
}, 10);
}, 10);
});
it('default-first-option', done => {
vm = createVue({
template: `
<div>
<el-select
v-model="value"
default-first-option
filterable
>
<el-option
v-for="item in options"
:label="item"
:key="item"
:value="item"
/>
</el-select>
</div>
`,
data() {
return {
options: ['1', '2', '3', '4', '5'],
value: ''
};
}
}, true);
const select = vm.$children[0];
setTimeout(() => {
select.$el.click();
select.query = '3';
select.handleQueryChange('3');
select.selectOption();
setTimeout(() => {
expect(select.value).to.equal('3');
done();
}, 10);
}, 10);
});
it('allow create', done => {
vm = getSelectVm({ filterable: true, allowCreate: true });
const select = vm.$children[0];
select.$el.querySelector('input').focus();
setTimeout(() => {
select.selectedLabel = 'new';
select.onInputChange();
setTimeout(() => {
const options = document.querySelectorAll('.el-select-dropdown__item span');
const target = [].filter.call(options, option => option.innerText === 'new');
target[0].click();
setTimeout(() => {
expect(select.value.indexOf('new') > -1).to.true;
done();
}, 10);
}, 10);
}, 10);
});
it('multiple select', done => {
vm = getSelectVm({ multiple: true });
const options = vm.$el.querySelectorAll('.el-select-dropdown__item');
vm.value = ['选项1'];
setTimeout(() => {
options[1].click();
setTimeout(() => {
options[3].click();
setTimeout(() => {
expect(vm.value.indexOf('选项2') > -1 && vm.value.indexOf('选项4') > -1).to.true;
const tagCloseIcons = vm.$el.querySelectorAll('.el-tag__close');
tagCloseIcons[0].click();
setTimeout(() => {
expect(vm.value.indexOf('选项1')).to.equal(-1);
done();
}, 100);
}, 100);
}, 100);
}, 100);
});
it('multiple remove-tag', done => {
sinon.stub(window.console, 'log');
vm = createVue({
template: `
<div>
<el-select v-model="value" multiple @remove-tag="handleRemoveTag">
<el-option
v-for="item in options"
:label="item.label"
:key="item.value"
:value="item.value">
<p>{{item.label}} {{item.value}}</p>
</el-option>
</el-select>
</div>
`,
data() {
return {
options: [{
value: '选项1',
label: '黄金糕'
}, {
value: '选项2',
label: '双皮奶'
}, {
value: '选项3',
label: '蚵仔煎'
}, {
value: '选项4',
label: '龙须面'
}, {
value: '选项5',
label: '北京烤鸭'
}],
value: ['选项1', '选项3']
};
},
methods: {
handleRemoveTag() {
console.log('remove tag');
}
}
}, true);
expect(vm.value.length).to.equal(2);
setTimeout(() => {
const tagCloseIcons = vm.$el.querySelectorAll('.el-tag__close');
tagCloseIcons[1].click();
setTimeout(() => {
expect(vm.value.length).to.equal(1);
expect(window.console.log.callCount).to.equal(1);
tagCloseIcons[0].click();
setTimeout(() => {
expect(vm.value.length).to.equal(0);
expect(window.console.log.callCount).to.equal(2);
window.console.log.restore();
done();
}, 50);
}, 50);
}, 50);
});
it('multiple limit', done => {
vm = getSelectVm({ multiple: true, multipleLimit: 1 });
const options = vm.$el.querySelectorAll('.el-select-dropdown__item');
options[1].click();
setTimeout(() => {
expect(vm.value.indexOf('选项2') > -1).to.true;
options[3].click();
setTimeout(() => {
expect(vm.value.indexOf('选项4')).to.equal(-1);
done();
}, 50);
}, 50);
});
it('multiple remote search', done => {
const remoteMethod = vm => {
return query => {
vm.loading = true;
setTimeout(() => {
vm.options = vm.options.filter(option => {
return option.label.indexOf(query) > -1;
});
vm.loading = false;
}, 200);
};
};
vm = getSelectVm({
multiple: true,
remote: true,
filterable: true,
remoteMethod
});
const select = vm.$children[0];
select.handleQueryChange('');
vm.$nextTick(() => {
select.handleQueryChange('面');
setTimeout(() => {
expect(select.filteredOptionsCount).to.equal(1);
select.options[0].$el.click();
vm.$nextTick(() => {
expect(vm.value[0]).to.equal('选项4');
select.deletePrevTag({ target: select.$refs.input });
select.deletePrevTag({ target: select.$refs.input });
select.resetInputState({ keyCode: 1 });
vm.$nextTick(() => {
expect(vm.value.length).to.equal(0);
done();
});
});
}, 250);
});
});
it('event:focus & blur', done => {
vm = createVue({
template: `
<el-select ref="select"></el-select>
`
}, true);
const spyFocus = sinon.spy();
const spyBlur = sinon.spy();
vm.$refs.select.$on('focus', spyFocus);
vm.$refs.select.$on('blur', spyBlur);
vm.$el.querySelector('input').focus();
vm.$el.querySelector('input').blur();
setTimeout(_ => {
expect(spyFocus.calledOnce).to.be.true;
expect(spyBlur.calledOnce).to.be.true;
done();
}, 250);
});
it('should return focus to input inside select after option select', done => {
vm = createVue({
template: `
<div>
<el-select v-model="value" ref="select">
<el-option label="1" :value="1" />
</el-select>
</div>
`,
data() {
return {
value: ''
};
}
}, true);
const spyInputFocus = sinon.spy();
const spySelectFocus = sinon.spy();
vm.$refs.select.$on('focus', spySelectFocus);
vm.$refs.select.$refs.reference.$on('focus', spyInputFocus);
const option = vm.$el.querySelectorAll('.el-select-dropdown__item')[0];
triggerEvent(option, 'mouseenter');
option.click();
vm.$nextTick(_ => {
expect(spyInputFocus.calledOnce).to.be.true;
expect(spySelectFocus.calledOnce).not.to.be.true;
done();
});
});
it('should not open popper when automatic-dropdown not set', done => {
vm = getSelectVm();
vm.$refs.select.$refs.reference.$refs.input.focus();
vm.$nextTick(_ => {
expect(vm.$refs.select.visible).to.be.false;
done();
});
});
it('should open popper when automatic-dropdown is set', done => {
vm = getSelectVm({ automaticDropdown: true });
vm.$refs.select.$refs.reference.$refs.input.focus();
vm.$nextTick(_ => {
expect(vm.$refs.select.visible).to.be.true;
done();
});
});
it('focus', done => {
vm = createVue({
template: `
<el-select ref="select"></el-select>
`
}, true);
const spy = sinon.spy();
vm.$refs.select.$on('focus', spy);
vm.$refs.select.focus();
vm.$nextTick(_ => {
expect(spy.calledOnce).to.be.true;
done();
});
});
it('only emit change on user input', done => {
let callCount = 0;
vm = createVue({
template: `
<div>
<el-select v-model="value" @change="change" ref="select">
<el-option label="1" :value="1" />
<el-option label="2" :value="2" />
<el-option label="3" :value="3" />
</el-select>
</div>
`,
data() {
return {
value: 1,
change: () => ++callCount
};
}
});
vm.value = 2;
setTimeout(() => {
expect(callCount).to.equal(0);
const options = vm.$el.querySelectorAll('.el-select-dropdown__item');
triggerEvent(options[2], 'mouseenter');
options[2].click();
setTimeout(() => {
expect(callCount).to.equal(1);
done();
}, 10);
}, 10);
});
it('render slot `empty`', done => {
vm = createVue({
template: `
<div>
<el-select v-model="value">
<div class="empty-slot" slot="empty">EmptySlot</div>
</el-select>
</div>
`,
data() {
return {
value: 1
};
}
});
expect(vm.$el.querySelector('.empty-slot').innerText).to.be.equal('EmptySlot');
done();
});
it('should set placeholder to label of selected option when filterable is true and multiple is false', async() => {
vm = createVue({
template: `
<div>
<el-select ref="select" v-model="value" filterable>
<el-option label="test" value="test" />
</el-select>
</div>
`,
data() {
return {
value: 'test'
};
}
});
vm.$refs.select.$el.click();
await waitImmediate();
expect(vm.$refs.select.visible).to.be.equal(true);
expect(vm.$el.querySelector('.el-input__inner').placeholder).to.be.equal('test');
expect(vm.value).to.be.equal('test');
});
it('default value is null or undefined', async() => {
vm = createVue({
template: `
<div>
<el-select v-model="value">
<el-option
v-for="item in options"
:label="item.label"
:key="item.value"
:value="item.value">
</el-option>
</el-select>
</div>
`,
data() {
return {
options: [{
value: '选项1',
label: '黄金糕'
}, {
value: '选项2',
label: '双皮奶'
}],
value: undefined
};
}
}, true);
vm.value = null;
await waitImmediate();
expect(vm.$el.querySelector('.el-input__inner').value).to.equal('');
vm.value = '选项1';
await waitImmediate();
expect(vm.$el.querySelector('.el-input__inner').value).to.equal('黄金糕');
});
describe('resetInputHeight', () => {
const getSelectComponentVm = (configs) => {
vm = getSelectVm(configs || {});
return vm.$refs.select;
};
it('should reset height if collapse-tags option is disabled', () => {
const select = getSelectComponentVm();
sinon.stub(select, '$nextTick');
select.resetInputHeight();
expect(select.$nextTick.callCount).to.equal(1);
});
it('should not reset height if collapse-tags option is enabled', () => {
const select = getSelectComponentVm({ collapseTags: true });
sinon.stub(select, '$nextTick');
select.resetInputHeight();
expect(select.$nextTick.callCount).to.equal(0);
});
it('should reset height if both collapse-tags and filterable are enabled', () => {
const select = getSelectComponentVm({ collapseTags: true, filterable: true });
sinon.stub(select, '$nextTick');
select.resetInputHeight();
expect(select.$nextTick.callCount).to.equal(1);
});
});
});

View File

@@ -0,0 +1,501 @@
import { createTest, createVue, triggerEvent, destroyVM, waitImmediate } from '../util';
import Slider from 'packages/slider';
describe('Slider', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', () => {
vm = createTest(Slider);
expect(vm.value).to.equal(0);
});
it('should not exceed min and max', done => {
vm = createVue({
template: `
<div>
<el-slider v-model="value" :min="50">
</el-slider>
</div>
`,
data() {
return {
value: 50
};
}
}, true);
setTimeout(() => {
vm.value = 40;
vm.$nextTick(() => {
expect(vm.value).to.equal(50);
vm.value = 120;
vm.$nextTick(() => {
expect(vm.value).to.equal(100);
done();
});
});
}, 10);
});
it('show tooltip', () => {
vm = createVue({
template: `
<div>
<el-slider v-model="value">
</el-slider>
</div>
`,
data() {
return {
value: 0
};
}
}, true);
const slider = vm.$children[0].$children[0];
slider.handleMouseEnter();
expect(slider.$refs.tooltip.showPopper).to.true;
slider.handleMouseLeave();
expect(slider.$refs.tooltip.showPopper).to.false;
});
it('hide tooltip', () => {
vm = createVue({
template: `
<div>
<el-slider v-model="value" :show-tooltip="false">
</el-slider>
</div>
`,
data() {
return {
value: 0
};
}
}, true);
const slider = vm.$children[0].$children[0];
expect(slider.$refs.tooltip.disabled).to.true;
});
it('format tooltip', async() => {
vm = createVue({
template: `
<div>
<el-slider ref="slider" v-model="value" :format-tooltip="formatTooltip">
</el-slider>
</div>
`,
data() {
return {
value: 0
};
},
methods: {
formatTooltip(val) {
return '$' + val;
}
}
}, true);
const sliderButton = vm.$refs.slider.$children[0];
await waitImmediate();
expect(sliderButton.formatValue).to.equal('$0');
});
it('drag', done => {
vm = createVue({
template: `
<div>
<el-slider v-model="value" :vertical="vertical"></el-slider>
</div>
`,
data() {
return {
vertical: false,
value: 0
};
}
}, true);
const slider = vm.$children[0].$children[0];
slider.onButtonDown({ clientX: 0, preventDefault() {} });
slider.onDragging({ clientX: 100 });
slider.onDragEnd();
setTimeout(() => {
expect(vm.value > 0).to.true;
vm.vertical = true;
vm.value = 0;
vm.$nextTick(() => {
expect(vm.value === 0).to.true;
slider.onButtonDown({ clientY: 0, preventDefault() {} });
slider.onDragging({ clientY: -100 });
slider.onDragEnd();
setTimeout(() => {
expect(vm.value > 0).to.true;
done();
}, 10);
});
}, 10);
});
it('accessibility', done => {
vm = createVue({
template: `
<div>
<el-slider v-model="value"></el-slider>
</div>
`,
data() {
return {
value: 0.1
};
}
}, true);
const slider = vm.$children[0].$children[0];
slider.onRightKeyDown();
setTimeout(() => {
expect(vm.value).to.equal(1);
slider.onLeftKeyDown();
setTimeout(() => {
expect(vm.value).to.equal(0);
done();
}, 10);
}, 10);
});
it('step', done => {
vm = createVue({
template: `
<div style="width: 200px;">
<el-slider v-model="value" :min="0" :max="1" :step="0.1"></el-slider>
</div>
`,
data() {
return {
value: 0
};
}
}, true);
const slider = vm.$children[0].$children[0];
slider.onButtonDown({ clientX: 0, preventDefault() {} });
slider.onDragging({ clientX: 100 });
slider.onDragEnd();
setTimeout(() => {
expect(vm.value > 0.4 && vm.value < 0.6).to.true;
done();
}, 10);
});
it('click', done => {
vm = createVue({
template: `
<div>
<el-slider v-model="value"></el-slider>
</div>
`,
data() {
return {
value: 0
};
}
}, true);
const slider = vm.$children[0];
setTimeout(() => {
slider.onSliderClick({ clientX: 100 });
setTimeout(() => {
expect(vm.value > 0).to.true;
done();
}, 10);
}, 10);
});
it('change event', done => {
vm = createVue({
template: `
<div>
<el-slider v-model="value" @change="onChange">
</el-slider>
</div>
`,
data() {
return {
data: 0,
value: 0
};
},
methods: {
onChange(val) {
this.data = val;
}
}
}, true);
const slider = vm.$children[0];
vm.value = 10;
setTimeout(() => {
expect(vm.data).to.equal(0);
slider.onSliderClick({ clientX: 100 });
setTimeout(() => {
expect(vm.data > 0).to.true;
done();
}, 10);
}, 10);
});
it('disabled', done => {
vm = createVue({
template: `
<div>
<el-slider v-model="value" disabled></el-slider>
</div>
`,
data() {
return {
value: 0
};
}
}, true);
const slider = vm.$children[0].$children[0];
slider.onButtonDown({ clientX: 0 });
slider.onDragging({ clientX: 100 });
slider.onDragEnd();
setTimeout(() => {
expect(vm.value).to.equal(0);
done();
}, 10);
});
it('show input', done => {
vm = createVue({
template: `
<div>
<el-slider v-model="value" show-input></el-slider>
</div>
`,
data() {
return {
value: 0
};
}
}, true);
setTimeout(() => {
triggerEvent(vm.$el.querySelector('.el-input-number'), 'keyup');
const inputNumber = vm.$el.querySelector('.el-input-number').__vue__;
inputNumber.setCurrentValue(40);
setTimeout(() => {
expect(vm.value).to.equal(40);
done();
}, 10);
}, 10);
});
it('show stops', () => {
vm = createTest(Slider, {
showStops: true,
step: 10
}, true);
const stops = vm.$el.querySelectorAll('.el-slider__stop');
expect(stops.length).to.equal(9);
});
it('vertical mode', done => {
vm = createVue({
template: `
<div>
<el-slider vertical v-model="value" height="200px"></el-slider>
</div>
`,
data() {
return {
value: 0
};
}
}, true);
const slider = vm.$children[0];
setTimeout(() => {
slider.onSliderClick({ clientY: 100 });
setTimeout(() => {
expect(vm.value > 0).to.true;
done();
}, 10);
}, 10);
});
describe('range', () => {
it('basic ranged slider', () => {
vm = createVue({
template: `
<div>
<el-slider v-model="value" range></el-slider>
</div>
`,
data() {
return {
value: [10, 20]
};
}
}, true);
const buttons = vm.$children[0].$children;
expect(buttons.length).to.equal(2);
});
it('should not exceed min and max', done => {
vm = createVue({
template: `
<div>
<el-slider v-model="value" range :min="50">
</el-slider>
</div>
`,
data() {
return {
value: [50, 60]
};
}
}, true);
setTimeout(() => {
vm.value = [40, 60];
setTimeout(() => {
expect(vm.value).to.deep.equal([50, 60]);
vm.value = [50, 120];
setTimeout(() => {
expect(vm.value).to.deep.equal([50, 100]);
done();
}, 10);
}, 10);
}, 10);
});
it('click', done => {
vm = createVue({
template: `
<div style="width: 200px;">
<el-slider range v-model="value"></el-slider>
</div>
`,
data() {
return {
value: [0, 100]
};
}
}, true);
const slider = vm.$children[0];
setTimeout(() => {
slider.onSliderClick({ clientX: 100 });
setTimeout(() => {
expect(vm.value[0] > 0).to.true;
expect(vm.value[1]).to.equal(100);
done();
}, 10);
}, 10);
});
it('responsive to dynamic min and max', done => {
vm = createVue({
template: `
<div>
<el-slider v-model="value" range :min="min" :max="max">
</el-slider>
</div>
`,
data() {
return {
min: 0,
max: 100,
value: [50, 80]
};
}
}, true);
setTimeout(() => {
vm.min = 60;
setTimeout(() => {
expect(vm.value).to.deep.equal([60, 80]);
vm.min = 30;
vm.max = 40;
setTimeout(() => {
expect(vm.value).to.deep.equal([40, 40]);
done();
}, 10);
}, 10);
}, 10);
});
it('show stops', done => {
vm = createVue({
template: `
<div>
<el-slider
v-model="value"
range
:step="10"
show-stops></el-slider>
</div>
`,
data() {
return {
value: [30, 60]
};
}
}, true);
setTimeout(() => {
const stops = vm.$el.querySelectorAll('.el-slider__stop');
expect(stops.length).to.equal(5);
done();
}, 10);
});
it('marks', async() => {
vm = createVue({
template: `
<div>
<el-slider
v-model="value"
range
:step="10"
:marks="marks"
:min="20"
show-stops></el-slider>
</div>
`,
data() {
return {
value: [30, 60],
marks: {
0: '0°C',
8: '8°C',
37: '37°C',
50: {
style: {
color: '#f50'
},
label: <strong>50°C</strong>
}
}
};
}
}, true);
waitImmediate();
const stops = vm.$el.querySelectorAll('.el-slider__marks-stop.el-slider__stop');
const marks = vm.$el.querySelectorAll('.el-slider__marks .el-slider__marks-text');
expect(marks.length).to.equal(2);
expect(stops.length).to.equal(2);
});
});
});

View File

@@ -0,0 +1,163 @@
import { createVue, destroyVM, waitImmediate } from '../util';
describe('Steps', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', () => {
vm = createVue(`
<el-steps>
<el-step title="step1"></el-step>
<el-step title="step2"></el-step>
<el-step title="step3"></el-step>
</el-steps>
`);
expect(vm.$el.querySelectorAll('.el-step')).to.length(3);
});
it('space', async() => {
vm = createVue(`
<el-steps>
<el-step title="step1"></el-step>
<el-step title="step2"></el-step>
<el-step title="step3"></el-step>
</el-steps>
`, true);
const vm2 = createVue(`
<el-steps :space="100">
<el-step title="step1"></el-step>
<el-step title="step2"></el-step>
<el-step title="step3"></el-step>
<el-step title="step4"></el-step>
</el-steps>
`, true);
await waitImmediate();
const stepElm = vm.$el.querySelector('.el-step');
const stepElm2 = vm2.$el.querySelector('.el-step');
expect(getComputedStyle(stepElm).flexBasis).to.equal('50%');
expect(getComputedStyle(stepElm2).flexBasis).to.equal('100px');
});
it('processStatus', done => {
vm = createVue(`
<el-steps :active="1" process-status="error">
<el-step title="step1"></el-step>
<el-step title="step2"></el-step>
<el-step title="step3"></el-step>
</el-steps>
`);
vm.$nextTick(_ => {
expect(vm.$el.querySelectorAll('.el-step__head.is-error')).to.length(1);
done();
});
});
it('update processStatus', done => {
vm = createVue({
template: `
<el-steps :active="1" :process-status="processStatus">
<el-step title="abc"></el-step>
<el-step title="abc2"></el-step>
</el-steps>
`,
data() {
return { processStatus: 'error' };
}
});
vm.$nextTick(_ => {
expect(vm.$el.querySelectorAll('.el-step__head.is-error')).to.length(1);
vm.processStatus = 'process';
vm.$nextTick(_ => {
expect(vm.$el.querySelectorAll('.el-step__head.is-process')).to.length(1);
done();
});
});
});
it('finishStatus', done => {
vm = createVue(`
<el-steps :active="1" finish-status="error">
<el-step title="abc"></el-step>
<el-step title="abc2"></el-step>
</el-steps>
`);
vm.$nextTick(_ => {
expect(vm.$el.querySelectorAll('.el-step__head.is-error')).to.length(1);
done();
});
});
it('active', done => {
vm = createVue({
template: `
<el-steps :active="active" finish-status="error">
<el-step title="abc"></el-step>
<el-step title="abc2"></el-step>
</el-steps>
`,
data() {
return { active: 0 };
}
});
vm.$nextTick(_ => {
expect(vm.$el.querySelectorAll('.el-step__head.is-error')).to.length(0);
vm.active = 2;
vm.$nextTick(_ => {
expect(vm.$el.querySelectorAll('.el-step__head.is-error')).to.length(2);
done();
});
});
});
it('create vertical', () => {
vm = createVue(`
<el-steps direction="vertical">
<el-step title="aaa"></el-step>
<el-step title="bbb"></el-step>
</el-steps>
`);
expect(vm.$el.querySelector('.is-vertical')).to.exist;
});
it('vertical:height', async() => {
vm = createVue(`
<el-steps direction="vertical" :space="200">
<el-step title="aaa"></el-step>
<el-step title="bbb"></el-step>
</el-steps>
`, true);
await waitImmediate();
const stepElm = vm.$el.querySelector('.el-step');
expect(getComputedStyle(stepElm).flexBasis).to.equal('200px');
});
it('step:status=error', done => {
vm = createVue(`
<el-steps :active="2" process-status="process" finish-status="success" direction="horizontal">
<el-step title="step1"></el-step>
<el-step title="step2" status="error"></el-step>
<el-step title="step3"></el-step>
</el-steps>
`);
vm.$nextTick(_ => {
const errorLine = vm.$el.querySelector('.el-step:nth-child(2) .el-step__line-inner');
expect(errorLine.getBoundingClientRect().width).to.equal(0);
const nextStep = vm.$el.querySelector('.el-step:nth-child(3) .el-step__head');
expect(nextStep.classList.contains('is-wait')).to.equal(true);
done();
});
});
});

View File

@@ -0,0 +1,209 @@
import { createTest, createVue, destroyVM } from '../util';
import Switch from 'packages/switch';
import Vue from 'vue';
describe('Switch', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', () => {
vm = createTest(Switch, {
activeText: 'on',
inactiveText: 'off',
activeColor: '#0f0',
inactiveColor: '#f00',
width: 100
});
const core = vm.$el.querySelector('.el-switch__core');
expect(core.style.backgroundColor).to.equal('rgb(255, 0, 0)');
expect(core.style.width).to.equal('100px');
expect(vm.$el.querySelector('.el-switch__label--left').querySelector('span').textContent).to.equal('off');
});
it('switch with icons', () => {
vm = createTest(Switch, {
activeIconClass: 'el-icon-check',
inactiveIconClass: 'el-icon-close'
});
const icon = vm.$el.querySelector('.el-switch__label--left').querySelector('i');
expect(icon.classList.contains('el-icon-close')).to.true;
});
it('value correctly update', done => {
vm = createVue({
template: `
<div>
<el-switch
v-model="value"
activeColor="#0f0"
inactiveColor="#f00">
</el-switch>
</div>
`,
data() {
return {
value: true
};
}
}, true);
const core = vm.$el.querySelector('.el-switch__core');
expect(core.style.backgroundColor).to.equal('rgb(0, 255, 0)');
core.click();
setTimeout(() => {
expect(core.style.backgroundColor).to.equal('rgb(255, 0, 0)');
expect(vm.value).to.equal(false);
core.click();
setTimeout(() => {
expect(vm.value).to.equal(true);
done();
}, 10);
}, 10);
});
it('change event', done => {
vm = createVue({
template: `
<div>
<el-switch
v-model="value"
@change="handleChange">
</el-switch>
</div>
`,
mounted() {
setTimeout(() => {
this.value = false;
}, 10);
},
methods: {
handleChange(val) {
this.target = val;
}
},
data() {
return {
target: 1,
value: true
};
}
}, true);
setTimeout(() => {
const core = vm.$el.querySelector('.el-switch__core');
expect(vm.target).to.equal(1);
core.click();
setTimeout(() => {
expect(vm.target).to.equal(true);
done();
}, 10);
}, 50);
});
it('disabled switch should not respond to user click', done => {
vm = createVue({
template: `
<div>
<el-switch disabled v-model="value"></el-switch>
</div>
`,
data() {
return {
value: true
};
}
}, true);
vm.$el.querySelector('.el-switch__core').click();
Vue.nextTick(() => {
expect(vm.value).to.true;
done();
});
});
it('expand switch value', done => {
vm = createVue({
template: `
<div>
<el-switch v-model="value" :active-value="onValue" :inactive-value="offValue"></el-switch>
</div>
`,
data() {
return {
value: '100',
onValue: '100',
offValue: '0'
};
}
}, true);
const core = vm.$el.querySelector('.el-switch__core');
core.click();
setTimeout(() => {
expect(vm.value).to.equal('0');
core.click();
setTimeout(() => {
expect(vm.value).to.equal('100');
done();
}, 10);
}, 10);
});
it('value is the single source of truth', done => {
vm = createVue({
template: `
<div>
<el-switch :value="true"></el-switch>
</div>
`
}, true);
const component = vm.$children[0];
const input = vm.$el.querySelector('input');
const core = vm.$el.querySelector('.el-switch__core');
core.click();
setTimeout(() => {
expect(component.checked).to.equal(true);
expect(component.$el.classList.contains('is-checked')).to.equal(true);
expect(input.checked).to.equal(true);
core.click();
setTimeout(() => {
expect(component.checked).to.equal(true);
expect(component.$el.classList.contains('is-checked')).to.equal(true);
expect(input.checked).to.equal(true);
done();
}, 10);
}, 10);
});
it('sets checkbox value', done => {
vm = createVue({
template: `
<div>
<el-switch v-model="value"></el-switch>
</div>
`,
data() {
return {
value: false
};
}
}, true);
vm.value = true;
setTimeout(() => {
expect(vm.$el.querySelector('input').checked).to.equal(true);
vm.value = false;
setTimeout(() => {
expect(vm.$el.querySelector('input').checked).to.equal(false);
done();
}, 10);
}, 10);
});
});

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,609 @@
import { createVue, destroyVM, triggerKeyDown } from '../util';
describe('Tabs', () => {
let vm;
let hasPromise = true;
before(() => {
if (!window.Promise) {
hasPromise = false;
window.Promise = require('es6-promise').Promise;
}
});
after(() => {
if (!hasPromise) {
window.Promise = undefined;
}
});
afterEach(() => {
destroyVM(vm);
});
it('create', done => {
vm = createVue({
template: `
<el-tabs ref="tabs">
<el-tab-pane label="用户管理">A</el-tab-pane>
<el-tab-pane label="配置管理">B</el-tab-pane>
<el-tab-pane label="角色管理" ref="pane-click">C</el-tab-pane>
<el-tab-pane label="定时任务补偿">D</el-tab-pane>
</el-tabs>
`
}, true);
let paneList = vm.$el.querySelector('.el-tabs__content').children;
let spy = sinon.spy();
vm.$refs.tabs.$on('tab-click', spy);
setTimeout(_ => {
const tabList = vm.$refs.tabs.$refs.nav.$refs.tabs;
expect(tabList[0].classList.contains('is-active')).to.be.true;
expect(paneList[0].style.display).to.not.ok;
tabList[2].click();
vm.$nextTick(_ => {
expect(spy.withArgs(vm.$refs['pane-click']).calledOnce).to.true;
expect(tabList[2].classList.contains('is-active')).to.be.true;
expect(paneList[2].style.display).to.not.ok;
done();
});
}, 100);
});
it('active-name', done => {
vm = createVue({
template: `
<el-tabs ref="tabs" :active-name="activeName" @click="handleClick">
<el-tab-pane name="tab-A" label="用户管理">A</el-tab-pane>
<el-tab-pane name="tab-B" label="配置管理">B</el-tab-pane>
<el-tab-pane name="tab-C" label="角色管理">C</el-tab-pane>
<el-tab-pane name="tab-D" label="定时任务补偿">D</el-tab-pane>
</el-tabs>
`,
data() {
return {
activeName: 'tab-B'
};
},
methods: {
handleClick(tab) {
this.activeName = tab.name;
}
}
}, true);
setTimeout(_ => {
const paneList = vm.$el.querySelector('.el-tabs__content').children;
const tabList = vm.$refs.tabs.$refs.nav.$refs.tabs;
expect(tabList[1].classList.contains('is-active')).to.be.true;
expect(paneList[1].style.display).to.not.ok;
tabList[3].click();
vm.$nextTick(_ => {
expect(tabList[3].classList.contains('is-active')).to.be.true;
expect(paneList[3].style.display).to.not.ok;
expect(vm.activeName === 'tab-D');
done();
});
}, 100);
});
it('card', () => {
vm = createVue({
template: `
<el-tabs type="card">
<el-tab-pane label="用户管理">A</el-tab-pane>
<el-tab-pane label="配置管理">B</el-tab-pane>
<el-tab-pane label="角色管理">C</el-tab-pane>
<el-tab-pane label="定时任务补偿">D</el-tab-pane>
</el-tabs>
`
}, true);
expect(vm.$el.classList.contains('el-tabs--card')).to.be.true;
});
it('border card', () => {
vm = createVue({
template: `
<el-tabs type="border-card">
<el-tab-pane label="用户管理">A</el-tab-pane>
<el-tab-pane label="配置管理">B</el-tab-pane>
<el-tab-pane label="角色管理">C</el-tab-pane>
<el-tab-pane label="定时任务补偿">D</el-tab-pane>
</el-tabs>
`
}, true);
expect(vm.$el.classList.contains('el-tabs--border-card')).to.be.true;
});
it('dynamic', (done) => {
vm = createVue({
template: `
<el-tabs type="card" ref="tabs">
<el-tab-pane :label="tab.label" :name="tab.name" v-for="tab in tabs" :key="tab.name">Test Content</el-tab-pane>
</el-tabs>
`,
data() {
return {
tabs: [{
label: 'tab1',
name: 'tab1'
}, {
label: 'tab2',
name: 'tab2'
}, {
label: 'tab3',
name: 'tab3'
}, {
label: 'tab4',
name: 'tab4'
}]
};
}
}, true);
setTimeout(() => {
expect(vm.$el.querySelectorAll('.el-tab-pane').length).to.equal(4);
vm.tabs.push({
label: 'tab5',
name: 'tab5'
});
setTimeout(() => {
expect(vm.$el.querySelectorAll('.el-tab-pane').length).to.equal(5);
done();
});
}, 100);
});
it('editable', done => {
vm = createVue({
template: `
<el-tabs ref="tabs" v-model="editableTabsValue" type="card" editable @edit="handleTabsEdit">
<el-tab-pane
v-for="(item, index) in editableTabs"
:key="item.name"
:label="item.title"
:name="item.name"
>
{{item.content}}
</el-tab-pane>
</el-tabs>
`,
data() {
return {
editableTabsValue: '2',
editableTabs: [{
title: 'Tab 1',
name: '1',
content: 'Tab 1 content'
}, {
title: 'Tab 2',
name: '2',
content: 'Tab 2 content'
}, {
title: 'Tab 3',
name: '3',
content: 'Tab 3 content'
}],
tabIndex: 3
};
},
methods: {
handleTabsEdit(targetName, action) {
if (action === 'add') {
let newTabName = ++this.tabIndex + '';
this.editableTabs.push({
title: 'New Tab',
name: newTabName,
content: 'New Tab content'
});
this.editableTabsValue = newTabName;
}
if (action === 'remove') {
let tabs = this.editableTabs;
let activeName = this.editableTabsValue;
if (activeName === targetName) {
tabs.forEach((tab, index) => {
if (tab.name === targetName) {
let nextTab = tabs[index + 1] || tabs[index - 1];
if (nextTab) {
activeName = nextTab.name;
}
}
});
}
this.editableTabsValue = activeName;
this.editableTabs = tabs.filter(tab => tab.name !== targetName);
}
}
}
}, true);
setTimeout(_ => {
const tabList = vm.$refs.tabs.$refs.nav.$refs.tabs;
const paneList = vm.$el.querySelector('.el-tabs__content').children;
tabList[1].querySelector('.el-icon-close').click();
setTimeout(_ => {
expect(tabList.length).to.be.equal(2);
expect(paneList.length).to.be.equal(2);
expect(tabList[1].classList.contains('is-active')).to.be.true;
vm.$refs.tabs.$el.querySelector('.el-tabs__new-tab').click();
setTimeout(_ => {
expect(tabList.length).to.be.equal(3);
expect(paneList.length).to.be.equal(3);
expect(tabList[2].classList.contains('is-active')).to.be.true;
done();
}, 100);
}, 100);
}, 100);
});
it('addable & closable', done => {
vm = createVue({
template: `
<el-tabs
ref="tabs"
v-model="editableTabsValue"
type="card"
addable
closable
@tab-add="addTab"
@tab-remove="removeTab"
>
<el-tab-pane
v-for="(item, index) in editableTabs"
:label="item.title"
:key="item.name"
:name="item.name"
>
{{item.content}}
</el-tab-pane>
</el-tabs>
`,
data() {
return {
editableTabsValue: '2',
editableTabs: [{
title: 'Tab 1',
name: '1',
content: 'Tab 1 content'
}, {
title: 'Tab 2',
name: '2',
content: 'Tab 2 content'
}],
tabIndex: 2
};
},
methods: {
addTab(targetName) {
let newTabName = ++this.tabIndex + '';
this.editableTabs.push({
title: 'New Tab',
name: newTabName,
content: 'New Tab content'
});
this.editableTabsValue = newTabName;
},
removeTab(targetName) {
let tabs = this.editableTabs;
let activeName = this.editableTabsValue;
if (activeName === targetName) {
tabs.forEach((tab, index) => {
if (tab.name === targetName) {
let nextTab = tabs[index + 1] || tabs[index - 1];
if (nextTab) {
activeName = nextTab.name;
}
}
});
}
this.editableTabsValue = activeName;
this.editableTabs = tabs.filter(tab => tab.name !== targetName);
}
}
}, true);
setTimeout(_ => {
const tabList = vm.$refs.tabs.$refs.nav.$refs.tabs;
const paneList = vm.$el.querySelector('.el-tabs__content').children;
vm.$refs.tabs.$el.querySelector('.el-tabs__new-tab').click();
setTimeout(_ => {
expect(tabList.length).to.be.equal(3);
expect(paneList.length).to.be.equal(3);
expect(tabList[2].classList.contains('is-active')).to.be.true;
tabList[2].querySelector('.el-icon-close').click();
setTimeout(_ => {
expect(tabList.length).to.be.equal(2);
expect(paneList.length).to.be.equal(2);
expect(tabList[1].classList.contains('is-active')).to.be.true;
done();
}, 100);
}, 100);
}, 100);
});
it('closable in tab-pane', (done) => {
vm = createVue({
template: `
<el-tabs type="card" ref="tabs">
<el-tab-pane label="用户管理" closable>A</el-tab-pane>
<el-tab-pane label="配置管理">B</el-tab-pane>
<el-tab-pane label="角色管理" closable>C</el-tab-pane>
<el-tab-pane label="定时任务补偿">D</el-tab-pane>
</el-tabs>
`
}, true);
setTimeout(() => {
expect(vm.$el.querySelectorAll('.el-icon-close').length).to.equal(2);
done();
}, 100);
});
it('disabled', done => {
vm = createVue({
template: `
<el-tabs type="card" ref="tabs">
<el-tab-pane label="用户管理">A</el-tab-pane>
<el-tab-pane disabled label="配置管理" ref="disabled">B</el-tab-pane>
<el-tab-pane label="角色管理">C</el-tab-pane>
<el-tab-pane label="定时任务补偿">D</el-tab-pane>
</el-tabs>
`
}, true);
vm.$nextTick(_ => {
const tabList = vm.$refs.tabs.$refs.nav.$refs.tabs;
tabList[1].click();
vm.$nextTick(_ => {
expect(tabList[1].classList.contains('is-active')).to.not.true;
done();
});
});
});
it('tab-position', done => {
vm = createVue({
template: `
<el-tabs ref="tabs" tab-position="left">
<el-tab-pane label="用户管理">A</el-tab-pane>
<el-tab-pane label="配置管理">B</el-tab-pane>
<el-tab-pane label="角色管理" ref="pane-click">C</el-tab-pane>
<el-tab-pane label="定时任务补偿">D</el-tab-pane>
</el-tabs>
`
}, true);
let paneList = vm.$el.querySelector('.el-tabs__content').children;
let spy = sinon.spy();
vm.$refs.tabs.$on('tab-click', spy);
setTimeout(_ => {
const tabList = vm.$refs.tabs.$refs.nav.$refs.tabs;
expect(tabList[0].classList.contains('is-active')).to.be.true;
expect(paneList[0].style.display).to.not.ok;
tabList[2].click();
vm.$nextTick(_ => {
expect(spy.withArgs(vm.$refs['pane-click']).calledOnce).to.true;
expect(tabList[2].classList.contains('is-active')).to.be.true;
expect(paneList[2].style.display).to.not.ok;
done();
});
}, 100);
});
it('stretch', done => {
vm = createVue({
template: `
<el-tabs ref="tabs" stretch :tab-position="tabPosition">
<el-tab-pane label="用户管理">A</el-tab-pane>
<el-tab-pane label="配置管理">B</el-tab-pane>
<el-tab-pane label="角色管理" ref="pane-click">C</el-tab-pane>
<el-tab-pane label="定时任务补偿">D</el-tab-pane>
</el-tabs>
`,
data() {
return {
tabPosition: 'bottom'
};
}
}, true);
setTimeout(_ => {
expect(vm.$el.querySelector('[role=tablist]').classList.contains('is-stretch')).to.be.true;
vm.tabPosition = 'left';
vm.$nextTick(_ => {
expect(vm.$el.querySelector('[role=tablist]').classList.contains('is-stretch')).not.to.be.true;
done();
});
}, 100);
});
it('horizonal-scrollable', done => {
vm = createVue({
template: `
<el-tabs ref="tabs" style="width: 200px;">
<el-tab-pane label="用户管理">A</el-tab-pane>
<el-tab-pane label="配置管理">B</el-tab-pane>
<el-tab-pane label="用户管理">A</el-tab-pane>
<el-tab-pane label="配置管理">B</el-tab-pane>
<el-tab-pane label="用户管理">A</el-tab-pane>
<el-tab-pane label="配置管理">B</el-tab-pane>
<el-tab-pane label="定时任务补偿">D</el-tab-pane>
</el-tabs>
`
}, true);
setTimeout(_ => {
const btnPrev = vm.$el.querySelector('.el-tabs__nav-prev');
btnPrev.click();
vm.$nextTick(_ => {
const tabNav = vm.$el.querySelector('.el-tabs__nav-wrap');
expect(tabNav.__vue__.navOffset).to.be.equal(0);
const btnNext = vm.$el.querySelector('.el-tabs__nav-next');
btnNext.click();
vm.$nextTick(_ => {
expect(tabNav.__vue__.navOffset).to.not.be.equal(0);
btnPrev.click();
vm.$nextTick(_ => {
expect(tabNav.__vue__.navOffset).to.be.equal(0);
done();
});
});
});
}, 100);
});
it('vertical-scrollable', done => {
vm = createVue({
template: `
<el-tabs ref="tabs" tab-position="left" style="height: 200px;">
<el-tab-pane label="用户管理">A</el-tab-pane>
<el-tab-pane label="配置管理">B</el-tab-pane>
<el-tab-pane label="用户管理">A</el-tab-pane>
<el-tab-pane label="配置管理">B</el-tab-pane>
<el-tab-pane label="用户管理">A</el-tab-pane>
<el-tab-pane label="配置管理">B</el-tab-pane>
<el-tab-pane label="定时任务补偿">D</el-tab-pane>
</el-tabs>
`
}, true);
setTimeout(_ => {
const btnPrev = vm.$el.querySelector('.el-tabs__nav-prev');
btnPrev.click();
vm.$nextTick(_ => {
const tabNav = vm.$el.querySelector('.el-tabs__nav-wrap');
expect(tabNav.__vue__.navOffset).to.be.equal(0);
const btnNext = vm.$el.querySelector('.el-tabs__nav-next');
btnNext.click();
vm.$nextTick(_ => {
expect(tabNav.__vue__.navOffset).to.not.be.equal(0);
btnPrev.click();
vm.$nextTick(_ => {
expect(tabNav.__vue__.navOffset).to.be.equal(0);
done();
});
});
});
}, 100);
});
it('should work with lazy', done => {
vm = createVue({
template: `
<el-tabs ref="tabs">
<el-tab-pane label="用户管理" name="A">A</el-tab-pane>
<el-tab-pane label="配置管理" name="B">B</el-tab-pane>
<el-tab-pane label="角色管理" name="C">C</el-tab-pane>
<el-tab-pane label="定时任务补偿" lazy name="D">D</el-tab-pane>
</el-tabs>
`
}, true);
expect(vm.$el.querySelector('.el-tabs__content').children.length).to.be.equal(3);
expect(vm.$el.querySelector('.el-tabs__content > #pane-D')).to.be.equal(null);
setTimeout(_ => {
vm.$el.querySelector('.el-tabs__nav > #tab-D').click();
vm.$nextTick(() => {
expect(vm.$el.querySelector('.el-tabs__content').children.length).to.be.equal(4);
expect(vm.$el.querySelector('.el-tabs__content > #pane-D')).not.to.be.equal(null);
vm.$el.querySelector('.el-tabs__nav > #tab-A').click();
vm.$nextTick(() => {
expect(vm.$el.querySelector('.el-tabs__content').children.length).to.be.equal(4);
expect(vm.$el.querySelector('.el-tabs__content > #pane-D')).not.to.be.equal(null);
done();
});
});
}, 100);
});
it('before leave', done => {
vm = createVue({
template: `
<el-tabs ref="tabs" v-model="activeName" :before-leave="beforeLeave">
<el-tab-pane name="tab-A" label="用户管理">A</el-tab-pane>
<el-tab-pane name="tab-B" label="配置管理">B</el-tab-pane>
<el-tab-pane name="tab-C" label="角色管理">C</el-tab-pane>
<el-tab-pane name="tab-D" label="定时任务补偿">D</el-tab-pane>
</el-tabs>
`,
data() {
return {
activeName: 'tab-B'
};
},
methods: {
beforeLeave() {
return new window.Promise((resolve, reject) => {
reject();
});
}
}
}, true);
setTimeout(_ => {
const paneList = vm.$el.querySelector('.el-tabs__content').children;
const tabList = vm.$refs.tabs.$refs.nav.$refs.tabs;
expect(tabList[1].classList.contains('is-active')).to.be.true;
expect(paneList[1].style.display).to.not.ok;
tabList[3].click();
vm.$nextTick(_ => {
setTimeout(() => {
expect(tabList[1].classList.contains('is-active')).to.be.true;
expect(paneList[1].style.display).to.not.ok;
expect(vm.activeName === 'tab-B');
done();
}, 200);
});
}, 100);
});
it('keyboard event', done => {
vm = createVue({
template: `
<el-tabs v-model="activeName">
<el-tab-pane label="用户管理" name="first">A</el-tab-pane>
<el-tab-pane label="配置管理" name="second">B</el-tab-pane>
<el-tab-pane label="角色管理" name="third">C</el-tab-pane>
<el-tab-pane label="定时任务补偿" name="fourth">D</el-tab-pane>
</el-tabs>
`,
data() {
return {
activeName: 'second'
};
}
}, true);
expect(vm.activeName).to.be.equal('second');
vm.$nextTick(() => {
triggerKeyDown(vm.$el.querySelector('#tab-second'), 39);
expect(vm.activeName).to.be.equal('third');
triggerKeyDown(vm.$el.querySelector('#tab-third'), 39);
expect(vm.activeName).to.be.equal('fourth');
triggerKeyDown(vm.$el.querySelector('#tab-fourth'), 39);
expect(vm.activeName).to.be.equal('first');
triggerKeyDown(vm.$el.querySelector('#tab-first'), 37);
expect(vm.activeName).to.be.equal('fourth');
triggerKeyDown(vm.$el.querySelector('#tab-fourth'), 37);
expect(vm.activeName).to.be.equal('third');
done();
});
});
});

125
test/unit/specs/tag.spec.js Normal file
View File

@@ -0,0 +1,125 @@
import { createTest, createVue, destroyVM } from '../util';
import Tag from 'packages/tag';
describe('Tag', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', () => {
vm = createVue({
template: `
<el-tag></el-tag>
`
}, true);
expect(vm.$el.classList.contains('el-tag')).to.be.true;
expect(vm.$el.classList.contains('el-tag__close')).to.be.false;
expect(vm.$el.classList.contains('is-hit')).to.be.false;
expect(vm.$el.classList.contains('md-fade-center')).to.be.false;
});
it('text', () => {
vm = createVue({
template: `
<el-tag>标签</el-tag>
`
}, true);
expect(vm.$el.textContent.length).to.be.at.least(2);
});
it('type', () => {
vm = createVue({
template: `
<el-tag type="primary"></el-tag>
`
}, true);
expect(vm.$el.classList.contains('el-tag--primary')).to.be.true;
});
it('hit', () => {
vm = createVue({
template: `
<el-tag hit></el-tag>
`
}, true);
expect(vm.$el.classList.contains('is-hit')).to.be.true;
});
it('closable', done => {
vm = createVue({
template: `
<el-tag closable @close="handleClose">关闭标签</el-tag>
`,
data() {
return {
isClose: false
};
},
methods: {
handleClose() {
this.isClose = true;
}
}
}, true);
var closeBtn = vm.$el.querySelector('.el-tag .el-tag__close');
expect(closeBtn).to.exist;
closeBtn.click();
vm.$nextTick(_ => {
expect(vm.isClose).to.true;
done();
});
});
it('closeTransition', () => {
vm = createVue({
template: `
<el-tag closable closeTransition></el-tag>
`
}, true);
expect(vm.$el.classList.contains('md-fade-center')).to.be.false;
});
it('color', () => {
vm = createVue({
template: `
<el-tag ref="tag" color="rgb(0, 0, 0)"></el-tag>
`
}, true);
expect(vm.$el.style.backgroundColor).to.equal('rgb(0, 0, 0)');
});
it('click', done => {
vm = createVue({
template: `
<el-tag ref="tag" @click="handleClick">点击标签</el-tag>
`,
data() {
return {
clicksCount: 0
};
},
methods: {
handleClick() {
this.clicksCount = this.clicksCount + 1;
}
}
}, true);
let tag = vm.$refs.tag;
tag.$el.click();
setTimeout(_ => {
expect(vm.clicksCount).to.be.equal(1);
done();
}, 20);
});
it('theme', () => {
vm = createTest(Tag, { effect: 'dark' }, true);
const el = vm.$el;
expect(el.className).to.includes('el-tag--dark');
expect(el.className).to.not.includes('el-tag--light');
expect(el.className).to.not.includes('el-tag--plain');
});
});

View File

@@ -0,0 +1,352 @@
import { createTest, destroyVM, createVue } from '../util';
import TimePicker from 'packages/time-picker';
const DELAY = 100;
describe('TimePicker', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', () => {
vm = createTest(TimePicker, {
placeholder: 'test',
readonly: true
});
expect(vm.$el.querySelector('input').getAttribute('placeholder')).to.equal('test');
expect(vm.$el.querySelector('input').getAttribute('readonly')).to.ok;
});
it('format', () => {
vm = createTest(TimePicker, {
format: 'HH-mm-ss',
value: new Date(2016, 9, 10, 18, 40)
});
expect(vm.$el.querySelector('input').value).to.equal('18-40-00');
});
it('set AM/PM format', done => {
vm = createTest(TimePicker, {
format: 'hh:mm:ss A',
value: new Date(2016, 9, 10, 18, 40)
}, true);
const input = vm.$el.querySelector('input');
expect(vm.$el.querySelector('input').value).to.equal('06:40:00 PM');
input.blur();
input.focus();
setTimeout(_ => {
const list = vm.picker.$el.querySelectorAll('.el-time-spinner__list');
const hoursEl = list[0];
expect(hoursEl.querySelectorAll('.el-time-spinner__item')[0].textContent).to.equal('12 AM');
expect(hoursEl.querySelectorAll('.el-time-spinner__item')[1].textContent).to.equal('01 AM');
expect(hoursEl.querySelectorAll('.el-time-spinner__item')[12].textContent).to.equal('12 PM');
expect(hoursEl.querySelectorAll('.el-time-spinner__item')[15].textContent).to.equal('03 PM');
done();
}, DELAY);
});
it('default value', done => {
vm = createTest(TimePicker, {
value: new Date(2016, 9, 10, 18, 40)
}, true);
const input = vm.$el.querySelector('input');
input.blur();
input.focus();
input.blur();
setTimeout(_ => {
const times = vm.picker.$el.querySelectorAll('.active');
expect(times[0].textContent).to.equal('18');
expect(times[1].textContent).to.equal('40');
expect(times[2].textContent).to.equal('00');
done();
}, DELAY);
});
it('select time', done => {
vm = createVue({
template: '<el-time-picker ref="compo" v-model="value"></el-time-picker>',
data() {
return {
value: ''
};
}
}, true);
const timePicker = vm.$refs.compo;
const input = timePicker.$el.querySelector('input');
input.blur();
input.focus();
setTimeout(_ => {
const list = timePicker.picker.$el.querySelectorAll('.el-time-spinner__list');
const hoursEl = list[0];
const minutesEl = list[1];
const secondsEl = list[2];
const hourEl = hoursEl.querySelectorAll('.el-time-spinner__item')[4];
const minuteEl = minutesEl.querySelectorAll('.el-time-spinner__item')[36];
const secondEl = secondsEl.querySelectorAll('.el-time-spinner__item')[20];
// click hour, minute, second one at a time.
hourEl.click();
vm.$nextTick(_ => {
minuteEl.click();
vm.$nextTick(_ => {
secondEl.click();
setTimeout(_ => {
const date = timePicker.picker.date;
expect(hourEl.classList.contains('active')).to.true;
expect(minuteEl.classList.contains('active')).to.true;
expect(secondEl.classList.contains('active')).to.true;
expect(date.getHours()).to.equal(4);
expect(date.getMinutes()).to.equal(36);
expect(date.getSeconds()).to.equal(20);
done();
}, DELAY);
});
});
}, DELAY);
});
it('click cancel button', done => {
vm = createVue({
template: '<el-time-picker ref="compo" v-model="value"></el-time-picker>',
data() {
return {
value: ''
};
}
}, true);
const timePicker = vm.$refs.compo;
const input = timePicker.$el.querySelector('input');
input.blur();
input.focus();
setTimeout(_ => {
timePicker.picker.$el.querySelector('.el-time-panel__btn.cancel').click();
setTimeout(_ => {
expect(vm.value).to.equal('');
done();
}, DELAY);
}, DELAY);
});
it('click confirm button', done => {
vm = createVue({
template: '<el-time-picker ref="compo" v-model="value"></el-time-picker>',
data() {
return {
value: ''
};
}
}, true);
const timePicker = vm.$refs.compo;
const input = timePicker.$el.querySelector('input');
input.blur();
input.focus();
setTimeout(_ => {
timePicker.picker.$el.querySelector('.el-time-panel__btn.confirm').click();
setTimeout(_ => {
expect(vm.value.toISOString()).to.exist;
done();
}, DELAY);
}, DELAY);
});
it('set format', done => {
vm = createTest(TimePicker, {
pickerOptions: {
format: 'HH:mm'
}
}, true);
const input = vm.$el.querySelector('input');
input.blur();
input.focus();
setTimeout(_ => {
expect(vm.picker.$el.querySelectorAll('.el-time-spinner__wrapper')[2].style.display).to.equal('none');
done();
}, 20);
});
it('set format to empty', done => {
vm = createTest(TimePicker, {
pickerOptions: {
format: ''
}
}, true);
const input = vm.$el.querySelector('input');
input.blur();
input.focus();
setTimeout(_ => {
expect(vm.picker.$el.querySelectorAll('.el-time-spinner__wrapper')[2].style.display).to.equal('none');
done();
}, DELAY);
});
it('selectableRange', done => {
vm = createTest(TimePicker, {
pickerOptions: {
selectableRange: ['17:30:00 - 18:30:00', '18:50:00 - 20:30:00', '21:00:00 - 22:00:00']
}
}, true);
const input = vm.$el.querySelector('input');
input.blur();
input.focus();
setTimeout(_ => {
const list = vm.picker.$el.querySelectorAll('.el-time-spinner__list');
const hoursEl = list[0];
const disabledHours = [].slice
.call(hoursEl.querySelectorAll('.disabled'))
.map(node => Number(node.textContent));
hoursEl.querySelectorAll('.disabled')[0].click();
expect(disabledHours).to.not.include.members([17, 18, 19, 20, 21, 22]);
const minutesEl = list[1];
hoursEl.querySelectorAll('.el-time-spinner__item')[18].click();
setTimeout(_ => {
const disabledMinutes = [].slice
.call(minutesEl.querySelectorAll('.disabled'))
.map(node => Number(node.textContent));
expect(disabledMinutes.every(t => t > 30 && t < 50)).to.equal(true);
expect(disabledMinutes.length).to.equal(19);
done();
}, DELAY);
}, DELAY);
});
it('event focus and blur', done => {
vm = createVue({
template: `
<el-date-picker
type="date"
placeholder="选择日期"
ref="picker">
</el-date-picker>
`
}, true);
const spyFocus = sinon.spy();
const spyBlur = sinon.spy();
vm.$refs.picker.$on('focus', spyFocus);
vm.$refs.picker.$on('blur', spyBlur);
vm.$el.querySelector('input').focus();
vm.$nextTick(_ => {
expect(spyFocus.calledOnce).to.be.true;
vm.$refs.picker.pickerVisible = false;
vm.$nextTick(_ => {
expect(spyBlur.calledOnce).to.be.true;
done();
});
});
});
it('focus', done => {
vm = createVue({
template: `
<el-date-picker
type="date"
placeholder="选择日期"
ref="picker">
</el-date-picker>
`
}, true);
const spy = sinon.spy();
vm.$refs.picker.$on('focus', spy);
vm.$refs.picker.focus();
vm.$nextTick(_ => {
expect(spy.calledOnce).to.be.true;
done();
});
});
});
describe('TimePicker(range)', () => {
let vm;
afterEach(() => destroyVM(vm));
it('create', done => {
vm = createTest(TimePicker, {
isRange: true,
value: [new Date(2016, 9, 10, 18, 40), new Date(2016, 9, 10, 19, 40)]
}, true);
vm.$el.querySelector('input').click();
setTimeout(_ => {
expect(vm.picker.$el.querySelectorAll('.el-time-range-picker__cell')).to.length(2);
expect(vm.picker.minDate.getTime()).to.equal(new Date(2016, 9, 10, 18, 40).getTime());
expect(vm.picker.maxDate.getTime()).to.equal(new Date(2016, 9, 10, 19, 40).getTime());
done();
}, DELAY);
});
it('default value', done => {
const defaultValue = [new Date(2000, 9, 1, 10, 0, 0), new Date(2000, 9, 1, 11, 0, 0)];
vm = createVue({
template: '<el-time-picker ref="compo" is-range v-model="value" :default-value="defaultValue"></el-time-picker>',
data() {
return {
value: '',
defaultValue
};
}
}, true);
const timePicker = vm.$refs.compo;
timePicker.$el.querySelector('input').click();
setTimeout(_ => {
expect(timePicker.picker.minDate.getTime()).to.equal(defaultValue[0].getTime());
expect(timePicker.picker.maxDate.getTime()).to.equal(defaultValue[1].getTime());
done();
}, DELAY);
});
it('cancel button', done => {
vm = createVue({
template: '<el-time-picker ref="compo" is-range v-model="value"></el-time-picker>',
data() {
return {
value: ''
};
}
}, true);
const timePicker = vm.$refs.compo;
timePicker.$el.querySelector('input').click();
setTimeout(_ => {
timePicker.picker.$el.querySelector('.cancel').click();
setTimeout(_ => {
expect(timePicker.picker.visible).to.false;
expect(vm.value).to.equal('');
done();
}, DELAY);
}, DELAY);
});
});

View File

@@ -0,0 +1,243 @@
import { createTest, createVue, destroyVM } from '../util';
import TimeSelect from 'packages/time-select';
import Vue from 'vue';
describe('TimeSelect', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('should render correct contents', done => {
vm = createTest(TimeSelect, {
pickerOptions: {
start: '08:30',
step: '00:15',
end: '18:30'
},
placeholder: 'test'
}, true);
const input = vm.$el.querySelector('input');
input.focus();
input.blur();
Vue.nextTick(_ => {
expect(vm.picker.start).to.equal('08:30');
expect(vm.picker.end).to.equal('18:30');
expect(vm.picker.step).to.equal('00:15');
expect(vm.$el.querySelector('input').getAttribute('placeholder')).to.equal('test');
done();
});
});
it('select time', done => {
vm = createVue({
template: `
<div>
<el-time-select ref="compo" v-model="value">
</el-time-select>
</div>
`,
data() {
return {
value: ''
};
}
}, true);
const input = vm.$el.querySelector('input');
input.focus();
input.blur();
Vue.nextTick(_ => {
const items = vm.$refs.compo.picker.$el.querySelectorAll('.time-select-item');
const target = items[4];
const time = target.textContent;
target.click();
Vue.nextTick(_ => {
expect(vm.value).to.equal(time);
done();
});
});
});
it('set default value', done => {
vm = createTest(TimeSelect, {
value: '14:30'
}, true);
const input = vm.$el.querySelector('input');
input.focus();
input.blur();
setTimeout(_ => {
expect(input.value).to.equal('14:30');
expect(vm.picker.$el.querySelector('.selected')).to.be.ok;
expect(vm.picker.$el.querySelector('.selected').textContent).to.equal('14:30');
done();
}, 50);
});
it('set minTime', done => {
vm = createVue(`
<el-time-select
ref="picker"
:picker-options="{
minTime: '14:30'
}">
</el-time-select>
`, true);
const input = vm.$el.querySelector('input');
const picker = vm.$refs.picker;
input.focus();
input.blur();
setTimeout(_ => {
const elms = picker.picker.$el.querySelectorAll('.disabled');
const elm = elms[elms.length - 1];
expect(elm.textContent).to.equal('14:30');
done();
}, 50);
});
it('minTime < value', done => {
vm = createVue({
template: `
<el-time-select
ref="picker"
v-model="value"
:picker-options="{
minTime: '14:30'
}">
</el-time-select>
`,
data() {
return { value: '09:30' };
}
}, true);
const input = vm.$el.querySelector('input');
const picker = vm.$refs.picker;
input.focus();
input.blur();
setTimeout(_ => {
vm.value = '10:30';
setTimeout(_ => {
expect(picker.picker.value).to.equal('10:30');
done();
}, 50);
}, 50);
});
it('set maxTime', done => {
vm = createVue(`
<el-time-select
ref="picker"
:picker-options="{
maxTime: '14:30',
step: '00:30'
}">
</el-time-select>
`, true);
const input = vm.$el.querySelector('input');
const picker = vm.$refs.picker;
input.focus();
input.blur();
setTimeout(_ => {
const elm = picker.picker.$el.querySelector('.disabled');
expect(elm.textContent).to.equal('14:30');
done();
}, 50);
});
it('maxTime > value', done => {
vm = createVue({
template: `
<el-time-select
ref="picker"
v-model="value"
:picker-options="{
maxTime: '14:30'
}">
</el-time-select>
`,
data() {
return { value: '09:30' };
}
}, true);
const input = vm.$el.querySelector('input');
const picker = vm.$refs.picker;
input.focus();
input.blur();
setTimeout(_ => {
vm.value = '10:30';
setTimeout(_ => {
expect(picker.picker.value).to.equal('10:30');
done();
}, 50);
}, 50);
});
it('event focus and blur', done => {
vm = createVue({
template: `
<el-time-select
ref="picker"
:picker-options="{
start: '08:30',
step: '00:15',
end: '18:30'
}"
placeholder="选择时间">
</el-time-select>
`
}, true);
const spyFocus = sinon.spy();
const spyBlur = sinon.spy();
vm.$refs.picker.$on('focus', spyFocus);
vm.$refs.picker.$on('blur', spyBlur);
vm.$el.querySelector('input').focus();
vm.$nextTick(_ => {
expect(spyFocus.calledOnce).to.be.true;
vm.$refs.picker.pickerVisible = false;
vm.$nextTick(_ => {
expect(spyBlur.calledOnce).to.be.true;
done();
});
});
});
it('focus', done => {
vm = createVue({
template: `
<el-time-select ref="picker"></el-time-select>
`
}, true);
const spy = sinon.spy();
vm.$refs.picker.$on('focus', spy);
vm.$refs.picker.focus();
vm.$nextTick(_ => {
expect(spy.calledOnce).to.be.true;
done();
});
});
});

View File

@@ -0,0 +1,228 @@
import { createVue, destroyVM } from '../util';
describe('Timeline', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', () => {
vm = createVue({
template: `
<el-timeline>
<el-timeline-item
v-for="(activity, index) in activities"
:key="index"
:timestamp="activity.timestamp">
{{activity.content}}
</el-timeline-item>
</el-timeline>
`,
data() {
return {
activities: [{
content: '创建成功',
timestamp: '2018-04-11'
}, {
content: '通过审核',
timestamp: '2018-04-13'
}, {
content: '活动按期开始',
timestamp: '2018-04-15'
}]
};
}
}, true);
let contentElms = vm.$el.querySelectorAll('.el-timeline-item__content');
contentElms.forEach((elm, index) => {
expect(elm.innerText).to.equal(vm.activities[index].content);
});
let timestampElms = vm.$el.querySelectorAll('.el-timeline-item__timestamp');
timestampElms.forEach((elm, index) => {
expect(elm.innerText).to.equal(vm.activities[index].timestamp);
});
});
it('reverse', done => {
vm = createVue({
template: `
<el-timeline :reverse="reverse">
<el-timeline-item
v-for="(activity, index) in activities"
:key="index"
:timestamp="activity.timestamp">
{{activity.content}}
</el-timeline-item>
</el-timeline>
`,
data() {
return {
reverse: true,
activities: [{
content: '创建成功',
timestamp: '2018-04-11'
}, {
content: '通过审核',
timestamp: '2018-04-13'
}, {
content: '活动按期开始',
timestamp: '2018-04-15'
}]
};
}
}, true);
const contentElms = vm.$el.querySelectorAll('.el-timeline-item__content');
contentElms.forEach((elm, index) => {
expect(elm.innerText).to.equal(vm.activities[vm.activities.length - index - 1].content);
});
vm.reverse = false;
vm.$nextTick(() => {
const contentElms = vm.$el.querySelectorAll('.el-timeline-item__content');
contentElms.forEach((elm, index) => {
expect(elm.innerText).to.equal(vm.activities[index].content);
});
done();
});
});
it('placement', () => {
vm = createVue({
template: `
<el-timeline>
<el-timeline-item
v-for="(activity, index) in activities"
:key="index"
:timestamp="activity.timestamp"
:placement="activity.placement">
{{activity.content}}
</el-timeline-item>
</el-timeline>
`,
data() {
return {
activities: [{
content: '创建成功',
timestamp: '2018-04-11',
placement: 'top'
}, {
content: '通过审核',
timestamp: '2018-04-13'
}, {
content: '活动按期开始',
timestamp: '2018-04-15'
}]
};
}
}, true);
const timestampElm = vm.$el.querySelectorAll('.el-timeline-item__timestamp')[0];
expect(timestampElm.classList.contains('is-top')).to.true;
});
it('hide-timestamp', () => {
vm = createVue({
template: `
<el-timeline>
<el-timeline-item
v-for="(activity, index) in activities"
:key="index"
:timestamp="activity.timestamp"
:hide-timestamp="activity.hideTimestamp">
{{activity.content}}
</el-timeline-item>
</el-timeline>
`,
data() {
return {
activities: [{
content: '创建成功',
timestamp: '2018-04-11',
hideTimestamp: true
}, {
content: '通过审核',
timestamp: '2018-04-13'
}, {
content: '活动按期开始',
timestamp: '2018-04-15'
}]
};
}
}, true);
const timestampElms = vm.$el.querySelectorAll('.el-timeline-item__timestamp');
expect(timestampElms.length).to.equal(2);
});
it('color', () => {
vm = createVue({
template: `
<el-timeline>
<el-timeline-item
timestamp="2018-04-11"
color="#f00">
创建成功
</el-timeline-item>
</el-timeline>
`
}, true);
const nodeElm = vm.$el.querySelector('.el-timeline-item__node');
expect(nodeElm.style.backgroundColor).to.equal('rgb(255, 0, 0)');
});
it('type', () => {
vm = createVue({
template: `
<el-timeline>
<el-timeline-item
timestamp="2018-04-11"
type="primary">
创建成功
</el-timeline-item>
</el-timeline>
`
}, true);
const nodeElm = vm.$el.querySelector('.el-timeline-item__node');
expect(nodeElm.classList.contains('el-timeline-item__node--primary')).to.true;
});
it('size', () => {
vm = createVue({
template: `
<el-timeline>
<el-timeline-item
timestamp="2018-04-11"
type="large">
创建成功
</el-timeline-item>
</el-timeline>
`
}, true);
const nodeElm = vm.$el.querySelector('.el-timeline-item__node');
expect(nodeElm.classList.contains('el-timeline-item__node--large')).to.true;
});
it('icon', () => {
vm = createVue({
template: `
<el-timeline>
<el-timeline-item
timestamp="2018-04-11"
icon="el-icon-more">
创建成功
</el-timeline-item>
</el-timeline>
`
}, true);
const nodeElm = vm.$el.querySelector('.el-timeline-item__icon');
expect(nodeElm.classList.contains('el-icon-more')).to.true;
});
});

View File

@@ -0,0 +1,164 @@
import { createVue, triggerEvent, destroyVM } from '../util';
describe('Tooltip', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('create', done => {
vm = createVue(`
<el-tooltip ref="tooltip" content="提示文字">
<button>click</button>
</el-tooltip>`);
vm.$nextTick(_ => {
expect(vm.$refs.tooltip.popperVM.$el).to.have.property('textContent', '提示文字');
done();
});
});
it('custom popper class', done => {
vm = createVue(`
<el-tooltip ref="tooltip" content="提示文字" popper-class="custom-popper">
<button>click</button>
</el-tooltip>`);
vm.$nextTick(_ => {
expect(vm.$refs.tooltip.popperVM.$el.classList.contains('custom-popper')).to.true;
done();
});
});
describe('manual', () => {
const vm = createVue({
template: `
<el-tooltip ref="tooltip" manual content="abc" v-model="show">
<button>click</button>
</el-tooltip>
`,
data() {
return { show: false };
}
}, true);
const tooltip = vm.$refs.tooltip;
it('showPopper is false', () => {
triggerEvent(tooltip.$el, 'mouseenter');
expect(tooltip.showPopper).to.false;
});
it('show', done => {
vm.show = true;
vm.$nextTick(_ => {
expect(tooltip.showPopper).to.true;
done();
});
});
it('still show when trigger mouseleave', () => {
triggerEvent(tooltip.$el, 'mouseleave');
expect(tooltip.showPopper).to.true;
});
it('hidden', done => {
vm.show = false;
vm.$nextTick(_ => {
expect(tooltip.showPopper).to.false;
done();
});
});
});
describe('hover', () => {
const vm = createVue(`
<el-tooltip ref="tooltip" content="提示文字">
<button>click</button>
</el-tooltip>
`);
const tooltip = vm.$refs.tooltip;
triggerEvent(tooltip.$el, 'mouseenter');
it('popperElm is exist', () => expect(tooltip.popperElm).to.exist);
it('showPopper is true', () => expect(tooltip.showPopper).to.true);
it('close popper', done => {
triggerEvent(tooltip.$el, 'mouseleave');
setTimeout(() => {
expect(tooltip.showPopper).to.false;
done();
}, 300);
});
});
it('light mode', done => {
vm = createVue(`
<el-tooltip ref="tooltip" content="abc" effect="light">
<button>abc</button>
</el-tooltip>
`);
vm.$nextTick(_ => {
expect(vm.$refs.tooltip.popperVM.$el.classList.contains('is-light')).to.exist;
done();
});
});
it('hide after', done => {
vm = createVue(`
<el-tooltip ref="tooltip" content="提示文字" :hide-after="300">
<button>click</button>
</el-tooltip>`);
const tooltip = vm.$refs.tooltip;
vm.$nextTick(_ => {
triggerEvent(tooltip.$el, 'mouseenter');
setTimeout(() => {
expect(tooltip.showPopper).to.be.true;
setTimeout(() => {
expect(tooltip.showPopper).to.be.false;
done();
}, 300);
}, 100);
});
});
it('remove focus', done => {
vm = createVue(`
<el-tooltip ref="tooltip" content="提示文字" :hide-after="300">
<button>click</button>
</el-tooltip>`);
const tooltip = vm.$refs.tooltip;
vm.$nextTick(_ => {
triggerEvent(tooltip.$el, 'mouseenter');
setTimeout(() => {
tooltip.focusing = true;
tooltip.$el.click();
setTimeout(() => {
expect(tooltip.showPopper).to.be.false;
done();
}, 300);
}, 100);
});
});
it('reference element focus', done => {
vm = createVue(`
<el-tooltip ref="tooltip" content="提示文字">
<button>click</button>
</el-tooltip>`);
const tooltip = vm.$refs.tooltip;
vm.$nextTick(_ => {
triggerEvent(tooltip.$el, 'focus');
setTimeout(() => {
expect(tooltip.showPopper).to.be.true;
expect(tooltip.focusing).to.be.true;
triggerEvent(tooltip.$el, 'blur');
setTimeout(() => {
expect(tooltip.showPopper).to.be.false;
expect(tooltip.focusing).to.be.false;
done();
}, 300);
}, 100);
});
});
it('custom tabindex', () => {
vm = createVue(`
<el-tooltip ref="tooltip" content="提示文字" :tabindex="-1">
<button>click</button>
</el-tooltip>
`, true);
expect(vm.$el.getAttribute('tabindex')).to.be.equal('-1');
});
});

View File

@@ -0,0 +1,184 @@
import { createTest, createVue, destroyVM } from '../util';
import Transfer from 'packages/transfer';
describe('Transfer', () => {
let vm;
const getTestData = () => {
const data = [];
for (let i = 1; i <= 15; i++) {
data.push({
key: i,
label: `备选项 ${ i }`,
disabled: i % 4 === 0
});
}
return data;
};
const createTransfer = (props, opts) => {
return createVue(Object.assign({
template: `
<el-transfer :data="testData" ref="transfer" ${props}>
</el-transfer>
`,
created() {
this.testData = getTestData();
}
}, opts));
};
afterEach(() => {
destroyVM(vm);
});
it('create', () => {
vm = createTest(Transfer, true);
expect(vm.$el).to.exist;
});
it('default target list', () => {
vm = createTransfer('v-model="value"', {
data() {
return {
value: [1, 4]
};
}
});
expect(vm.$refs.transfer.sourceData.length).to.equal(13);
});
it('filterable', done => {
vm = createTransfer('v-model="value" filterable :filter-method="method"', {
data() {
return {
value: [],
method(query, option) {
return option.key === Number(query);
}
};
}
});
const transfer = vm.$refs.transfer;
const leftList = transfer.$el.querySelector('.el-transfer-panel').__vue__;
leftList.query = '1';
setTimeout(_ => {
expect(leftList.filteredData.length).to.equal(1);
done();
}, 50);
});
it('transfer', done => {
vm = createTransfer('v-model="value" :left-default-checked="[2, 3]" :right-default-checked="[1]"', {
data() {
return {
value: [1, 4]
};
}
});
const transfer = vm.$refs.transfer;
setTimeout(_ => {
transfer.addToLeft();
setTimeout(_ => {
expect(transfer.sourceData.length).to.equal(14);
transfer.addToRight();
setTimeout(_ => {
expect(transfer.sourceData.length).to.equal(12);
done();
}, 50);
}, 50);
}, 50);
});
it('customize', () => {
vm = createTransfer('v-model="value" :titles="titles" :render-content="renderFunc" :format="format"', {
data() {
return {
value: [2],
titles: ['表1', '表2'],
format: { noChecked: 'no', hasChecked: 'has' },
renderFunc(h, option) {
return <span>{ option.key } - { option.label }</span>;
}
};
}
});
const transfer = vm.$refs.transfer.$el;
const label = transfer.querySelector('.el-transfer-panel__header .el-checkbox__label');
expect(label.innerText.indexOf('表1') > -1).to.true;
expect(transfer.querySelector('.el-transfer-panel__list .el-checkbox__label span').innerText).to.equal('1 - 备选项 1');
expect(label.querySelector('span').innerText).to.equal('no');
});
it('check', () => {
vm = createTransfer('v-model="value"', {
data() {
return {
value: []
};
}
});
const leftList = vm.$refs.transfer.$el.querySelector('.el-transfer-panel').__vue__;
leftList.handleAllCheckedChange({ target: { checked: true } });
expect(leftList.checked.length).to.equal(12);
});
describe('target order', () => {
it('original(default)', done => {
vm = createTransfer('v-model="value" :left-default-checked="[2, 3]"', {
data() {
return {
value: [1, 4]
};
}
});
const transfer = vm.$refs.transfer;
setTimeout(() => {
transfer.addToRight();
setTimeout(() => {
const targetItems = [].slice.call(vm.$el.querySelectorAll('.el-transfer__buttons + .el-transfer-panel .el-transfer-panel__body .el-checkbox__label span'));
expect(targetItems.map(item => item.innerText)).to.deep.equal(['备选项 1', '备选项 2', '备选项 3', '备选项 4']);
done();
}, 50);
}, 50);
});
it('push', done => {
vm = createTransfer('v-model="value" :left-default-checked="[2, 3]" target-order="push"', {
data() {
return {
value: [1, 4]
};
}
});
const transfer = vm.$refs.transfer;
setTimeout(() => {
transfer.addToRight();
setTimeout(() => {
const targetItems = [].slice.call(vm.$el.querySelectorAll('.el-transfer__buttons + .el-transfer-panel .el-transfer-panel__body .el-checkbox__label span'));
expect(targetItems.map(item => item.innerText)).to.deep.equal(['备选项 1', '备选项 4', '备选项 2', '备选项 3']);
done();
}, 50);
}, 50);
});
it('unshift', done => {
vm = createTransfer('v-model="value" :left-default-checked="[2, 3]" target-order="unshift"', {
data() {
return {
value: [1, 4]
};
}
});
const transfer = vm.$refs.transfer;
setTimeout(() => {
transfer.addToRight();
setTimeout(() => {
const targetItems = [].slice.call(vm.$el.querySelectorAll('.el-transfer__buttons + .el-transfer-panel .el-transfer-panel__body .el-checkbox__label span'));
expect(targetItems.map(item => item.innerText)).to.deep.equal(['备选项 2', '备选项 3', '备选项 1', '备选项 4']);
done();
}, 50);
}, 50);
});
});
});

View File

@@ -0,0 +1,893 @@
import { createVue, destroyVM, waitImmediate, wait } from '../util';
const DELAY = 10;
describe('Tree', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
const getTreeVm = (props, options) => {
return createVue(Object.assign({
template: `
<el-tree ref="tree" :data="data" ${ props }></el-tree>
`,
data() {
return {
defaultExpandedKeys: [],
defaultCheckedKeys: [],
clickedNode: null,
count: 1,
data: [{
id: 1,
label: '一级 1',
children: [{
id: 11,
label: '二级 1-1',
children: [{
id: 111,
label: '三级 1-1'
}]
}]
}, {
id: 2,
label: '一级 2',
children: [{
id: 21,
label: '二级 2-1'
}, {
id: 22,
label: '二级 2-2'
}]
}, {
id: 3,
label: '一级 3',
children: [{
id: 31,
label: '二级 3-1'
}, {
id: 32,
label: '二级 3-2'
}]
}],
defaultProps: {
children: 'children',
label: 'label'
}
};
}
}, options), true);
};
const getDisableTreeVm = (props, options) => {
return createVue(Object.assign({
template: `
<el-tree ref="tree" :data="data" ${ props }></el-tree>
`,
data() {
return {
defaultExpandedKeys: [],
defaultCheckedKeys: [],
clickedNode: null,
count: 1,
data: [{
id: 1,
label: '一级 1',
children: [{
id: 11,
label: '二级 1-1',
children: [{
id: 111,
label: '三级 1-1',
disabled: true
}]
}]
}, {
id: 2,
label: '一级 2',
children: [{
id: 21,
label: '二级 2-1'
}, {
id: 22,
label: '二级 2-2'
}]
}, {
id: 3,
label: '一级 3',
children: [{
id: 31,
label: '二级 3-1'
}, {
id: 32,
label: '二级 3-2'
}]
}],
defaultProps: {
children: 'children',
label: 'label',
disabled: 'disabled'
}
};
}
}, options), true);
};
const ALL_NODE_COUNT = 9;
it('create', () => {
vm = getTreeVm(':props="defaultProps" default-expand-all');
expect(document.querySelector('.el-tree')).to.exist;
expect(document.querySelectorAll('.el-tree > .el-tree-node').length).to.equal(3);
expect(document.querySelectorAll('.el-tree .el-tree-node').length).to.equal(ALL_NODE_COUNT);
vm.data[1].children = [{ label: '二级 2-1' }];
const tree = vm.$children[0];
expect(tree.children).to.deep.equal(vm.data);
});
it('click node', done => {
vm = getTreeVm(':props="defaultProps" @node-click="handleNodeClick"', {
methods: {
handleNodeClick(data) {
this.clickedNode = data;
}
}
});
const firstNode = vm.$el.querySelector('.el-tree-node__content');
firstNode.click();
expect(vm.clickedNode.label).to.equal('一级 1');
setTimeout(() => {
expect(vm.$el.querySelector('.el-tree-node').classList.contains('is-expanded')).to.true;
firstNode.click();
setTimeout(() => {
expect(vm.$el.querySelector('.el-tree-node').classList.contains('is-expanded')).to.false;
done();
}, DELAY);
}, DELAY);
});
it('current change', done => {
vm = getTreeVm(':props="defaultProps" @current-change="handleCurrentChange"', {
methods: {
handleCurrentChange(data) {
this.currentNode = data;
}
}
});
const firstNode = vm.$el.querySelector('.el-tree-node__content');
firstNode.click();
expect(vm.currentNode.label).to.equal('一级 1');
done();
});
it('emptyText', (done) => {
vm = getTreeVm(':props="defaultProps"');
vm.data = [];
vm.$nextTick(() => {
expect(vm.$el.querySelectorAll('.el-tree__empty-block').length).to.equal(1);
done();
});
});
it('highlight current', done => {
vm = getTreeVm(':props="defaultProps" highlight-current');
const firstNode = document.querySelector('.el-tree-node');
firstNode.click();
vm.$nextTick(() => {
expect(firstNode.className.indexOf('is-current')).to.not.equal(-1);
done();
});
});
it('expandOnNodeClick', done => {
vm = getTreeVm(':props="defaultProps" :expand-on-click-node="false"');
const firstNode = document.querySelector('.el-tree-node');
firstNode.click();
vm.$nextTick(() => {
expect(firstNode.className.indexOf('is-expanded')).to.equal(-1);
done();
});
});
it('checkOnNodeClick', done => {
vm = getTreeVm(':props="defaultProps" show-checkbox check-on-click-node');
const firstNode = document.querySelector('.el-tree-node');
firstNode.click();
vm.$nextTick(() => {
expect(firstNode.querySelector('input').checked).to.true;
done();
});
});
it('current-node-key', () => {
vm = getTreeVm(':props="defaultProps" default-expand-all highlight-current node-key="id" :current-node-key="11"');
const currentNodeLabel = document.querySelector('.is-current .el-tree-node__label').textContent;
expect(currentNodeLabel).to.be.equal('二级 1-1');
});
it('defaultExpandAll', () => {
vm = getTreeVm(':props="defaultProps" default-expand-all');
expect(vm.$el.querySelectorAll('.el-tree-node.is-expanded').length).to.equal(ALL_NODE_COUNT);
});
it('defaultExpandedKeys', () => {
vm = getTreeVm(':props="defaultProps" :default-expanded-keys="defaultExpandedKeys" node-key="id"', {
created() {
this.defaultExpandedKeys = [1, 3];
}
});
expect(vm.$el.querySelectorAll('.el-tree-node.is-expanded').length).to.equal(2);
});
it('defaultExpandedKeys set', (done) => {
vm = getTreeVm(':props="defaultProps" :default-expanded-keys="defaultExpandedKeys" node-key="id"', {
created() {
this.defaultExpandedKeys = [1, 3];
}
});
expect(vm.$el.querySelectorAll('.el-tree-node.is-expanded').length).to.equal(2);
vm.defaultExpandedKeys = [2];
vm.data = JSON.parse(JSON.stringify(vm.data));
setTimeout(() => {
expect(vm.$el.querySelectorAll('.el-tree-node.is-expanded').length).to.equal(1);
done();
}, 50);
});
it('filter-node-method', (done) => {
vm = getTreeVm(':props="defaultProps" :filter-node-method="filterNode"', {
methods: {
filterNode(value, data) {
if (!value) return true;
return data.label.indexOf(value) !== -1;
}
}
});
const tree = vm.$refs.tree;
tree.filter('2-1');
setTimeout(() => {
expect(tree.$el.querySelectorAll('.el-tree-node.is-hidden').length).to.equal(3);
done();
}, 100);
});
it('autoExpandParent = true', () => {
vm = getTreeVm(':props="defaultProps" :default-expanded-keys="defaultExpandedKeys" node-key="id"', {
created() {
this.defaultExpandedKeys = [111];
}
});
expect(vm.$el.querySelectorAll('.el-tree-node.is-expanded').length).to.equal(3);
});
it('autoExpandParent = false', (done) => {
vm = getTreeVm(':props="defaultProps" :default-expanded-keys="defaultExpandedKeys" node-key="id" :auto-expand-parent="false"', {
created() {
this.defaultExpandedKeys = [11];
}
});
expect(vm.$el.querySelectorAll('.el-tree-node.is-expanded').length).to.equal(0);
const firstNode = document.querySelector('.el-tree-node__content');
firstNode.querySelector('.el-tree-node__expand-icon').click();
setTimeout(() => {
expect(document.querySelectorAll('.el-tree-node.is-expanded').length).to.equal(2);
done();
}, 100);
});
it('defaultCheckedKeys & check-strictly = false', () => {
vm = getTreeVm(':props="defaultProps" default-expand-all show-checkbox :default-checked-keys="defaultCheckedKeys" node-key="id"', {
created() {
this.defaultCheckedKeys = [1];
}
});
expect(vm.$el.querySelectorAll('.el-checkbox .is-checked').length).to.equal(3);
});
it('defaultCheckedKeys & check-strictly', () => {
vm = getTreeVm(':props="defaultProps" default-expand-all show-checkbox :default-checked-keys="defaultCheckedKeys" node-key="id" check-strictly', {
created() {
this.defaultCheckedKeys = [1];
}
});
expect(vm.$el.querySelectorAll('.el-checkbox .is-checked').length).to.equal(1);
});
it('show checkbox', done => {
vm = getTreeVm(':props="defaultProps" show-checkbox');
const tree = vm.$children[0];
const secondNode = document.querySelectorAll('.el-tree-node__content')[1];
const nodeCheckbox = secondNode.querySelector('.el-checkbox');
expect(nodeCheckbox).to.be.exist;
nodeCheckbox.click();
setTimeout(() => {
expect(tree.getCheckedNodes().length).to.equal(3);
expect(tree.getCheckedNodes(true).length).to.equal(2);
secondNode.querySelector('.el-tree-node__expand-icon').click();
setTimeout(() => {
const firstLeaf = secondNode.nextElementSibling.querySelector('.el-tree-node__content');
const leafCheckbox = firstLeaf.querySelector('.el-checkbox');
leafCheckbox.click();
setTimeout(() => {
expect(tree.getCheckedNodes().length).to.equal(1);
done();
}, 10);
}, 10);
}, 10);
});
it('check', done => {
const spy = sinon.spy();
vm = getTreeVm(':props="defaultProps" show-checkbox @check="handleCheck"', {
methods: {
handleCheck: spy
}
});
const secondNode = document.querySelectorAll('.el-tree-node__content')[1];
const nodeCheckbox = secondNode.querySelector('.el-checkbox');
expect(nodeCheckbox).to.be.exist;
nodeCheckbox.click();
setTimeout(() => {
expect(spy.calledOnce).to.be.true;
const [data, args] = spy.args[0];
expect(data.id).to.equal(2);
expect(args.checkedNodes.length).to.equal(3);
done();
}, 10);
});
it('setCheckedNodes', (done) => {
vm = getTreeVm(':props="defaultProps" show-checkbox node-key="id"');
const tree = vm.$children[0];
const secondNode = document.querySelectorAll('.el-tree-node__content')[1];
const nodeCheckbox = secondNode.querySelector('.el-checkbox');
nodeCheckbox.click();
setTimeout(() => {
expect(tree.getCheckedNodes().length).to.equal(3);
expect(tree.getCheckedNodes(true).length).to.equal(2);
setTimeout(() => {
tree.setCheckedNodes([]);
expect(tree.getCheckedNodes().length).to.equal(0);
done();
}, 10);
}, 10);
});
it('setCheckedKeys', async() => {
vm = getTreeVm(':props="defaultProps" show-checkbox node-key="id"');
const tree = vm.$children[0];
tree.setCheckedKeys([111]);
await waitImmediate();
expect(tree.getCheckedNodes().length).to.equal(3);
expect(tree.getCheckedKeys().length).to.equal(3);
tree.setCheckedKeys([1]);
await waitImmediate();
expect(tree.getCheckedNodes().length).to.equal(3);
expect(tree.getCheckedKeys().length).to.equal(3);
tree.setCheckedKeys([2]);
await waitImmediate();
expect(tree.getCheckedNodes().length).to.equal(3);
expect(tree.getCheckedKeys().length).to.equal(3);
tree.setCheckedKeys([21]);
await waitImmediate();
expect(tree.getCheckedNodes().length).to.equal(1);
expect(tree.getCheckedKeys().length).to.equal(1);
});
it('setCheckedKeys with checkStrictly', async() => {
vm = getTreeVm(':props="defaultProps" checkStrictly show-checkbox node-key="id"');
const tree = vm.$children[0];
tree.setCheckedKeys([111]);
expect(tree.getCheckedNodes().length).to.equal(1);
expect(tree.getCheckedKeys().length).to.equal(1);
tree.setCheckedKeys([1]);
await waitImmediate();
expect(tree.getCheckedNodes().length).to.equal(1);
expect(tree.getCheckedKeys().length).to.equal(1);
tree.setCheckedKeys([2]);
await waitImmediate();
expect(tree.getCheckedNodes().length).to.equal(1);
expect(tree.getCheckedKeys().length).to.equal(1);
tree.setCheckedKeys([21, 22]);
await waitImmediate();
expect(tree.getCheckedNodes().length).to.equal(2);
expect(tree.getCheckedKeys().length).to.equal(2);
});
it('method setChecked', () => {
vm = getTreeVm(':props="defaultProps" show-checkbox node-key="id"');
const tree = vm.$children[0];
tree.setChecked(111, true, true);
expect(tree.getCheckedNodes().length).to.equal(3);
expect(tree.getCheckedKeys().length).to.equal(3);
tree.setChecked(vm.data[0], false, true);
expect(tree.getCheckedNodes().length).to.equal(0);
expect(tree.getCheckedKeys().length).to.equal(0);
});
it('setCheckedKeys with leafOnly=false', async() => {
vm = getTreeVm(':props="defaultProps" show-checkbox node-key="id"');
const tree = vm.$children[0];
tree.setCheckedKeys([1, 11, 111, 2], false);
await waitImmediate();
expect(tree.getCheckedNodes().length).to.equal(6);
expect(tree.getCheckedKeys().length).to.equal(6);
});
it('setCheckedKeys with leafOnly=true', async() => {
vm = getTreeVm(':props="defaultProps" show-checkbox node-key="id"');
const tree = vm.$children[0];
tree.setCheckedKeys([2], true);
await waitImmediate();
expect(tree.getCheckedNodes().length).to.equal(2);
expect(tree.getCheckedKeys().length).to.equal(2);
});
it('setCurrentKey', (done) => {
vm = getTreeVm(':props="defaultProps" show-checkbox node-key="id"');
const tree = vm.$children[0];
tree.setCurrentKey(111);
vm.$nextTick(() => {
expect(tree.store.currentNode.data.id).to.equal(111);
// cancel highlight
tree.setCurrentKey(null);
vm.$nextTick(() => {
expect(tree.store.currentNode).to.equal(null);
done();
});
});
});
it('setCurrentNode', (done) => {
vm = getTreeVm(':props="defaultProps" show-checkbox node-key="id"');
const tree = vm.$children[0];
tree.setCurrentNode({
id: 111,
label: '三级 1-1'
});
vm.$nextTick(() => {
expect(tree.store.currentNode.data.id).to.equal(111);
done();
});
});
it('getCurrentKey', (done) => {
vm = getTreeVm(':props="defaultProps" show-checkbox node-key="id"');
const tree = vm.$children[0];
tree.setCurrentKey(111);
vm.$nextTick(() => {
expect(tree.getCurrentKey()).to.equal(111);
done();
});
});
it('getCurrentNode', (done) => {
vm = getTreeVm(':props="defaultProps" show-checkbox node-key="id"');
const tree = vm.$children[0];
tree.setCurrentKey(111);
vm.$nextTick(() => {
expect(tree.getCurrentNode().id).to.equal(111);
done();
});
});
it('getNode', () => {
vm = getTreeVm(':props="defaultProps" node-key="id"');
const tree = vm.$children[0];
const node = tree.getNode(111);
expect(node.data.id).to.equal(111);
});
it('remove', (done) => {
vm = getTreeVm(':props="defaultProps" node-key="id"');
const tree = vm.$children[0];
tree.setCurrentKey(1);
expect(tree.getCurrentNode().id).to.equal(1);
tree.remove(1);
vm.$nextTick(() => {
expect(vm.data[0].id).to.equal(2);
expect(tree.getNode(1)).to.equal(null);
expect(tree.getCurrentNode()).to.equal(null);
done();
});
});
it('append', () => {
vm = getTreeVm(':props="defaultProps" node-key="id"');
const tree = vm.$children[0];
const nodeData = { id: 88, label: '88' };
tree.append(nodeData, tree.getNode(1));
expect(vm.data[0].children.length).to.equal(2);
expect(tree.getNode(88).data).to.equal(nodeData);
});
it('insertBefore', () => {
vm = getTreeVm(':props="defaultProps" node-key="id"');
const tree = vm.$children[0];
const nodeData = { id: 88, label: '88' };
tree.insertBefore(nodeData, tree.getNode(11));
expect(vm.data[0].children.length).to.equal(2);
expect(vm.data[0].children[0]).to.equal(nodeData);
expect(tree.getNode(88).data).to.equal(nodeData);
});
it('insertAfter', () => {
vm = getTreeVm(':props="defaultProps" node-key="id"');
const tree = vm.$children[0];
const nodeData = { id: 88, label: '88' };
tree.insertAfter(nodeData, tree.getNode(11));
expect(vm.data[0].children.length).to.equal(2);
expect(vm.data[0].children[1]).to.equal(nodeData);
expect(tree.getNode(88).data).to.equal(nodeData);
});
it('set disabled checkbox', done => {
vm = getDisableTreeVm(':props="defaultProps" show-checkbox node-key="id" default-expand-all');
const node = document.querySelectorAll('.el-tree-node__content')[2];
const nodeCheckbox = node.querySelector('.el-checkbox input');
vm.$nextTick(() => {
expect(nodeCheckbox.disabled).to.equal(true);
done();
});
});
it('check strictly', (done) => {
vm = getTreeVm(':props="defaultProps" show-checkbox check-strictly default-expand-all');
const tree = vm.$children[0];
const secondNode = document.querySelectorAll('.el-tree-node__content')[3];
const nodeCheckbox = secondNode.querySelector('.el-checkbox');
nodeCheckbox.click();
expect(tree.getCheckedNodes().length).to.equal(1);
expect(tree.getCheckedNodes(true).length).to.equal(0);
const firstLeaf = secondNode.nextElementSibling.querySelector('.el-tree-node__content');
const leafCheckbox = firstLeaf.querySelector('.el-checkbox');
vm.$nextTick(() => {
leafCheckbox.click();
expect(tree.getCheckedNodes().length).to.equal(2);
done();
});
});
it('render content', () => {
vm = getTreeVm(':props="defaultProps" :render-content="renderContent"', {
methods: {
renderContent(h, node) {
return (
<span class="custom-content">
<el-button>{ node.node.label }</el-button>
</span>
);
}
}
});
const firstNode = document.querySelector('.el-tree-node__content');
expect(firstNode.querySelector('.custom-content')).to.exist;
const button = firstNode.querySelector('.custom-content .el-button');
expect(button).to.exist;
expect(button.querySelector('span').textContent).to.equal('一级 1');
});
it('scoped slot', () => {
vm = createVue({
template: `
<el-tree ref="tree" :data="data">
<div slot-scope="scope" class="custom-tree-template">
<span>{{ scope.node.label }}</span>
<el-button></el-button>
</div>
</el-tree>
`,
data() {
return {
data: [{
id: 1,
label: '一级 1',
children: [{
id: 11,
label: '二级 1-1',
children: [{
id: 111,
label: '三级 1-1'
}]
}]
}, {
id: 2,
label: '一级 2',
children: [{
id: 21,
label: '二级 2-1'
}, {
id: 22,
label: '二级 2-2'
}]
}, {
id: 3,
label: '一级 3',
children: [{
id: 31,
label: '二级 3-1'
}, {
id: 32,
label: '二级 3-2'
}]
}]
};
}
}, true);
const firstNode = document.querySelector('.custom-tree-template');
expect(firstNode).to.exist;
const span = firstNode.querySelector('span');
const button = firstNode.querySelector('.el-button');
expect(span).to.exist;
expect(span.innerText).to.equal('一级 1');
expect(button).to.exist;
});
it('load node', done => {
vm = getTreeVm(':props="defaultProps" lazy :load="loadNode" show-checkbox', {
methods: {
loadNode(node, resolve) {
if (node.level === 0) {
return resolve([{ label: 'region1' }, { label: 'region2' }]);
}
if (node.level > 4) return resolve([]);
setTimeout(() => {
resolve([{
label: 'zone' + this.count++
}, {
label: 'zone' + this.count++
}]);
}, 50);
}
}
});
const nodes = document.querySelectorAll('.el-tree-node__content');
expect(nodes.length).to.equal(2);
nodes[0].click();
setTimeout(() => {
expect(document.querySelectorAll('.el-tree-node__content').length).to.equal(4);
done();
}, 100);
});
it('lazy defaultChecked', done => {
vm = getTreeVm(':props="defaultProps" node-key="id" lazy :load="loadNode" show-checkbox', {
methods: {
loadNode(node, resolve) {
if (node.level === 0) {
return resolve([{ label: 'region1', id: this.count++ }, { label: 'region2', id: this.count++ }]);
}
if (node.level > 4) return resolve([]);
setTimeout(() => {
resolve([{
label: 'zone' + this.count,
id: this.count++
}, {
label: 'zone' + this.count,
id: this.count++
}]);
}, 50);
}
}
});
const tree = vm.$children[0];
const firstNode = document.querySelector('.el-tree-node__content');
const initStatus = firstNode.querySelector('.is-indeterminate');
expect(initStatus).to.equal(null);
tree.store.setCheckedKeys([3]);
firstNode.querySelector('.el-tree-node__expand-icon').click();
setTimeout(() => {
const clickStatus = firstNode.querySelector('.is-indeterminate');
expect(clickStatus).to.not.equal(null);
const child = document.querySelectorAll('.el-tree-node__content')[1];
expect(child.querySelector('input').checked).to.equal(true);
done();
}, 300);
});
it('lazy expandOnChecked', done => {
vm = getTreeVm(':props="defaultProps" node-key="id" lazy :load="loadNode" show-checkbox check-descendants', {
methods: {
loadNode(node, resolve) {
if (node.level === 0) {
return resolve([{ label: 'region1', id: this.count++ }, { label: 'region2', id: this.count++ }]);
}
if (node.level > 2) return resolve([]);
setTimeout(() => {
resolve([{
label: 'zone' + this.count,
id: this.count++
}, {
label: 'zone' + this.count,
id: this.count++
}]);
}, 10);
}
}
});
const tree = vm.$children[0];
tree.store.setCheckedKeys([1]);
setTimeout(() => {
const checkedKeys = tree.getCheckedKeys();
expect(checkedKeys.length).to.equal(7);
done();
}, 400);
});
it('lazy without expandOnChecked', done => {
vm = getTreeVm(':props="defaultProps" node-key="id" lazy :load="loadNode" show-checkbox', {
methods: {
loadNode(node, resolve) {
if (node.level === 0) {
return resolve([{ label: 'region1', id: this.count++ }, { label: 'region2', id: this.count++ }]);
}
if (node.level > 4) return resolve([]);
setTimeout(() => {
resolve([{
label: 'zone' + this.count,
id: this.count++
}, {
label: 'zone' + this.count,
id: this.count++
}]);
}, 50);
}
}
});
const tree = vm.$children[0];
tree.store.setCheckedKeys([1]);
setTimeout(() => {
const nodes = document.querySelectorAll('.el-tree-node__content');
expect(nodes[0].querySelector('input').checked).to.equal(true);
expect(nodes.length).to.equal(2);
done();
}, 300);
});
it('accordion', done => {
vm = getTreeVm(':props="defaultProps" accordion');
const firstNode = vm.$el.querySelector('.el-tree-node__content');
const secondNode = vm.$el.querySelector('.el-tree-node:nth-child(2) .el-tree-node__content');
firstNode.click();
setTimeout(() => {
expect(vm.$el.querySelector('.el-tree-node').classList.contains('is-expanded')).to.true;
secondNode.click();
setTimeout(() => {
expect(vm.$el.querySelector('.el-tree-node').classList.contains('is-expanded')).to.false;
done();
}, DELAY);
}, DELAY);
});
it('handleNodeOpen & handleNodeClose', (done) => {
vm = getTreeVm(':props="defaultProps" lazy :load="loadNode" @node-expand="handleNodeOpen" @node-collapse="handleNodeClose"', {
methods: {
loadNode(node, resolve) {
if (node.level === 0) {
return resolve([{label: 'region1'}, {label: 'region2'}]);
}
if (node.level > 4) return resolve([]);
setTimeout(() => {
resolve([{
label: 'zone' + this.count++
}, {
label: 'zone' + this.count++
}]);
}, 50);
},
handleNodeOpen(data, node, vm) {
this.currentNode = data;
this.nodeExpended = true;
},
handleNodeClose(data, node, vm) {
this.currentNode = data;
this.nodeExpended = false;
}
}
});
const firstNode = document.querySelector('.el-tree-node__content');
expect(firstNode.nextElementSibling).to.not.exist;
firstNode.click();
setTimeout(() => {
expect(vm.nodeExpended).to.equal(true);
expect(vm.currentNode.label).to.equal('region1');
firstNode.click();
setTimeout(() => {
expect(vm.nodeExpended).to.equal(false);
expect(vm.currentNode.label).to.equal('region1');
done();
}, 100);
}, 100);
});
it('updateKeyChildren', (done) => {
vm = getTreeVm(':props="defaultProps" show-checkbox node-key="id" default-expand-all');
const tree = vm.$children[0];
tree.updateKeyChildren(1, [{
id: 111,
label: '三级 1-1'
}]);
const node = document.querySelectorAll('.el-tree-node__content')[2];
const label = node.querySelector('.el-tree-node__label');
vm.$nextTick(() => {
expect(tree.store.nodesMap['11']).to.equal(undefined);
expect(tree.store.nodesMap['1'].childNodes[0].data.id).to.equal(111);
expect(label.textContent).to.equal('三级 1-1');
done();
});
});
it('update multi tree data', async() => {
const vm = createVue({
template: `
<div>
<el-tree ref="tree1" :data="data" node-key="id" :props="defaultProps"></el-tree>
<el-tree ref="tree2" :data="data" node-key="id" :props="defaultProps"></el-tree>
</div>
`,
data() {
return {
data: [{
id: 1,
label: '一级 1',
children: [{
id: 11,
label: '二级 1-1',
children: [{
id: 111,
label: '三级 1-1'
}]
}]
}, {
id: 2,
label: '一级 2',
children: [{
id: 21,
label: '二级 2-1'
}, {
id: 22,
label: '二级 2-2'
}]
}, {
id: 3,
label: '一级 3',
children: [{
id: 31,
label: '二级 3-1'
}, {
id: 32,
label: '二级 3-2'
}]
}],
defaultProps: {
children: 'children',
label: 'label'
}
};
}
}, true);
const nodeData = { label: '新增 1', id: 4 };
vm.data.push(nodeData);
await wait();
const tree1 = vm.$refs.tree1;
expect(tree1.getNode(4).data).to.equal(nodeData);
const tree2 = vm.$refs.tree2;
expect(tree2.getNode(4).data).to.equal(nodeData);
});
});

View File

@@ -0,0 +1,317 @@
import { createVue, destroyVM } from '../util.js';
import ajax from 'packages/upload/src/ajax';
const noop = () => {};
const option = {
onSuccess: noop,
onProgress: noop,
data: { a: 'abc', b: 'bcd' },
filename: 'file.png',
file: new File([JSON.stringify('foo')], {type: 'image/png'}),
action: '/upload',
headers: { region: 'shanghai' }
};
let requests, xhr;
describe('ajax', () => {
beforeEach(() => {
xhr = sinon.useFakeXMLHttpRequest();
requests = [];
xhr.onCreate = req => requests.push(req);
option.onError = noop;
option.onSuccess = noop;
});
afterEach(() => {
xhr.restore();
});
it('request success', done => {
option.onError = done;
option.onSuccess = ret => {
expect(ret).to.eql({ success: true });
done();
};
ajax(option);
requests[0].respond(200, {}, '{"success": true}');
});
it('request width header', done => {
ajax(option);
expect(requests[0].requestHeaders).to.eql({
region: 'shanghai'
});
done();
});
it('40x code should be error', done => {
option.onError = e => {
expect(e.toString()).to.contain('Not found');
done();
};
option.onSuccess = () => done('404 should throw error');
ajax(option);
requests[0].respond(404, {}, 'Not found');
});
it('2xx code should be success', done => {
option.onError = done;
option.onSuccess = ret => {
expect(ret).to.equal('');
done();
};
ajax(option);
requests[0].respond(204, {});
});
});
describe('Upload', () => {
let requests;
let xhr;
beforeEach(() => {
xhr = sinon.useFakeXMLHttpRequest();
requests = [];
xhr.onCreate = req => requests.push(req);
});
afterEach(() => {
xhr.restore();
});
describe('ajax upload', () => {
let uploader;
let handlers = {};
const props = {
props: {
action: '/upload',
onSuccess(res, file, fileList) {
if (handlers.onSuccess) {
handlers.onSuccess(res, file, fileList);
}
},
onError(err, file, fileList) {
if (handlers.onError) {
handlers.onError(err, file, fileList);
}
},
onPreview(file) {
if (handlers.onPreview) {
handlers.onPreview(file);
}
},
limit: 2,
onExceed(files, fileList) {
if (handlers.onExceed) {
handlers.onExceed(files, fileList);
}
},
beforeUpload(file) {
if (handlers.beforeUpload) {
return handlers.beforeUpload(file);
} else {
return true;
}
},
beforeRemove(file, fileList) {
if (handlers.beforeRemove) {
return handlers.beforeRemove(file);
} else {
return true;
}
}
}
};
beforeEach(() => {
uploader = createVue({
render(h) {
return (
<el-upload {...props} ref="upload">
<el-button size="small" type="primary">点击上传</el-button>
</el-upload>
);
}
}, true).$refs.upload;
});
afterEach(() => {
destroyVM(uploader);
handlers = {};
});
it('upload success', done => {
const file = new Blob([JSON.stringify({}, null, 2)], {
type: 'application/json'
});
file.name = 'success.png';
const files = [file];
handlers.onSuccess = (res, file, fileList) => {
expect(file.name).to.equal('success.png');
expect(fileList.length).to.equal(1);
expect(res).to.equal('success.png');
done();
};
uploader.$refs['upload-inner'].handleChange({ target: { files }});
setTimeout(() => {
requests[0].respond(200, {}, `${files[0].name}`);
}, 100);
});
it('upload fail', done => {
const file = new Blob([JSON.stringify({}, null, 2)], {
type: 'application/json'
});
file.name = 'fail.png';
const files = [file];
handlers.onError = (err, file, fileList) => {
expect(err instanceof Error).to.equal(true);
expect(file.name).to.equal('fail.png');
done();
};
uploader.$refs['upload-inner'].handleChange({ target: { files }});
setTimeout(() => {
requests[0].respond(400, {}, 'error 400');
}, 100);
});
it('preview file', done => {
const file = new Blob([JSON.stringify({}, null, 2)], {
type: 'application/json'
});
file.name = 'success.png';
const files = [file];
handlers.onPreview = (file) => {
expect(file.response).to.equal('success.png');
done();
};
handlers.onSuccess = (res, file, fileList) => {
uploader.$nextTick(_ => {
uploader.$el.querySelector('.el-upload-list .is-success a').click();
});
};
uploader.$refs['upload-inner'].handleChange({ target: { files }});
setTimeout(() => {
requests[0].respond(200, {}, `${files[0].name}`);
}, 100);
});
it('file remove', done => {
const file = new Blob([JSON.stringify({}, null, 2)], {
type: 'application/json'
});
file.name = 'success.png';
const files = [file];
handlers.onSuccess = (res, file, fileList) => {
uploader.$el.querySelector('.el-upload-list .el-icon-close').click();
uploader.$nextTick(_ => {
expect(uploader.fileList.length).to.equal(0);
done();
});
};
uploader.$refs['upload-inner'].handleChange({ target: { files }});
setTimeout(() => {
requests[0].respond(200, {}, `${files[0].name}`);
}, 100);
});
it('clear files', done => {
const file = new Blob([JSON.stringify({}, null, 2)], {
type: 'application/json'
});
file.name = 'success.png';
const files = [file];
handlers.onSuccess = (res, file, fileList) => {
uploader.clearFiles();
uploader.$nextTick(_ => {
expect(uploader.fileList.length).to.equal(0);
done();
});
};
uploader.$refs['upload-inner'].handleChange({ target: { files }});
setTimeout(() => {
requests[0].respond(200, {}, `${files[0].name}`);
}, 100);
});
it('beforeUpload return promise', done => {
const spy = sinon.spy();
const file = new Blob([JSON.stringify({}, null, 2)], {
type: 'application/json'
});
const files = [file];
handlers.onSuccess = () => {
expect(spy.calledOnce).to.equal(true);
done();
};
handlers.beforeUpload = (file) => {
return new window.Promise((resolve) => {
spy();
resolve(file);
});
};
uploader.$refs['upload-inner'].handleChange({ target: { files }});
setTimeout(() => {
requests[0].respond(200, {}, `${files[0].name}`);
}, 100);
});
it('beforeRemove return rejected promise', done => {
const spy = sinon.spy();
handlers.beforeRemove = (file) => {
return new window.Promise((resolve, reject) => {
spy();
reject();
});
};
const file = new Blob([JSON.stringify({}, null, 2)], {
type: 'application/json'
});
file.name = 'success.png';
const files = [file];
handlers.onSuccess = (res, file, fileList) => {
uploader.$el.querySelector('.el-upload-list .el-icon-close').click();
setTimeout(() => {
expect(spy.calledOnce).to.equal(true);
expect(uploader.uploadFiles.length).to.equal(1);
done();
}, 200);
};
uploader.$refs['upload-inner'].handleChange({ target: { files }});
setTimeout(() => {
requests[0].respond(200, {}, `${files[0].name}`);
}, 100);
});
it('limit files', done => {
const files = [{
name: 'exceed2.png',
type: 'xml'
}, {
name: 'exceed3.png',
type: 'xml'
}];
uploader.uploadFiles = [{
name: 'exceed1.png',
type: 'xml'
}];
handlers.onExceed = (files, fileList) => {
uploader.$nextTick(_ => {
expect(uploader.uploadFiles.length).to.equal(1);
done();
});
};
uploader.$nextTick(_ => uploader.$refs['upload-inner'].handleChange({ target: { files }}));
});
});
});

View File

@@ -0,0 +1,170 @@
import Clickoutside from 'element-ui/src/utils/clickoutside';
const ctx = '@@clickoutsideContext';
import { triggerEvent, triggerClick } from '../util';
describe('Utils:Clickoutside', () => {
it('create', () => {
let count = 0;
const el = document.createElement('div');
const vnode = {
context: {
handleClick: () => ++count
}
};
const binding = {
expression: 'handleClick'
};
Clickoutside.bind(el, binding, vnode);
expect(el[ctx]).to.exist;
});
it('cotext not exist', () => {
const el = document.createElement('div');
const vnode = {};
const binding = {
expression: 'handleClick'
};
Clickoutside.bind(el, binding, vnode);
expect(el[ctx]).to.exist;
});
it('binding expression', () => {
const el = document.createElement('div');
let count = 0;
const vnode = {
context: {
handleClick: () => ++count
}
};
const binding = {
expression: 'handleClick'
};
Clickoutside.bind(el, binding, vnode);
triggerClick(document);
expect(count).to.equal(1);
});
it('click inside', () => {
const el = document.createElement('div');
const insideElm = document.createElement('div');
let count = 0;
const vnode = {
context: {
handleClick: () => ++count
}
};
const binding = {
expression: 'handleClick'
};
el.appendChild(insideElm);
Clickoutside.bind(el, binding, vnode);
triggerClick(insideElm);
expect(count).to.equal(0);
triggerClick(document);
expect(count).to.equal(1);
});
it('tigger event in popperElm', () => {
const el = document.createElement('div');
const insideElm = document.createElement('div');
let count = 0;
const vnode = {
context: {
handleClick: () => ++count,
popperElm: document.createElement('div')
}
};
const binding = {
expression: 'handleClick'
};
vnode.context.popperElm.appendChild(insideElm);
Clickoutside.bind(el, binding, vnode);
triggerClick(insideElm);
expect(count).to.equal(0);
triggerClick(document);
expect(count).to.equal(1);
});
it('binding value', () => {
const el = document.createElement('div');
let count = 0;
const vnode = {
context: {}
};
const binding = {
value: () => ++count
};
Clickoutside.bind(el, binding, vnode);
expect(count).to.equal(0);
triggerClick(document);
expect(count).to.equal(1);
});
it('update', () => {
let count = 0;
const el = document.createElement('div');
const vnode = {
context: {
abc: () => ++count,
ddd: () => ++count
}
};
const binding = {
expression: 'abc'
};
const newBinding = {
expression: 'ddd'
};
Clickoutside.bind(el, binding, vnode);
expect(el[ctx].methodName).to.equal('abc');
Clickoutside.update(el, newBinding);
expect(el[ctx].methodName).to.equal('ddd');
});
it('unbind', () => {
const el = document.createElement('div');
let count = 0;
const vnode = {
context: {}
};
const binding = {
value: () => ++count
};
Clickoutside.bind(el, binding, vnode);
triggerClick(document);
Clickoutside.unbind(el);
triggerClick(document);
expect(count).to.equal(1);
});
it('stays open on drag click', () => {
const el = document.createElement('div');
const insideElm = document.createElement('div');
let count = 0;
const vnode = {
context: {
handleClick: () => ++count
}
};
const binding = {
expression: 'handleClick'
};
el.appendChild(insideElm);
Clickoutside.bind(el, binding, vnode);
triggerEvent(insideElm, 'mousedown');
triggerEvent(document, 'mouseup');
expect(count).to.equal(1);
});
});

View File

@@ -0,0 +1,179 @@
import VuePopper from 'element-ui/src/utils/vue-popper';
import { createTest } from '../util';
const Popper = Object.assign({}, VuePopper, {
render(h) {
return h('div');
},
created() {
this.popperElm = document.createElement('div');
this.referenceElm = document.createElement('div');
}
});
const CleanPopper = Object.assign({}, VuePopper, {
render(h) {
return h('div');
}
});
describe('Utils:VuePopper', () => {
it('set popper not reference', () => {
const vm = createTest(CleanPopper, {
popper: document.createElement('div')
});
vm.createPopper();
expect(vm.popperElm).to.exist;
expect(vm.referenceElm).to.not.exist;
expect(vm.popperJS).to.not.exist;
});
it('set reference not popper', () => {
const vm = createTest(CleanPopper, {
reference: document.createElement('div')
});
vm.createPopper();
expect(vm.referenceElm).to.exist;
expect(vm.popperElm).to.not.exist;
expect(vm.popperJS).to.not.exist;
});
it('set reference by slot', () => {
const vm = createTest(CleanPopper);
vm.$slots['reference'] = [{
elm: document.createElement('div')
}];
vm.createPopper();
expect(vm.referenceElm).to.exist;
expect(vm.popperElm).to.not.exist;
expect(vm.popperJS).to.not.exist;
});
it('createPopper', () => {
const vm = createTest(Popper, { placement: 'top' });
vm.createPopper();
expect(vm.popperJS._popper.getAttribute('x-placement')).to.equal('top');
});
it('destroy popper when calling createPopper twice', () => {
const vm = createTest(Popper);
vm.createPopper();
const popperJS = vm.popperJS;
expect(vm.popperJS).to.exist;
expect(vm.popperJS).to.equal(popperJS);
vm.createPopper();
expect(vm.popperJS).to.not.equal(popperJS);
});
it('updatePopper', () => {
const vm = createTest(Popper);
vm.updatePopper();
const popperJS = vm.popperJS;
expect(vm.popperJS).to.exist;
vm.updatePopper();
expect(vm.popperJS).to.equal(popperJS);
});
it('doDestroy', () => {
const vm = createTest(Popper, { placement: 'top' });
vm.createPopper();
expect(vm.popperJS._popper.getAttribute('x-placement')).to.equal('top');
vm.doDestroy();
expect(vm.popperJS).to.not.exist;
});
it('destroyPopper', () => {
const vm = createTest(Popper);
const vm2 = createTest(Popper);
vm.createPopper();
expect(() => vm.destroyPopper()).to.not.throw();
expect(() => vm2.destroyPopper()).to.not.throw();
});
it('placement', () => {
const vm = createTest(Popper, { placement: 'bottom-start' });
const vm2 = createTest(Popper, { placement: 'bottom-abc' });
vm.createPopper();
vm2.createPopper();
expect(vm.popperJS._popper.getAttribute('x-placement')).to.equal('bottom-start');
expect(vm2.popperJS).to.not.exist;
});
it('display arrow', () => {
const vm = createTest(Popper, {
visibleArrow: true
});
vm.createPopper();
expect(vm.popperJS._popper.querySelector('div[x-arrow]')).to.exist;
});
it('update showPopper', done => {
const vm = createTest(Popper);
expect(vm.popperJS).to.not.exist;
vm.showPopper = true;
setTimeout(_ => {
expect(vm.popperJS).to.exist;
vm.showPopper = false;
setTimeout(_ => {
expect(vm.popperJS).to.exist;
}, 50);
done();
}, 50);
});
it('resetTransformOrigin', () => {
const vm = createTest(Popper, {
placement: 'left'
});
vm.createPopper();
expect(vm.popperJS._popper.style.transformOrigin).to.include('right center');
});
it('appendArrow', () => {
const vm = createTest(Popper, {
visibleArrow: true
});
expect(vm.appended).to.be.undefined;
vm.createPopper();
expect(vm.appended).to.true;
vm.appendArrow();
expect(vm.popperJS._popper.querySelector('[x-arrow]')).to.exist;
expect(vm.appended).to.true;
});
it('appendArrow: add scoped', () => {
const popper = document.createElement('div');
popper.setAttribute('_v-110', true);
const vm = createTest(CleanPopper, {
reference: document.createElement('div'),
visibleArrow: true,
popper
});
expect(vm.appended).to.be.undefined;
vm.createPopper();
expect(vm.popperJS._popper.querySelector('[x-arrow][_v-110]')).to.exist;
});
it('appendToBody set false', () => {
const vm = createTest(Popper, {
appendToBody: false
});
vm.createPopper();
expect(document.body.contains(vm.popperElm)).to.false;
});
it('destroy', () => {
const vm = createTest(Popper, true);
vm.createPopper();
expect(document.body.contains(vm.popperElm)).to.true;
vm.$destroy();
expect(document.body.contains(vm.popperElm)).to.false;
});
});

121
test/unit/util.js Normal file
View File

@@ -0,0 +1,121 @@
import Vue from 'vue';
import Element from 'main/index.js';
Vue.use(Element);
let id = 0;
const createElm = function() {
const elm = document.createElement('div');
elm.id = 'app' + ++id;
document.body.appendChild(elm);
return elm;
};
/**
* 回收 vm
* @param {Object} vm
*/
export const destroyVM = function(vm) {
vm.$destroy && vm.$destroy();
vm.$el &&
vm.$el.parentNode &&
vm.$el.parentNode.removeChild(vm.$el);
};
/**
* 创建一个 Vue 的实例对象
* @param {Object|String} Compo 组件配置,可直接传 template
* @param {Boolean=false} mounted 是否添加到 DOM 上
* @return {Object} vm
*/
export const createVue = function(Compo, mounted = false) {
if (Object.prototype.toString.call(Compo) === '[object String]') {
Compo = { template: Compo };
}
return new Vue(Compo).$mount(mounted === false ? null : createElm());
};
/**
* 创建一个测试组件实例
* @link http://vuejs.org/guide/unit-testing.html#Writing-Testable-Components
* @param {Object} Compo - 组件对象
* @param {Object} propsData - props 数据
* @param {Boolean=false} mounted - 是否添加到 DOM 上
* @return {Object} vm
*/
export const createTest = function(Compo, propsData = {}, mounted = false) {
if (propsData === true || propsData === false) {
mounted = propsData;
propsData = {};
}
const elm = createElm();
const Ctor = Vue.extend(Compo);
return new Ctor({ propsData }).$mount(mounted === false ? null : elm);
};
/**
* 触发一个事件
* mouseenter, mouseleave, mouseover, keyup, change, click 等
* @param {Element} elm
* @param {String} name
* @param {*} opts
*/
export const triggerEvent = function(elm, name, ...opts) {
let eventName;
if (/^mouse|click/.test(name)) {
eventName = 'MouseEvents';
} else if (/^key/.test(name)) {
eventName = 'KeyboardEvent';
} else {
eventName = 'HTMLEvents';
}
const evt = document.createEvent(eventName);
evt.initEvent(name, ...opts);
elm.dispatchEvent
? elm.dispatchEvent(evt)
: elm.fireEvent('on' + name, evt);
return elm;
};
/**
* 触发 “mouseup” 和 “mousedown” 事件
* @param {Element} elm
* @param {*} opts
*/
export const triggerClick = function(elm, ...opts) {
triggerEvent(elm, 'mousedown', ...opts);
triggerEvent(elm, 'mouseup', ...opts);
return elm;
};
/**
* 触发 keydown 事件
* @param {Element} elm
* @param {keyCode} int
*/
export const triggerKeyDown = function(el, keyCode) {
const evt = document.createEvent('Events');
evt.initEvent('keydown', true, true);
evt.keyCode = keyCode;
el.dispatchEvent(evt);
};
/**
* 等待 ms 毫秒,返回 Promise
* @param {Number} ms
*/
export const wait = function(ms = 50) {
return new Promise(resolve => setTimeout(() => resolve(), ms));
};
/**
* 等待一个 Tick代替 Vue.nextTick返回 Promise
*/
export const waitImmediate = () => wait(0);