import {createVue, destroyVM, waitForIt, promissedTick} from '../util';
describe('Select.vue', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
describe('Props tests', () => {
it('should create a Select component with passed placeholder', done => {
const placeholder = 'Hi! Select something!';
vm = createVue({
template: `
`,
data() {
return {
value: '',
options: [{value: 1, label: 'Foo'}, {value: 2, label: 'Bar'}]
};
}
});
vm.$nextTick(() => {
const placeholderSpan = vm.$el.querySelector('.ivu-select-placeholder');
expect(placeholderSpan.textContent).to.equal(placeholder);
expect(placeholderSpan.style.display).to.not.equal('none');
done();
});
});
it('should create a Select component and take a pre-selected value', done => {
vm = createVue({
template: `
`,
data() {
return {
value: 2,
options: [{value: 1, label: 'Foo'}, {value: 2, label: 'Bar'}]
};
}
});
waitForIt(
() => {
const selectedValueSpan = vm.$el.querySelector('.ivu-select-selected-value');
return selectedValueSpan.textContent === 'Bar';
},
() => {
const selectedValueSpan = vm.$el.querySelector('.ivu-select-selected-value');
const {label, value} = vm.$children[0].values[0];
expect(selectedValueSpan.textContent).to.equal('Bar');
expect(selectedValueSpan.style.display).to.not.equal('none');
expect(label).to.equal('Bar');
expect(value).to.equal(2);
done();
}
);
});
it('should accept normal characters', done => {
vm = createVue({
template: `
`,
data() {
return {
value: '',
options: [{value: 1, label: '> 100$'}, {value: 2, label: '< 100$'}]
};
}
});
vm.$nextTick(() => {
const selectedValueSpan = vm.$el.querySelector('.ivu-select-selected-value');
expect(selectedValueSpan.textContent).to.equal('< 100$');
done();
});
});
it('should display normal characters in input when in filterable mode', done => {
vm = createVue({
template: `
`,
data() {
return {
value: 2,
options: [{value: 1, label: '> 100$'}, {value: 2, label: '< 100$'}]
};
}
});
vm.$nextTick(() => {
const input = vm.$el.querySelector('.ivu-select-input');
expect(input.value).to.equal('< 100$');
done();
});
});
it('should use the value\'s label instead of placeholder when both are set', done => {
vm = createVue({
template: `
`,
data() {
return {
value: '',
options: [{value: 1, label: 'Foo'}, {value: 2, label: 'Bar'}]
};
}
});
waitForIt(
() => {
const selectedValueSpan = vm.$el.querySelector('.ivu-select-selected-value');
return selectedValueSpan.textContent === 'Bar';
},
() => {
const placeholderSpan = vm.$el.querySelector('.ivu-select-placeholder');
const selectedValueSpan = vm.$el.querySelector('.ivu-select-selected-value');
expect(placeholderSpan).to.equal(null);
expect(!!selectedValueSpan.style.display).to.not.equal('none');
expect(selectedValueSpan.textContent).to.equal('Bar');
done();
}
);
});
it('should set different classes for different sizes', done => {
vm = createVue(`
`);
vm.$nextTick(() => {
const [defaultSelect, largeSelect, smallSelect] = [...vm.$el.querySelectorAll('.ivu-select')];
expect(defaultSelect.className).to.equal('ivu-select ivu-select-single');
expect(largeSelect.classList.contains('ivu-select-large')).to.equal(true);
expect(smallSelect.classList.contains('ivu-select-small')).to.equal(true);
done();
});
});
it('should set new options', done => {
const laterOptions = [{value: 1, label: 'Foo'}, {value: 2, label: 'Bar'}];
vm = createVue({
template: `
`,
data() {
return {
value: '',
options: []
};
},
mounted() {
this.$nextTick(() => (this.options = laterOptions));
}
});
const condition = function() {
const componentOptions = vm.$children[0].flatOptions;
return componentOptions && componentOptions.length > 0;
};
const callback = function() {
const renderedOptions = vm.$el.querySelectorAll('.ivu-select-dropdown-list li');
expect(renderedOptions.length).to.equal(laterOptions.length);
const labels = [...renderedOptions].map(el => el.textContent).join('<>');
const expected = laterOptions.map(o => o.label).join('<>');
expect(labels).to.equal(expected);
done();
};
waitForIt(condition, callback);
});
});
describe('Behavior tests', () => {
it('should create different and independent instances', done => {
const options = [
{value: 'beijing', label: 'Beijing'},
{value: 'stockholm', label: 'Stockholm'},
{value: 'lisboa', label: 'Lisboa'}
];
vm = createVue({
template: `
{{ item.label }}
{{ item.label }}
`,
data() {
return {
cityList: [],
modelA: [],
modelB: []
};
},
mounted() {
setTimeout(() => (this.cityList = options), 200);
}
});
const [SelectA, SelectB] = vm.$children;
SelectA.toggleMenu(null, true);
SelectB.toggleMenu(null, true);
new Promise(resolve => {
const condition = function() {
const optionsA = SelectA.$el.querySelectorAll('.ivu-select-item');
const optionsB = SelectB.$el.querySelectorAll('.ivu-select-item');
return optionsA.length > 0 && optionsB.length > 0;
};
waitForIt(condition, resolve);
})
.then(() => {
// click in A options
const optionsA = SelectA.$el.querySelectorAll('.ivu-select-item');
optionsA[0].click();
return promissedTick(SelectA);
})
.then(() => {
expect(SelectA.value[0]).to.equal(options[0].value);
expect(SelectA.value.length).to.equal(1);
expect(SelectB.value.length).to.equal(0);
// click in B options
const optionsB = SelectB.$el.querySelectorAll('.ivu-select-item');
optionsB[1].click();
optionsB[2].click();
return promissedTick(SelectB);
})
.then(() => {
// lets check the values!
const getSelections = component => {
const tags = component.$el.querySelectorAll('.ivu-select-selection .ivu-tag');
return [...tags].map(el => el.textContent.trim()).join(',');
};
const selectAValue = getSelections(SelectA);
const selectBValue = getSelections(SelectB);
expect(selectAValue).to.equal(options[0].label);
expect(selectBValue).to.equal(options.slice(1, 3).map(obj => obj.label.trim()).join(','));
done();
}).catch(err => {
console.log(err);
done(false);
});
});
it('should create update model with value, and label when asked', done => {
const options = [
{value: 'beijing', label: 'Beijing'},
{value: 'stockholm', label: 'Stockholm'},
{value: 'lisboa', label: 'Lisboa'}
];
let onChangeValueA, onChangeValueB;
vm = createVue({
template: `
{{ item.label }}
{{ item.label }}
`,
data() {
return {
cityList: options,
modelA: [],
modelB: []
};
},
methods: {
onChangeA(val){
onChangeValueA = val;
},
onChangeB(val){
onChangeValueB = val;
}
}
});
const [SelectA, SelectB] = vm.$children;
SelectA.toggleMenu(null, true);
SelectB.toggleMenu(null, true);
new Promise(resolve => {
const condition = function() {
const optionsA = SelectA.$el.querySelectorAll('.ivu-select-item');
const optionsB = SelectB.$el.querySelectorAll('.ivu-select-item');
return optionsA.length > 0 && optionsB.length > 0;
};
waitForIt(condition, resolve);
})
.then(() => {
// click in A options
const optionsA = SelectA.$el.querySelectorAll('.ivu-select-item');
optionsA[0].click();
return promissedTick(SelectA);
})
.then(() => {
expect(vm.modelA).to.equal(options[0].value);
expect(onChangeValueA).to.equal(options[0].value);
// click in B options
const optionsB = SelectB.$el.querySelectorAll('.ivu-select-item');
optionsB[2].click();
return promissedTick(SelectB);
})
.then(() => {
expect(vm.modelB).to.equal(options[2].value);
expect(JSON.stringify(onChangeValueB)).to.equal(JSON.stringify(options[2]));
done();
});
});
});
describe('Public API', () => {
it('The "setQuery" method should behave as expected', (done) => {
const options = [
{value: 'beijing', label: 'Beijing'},
{value: 'stockholm', label: 'Stockholm'},
{value: 'lisboa', label: 'Lisboa'}
];
vm = createVue({
template: `
`,
data() {
return {
value: '',
options: options
};
}
});
const [Select] = vm.$children;
Select.setQuery('i');
vm.$nextTick(() => {
const query = 'i';
const input = vm.$el.querySelector('.ivu-select-input');
expect(input.value).to.equal(query);
const renderedOptions = [...vm.$el.querySelectorAll('.ivu-select-item')].map(el => el.textContent);
const filteredOptions = options.filter(option => JSON.stringify(option).includes(query)).map(({label}) => label);
expect(JSON.stringify(renderedOptions)).to.equal(JSON.stringify(filteredOptions));
// reset query
// setQuery(null) should clear the select
Select.setQuery(null);
vm.$nextTick(() => {
const input = vm.$el.querySelector('.ivu-select-input');
expect(input.value).to.equal('');
const renderedOptions = [...vm.$el.querySelectorAll('.ivu-select-item')].map(el => el.textContent);
expect(JSON.stringify(renderedOptions)).to.equal(JSON.stringify(options.map(({label}) => label)));
done();
});
});
});
it('The "clearSingleSelect" method should behave as expected', (done) => {
// clearSingleSelect
const options = [
{value: 'beijing', label: 'Beijing'},
{value: 'stockholm', label: 'Stockholm'},
{value: 'lisboa', label: 'Lisboa'}
];
const preSelected = 'lisboa';
vm = createVue({
template: `
`,
data() {
return {
value: preSelected,
options: options
};
}
});
const [Select] = vm.$children;
vm.$nextTick(() => {
expect(Select.publicValue).to.equal(preSelected);
Select.clearSingleSelect();
expect(typeof Select.publicValue).to.equal('undefined');
done();
});
});
});
describe('Performance tests', () => {
it('should handle big numbers of options', done => {
const manyLaterOptions = Array.apply(null, Array(200)).map((_, i) => {
return {
value: i + 1,
label: Math.random().toString(36).slice(2).toUpperCase()
};
});
const start = +new Date();
vm = createVue({
template: `
`,
data() {
return {
value: '',
options: []
};
},
mounted() {
this.$nextTick(() => (this.options = manyLaterOptions));
}
});
const condition = function() {
const componentOptions = vm.$children[0].flatOptions;
return componentOptions && componentOptions.length === manyLaterOptions.length;
};
const callback = function() {
const end = +new Date();
const renderedOptions = vm.$el.querySelectorAll('.ivu-select-dropdown-list li');
expect(renderedOptions.length).to.equal(manyLaterOptions.length);
expect(end - start).to.be.not.above(1000);
done();
};
waitForIt(condition, callback);
});
});
});