Commit afef4ce7f7870df129d29786cfaf64e9ab41c169

Authored by Sergio Crisostomo
1 parent c9b86944

Fix unit tests and add more tests

Showing 1 changed file with 269 additions and 102 deletions   Show diff stats
test/unit/specs/select.spec.js
@@ -26,34 +26,40 @@ describe('Select.vue', () => { @@ -26,34 +26,40 @@ describe('Select.vue', () => {
26 const placeholderSpan = vm.$el.querySelector('.ivu-select-placeholder'); 26 const placeholderSpan = vm.$el.querySelector('.ivu-select-placeholder');
27 expect(placeholderSpan.textContent).to.equal(placeholder); 27 expect(placeholderSpan.textContent).to.equal(placeholder);
28 expect(placeholderSpan.style.display).to.not.equal('none'); 28 expect(placeholderSpan.style.display).to.not.equal('none');
29 -  
30 - expect(vm.$children[0].showPlaceholder).to.equal(true);  
31 done(); 29 done();
32 }); 30 });
33 }); 31 });
34 32
35 it('should create a Select component and take a pre-selected value', done => { 33 it('should create a Select component and take a pre-selected value', done => {
36 vm = createVue({ 34 vm = createVue({
37 - template: `  
38 - <Select :value="2">  
39 - <Option v-for="item in options" :value="item.value" :key="item.value">{{ item.label }}</Option>  
40 - </Select>  
41 - `,  
42 - data() {  
43 - return {  
44 - value: '',  
45 - options: [{value: 1, label: 'Foo'}, {value: 2, label: 'Bar'}]  
46 - };  
47 - }  
48 - });  
49 - vm.$nextTick(() => {  
50 - const selectedValueSpan = vm.$el.querySelector('.ivu-select-selected-value');  
51 - expect(selectedValueSpan.textContent).to.equal('Bar');  
52 - expect(selectedValueSpan.style.display).to.not.equal('none');  
53 - expect(vm.$children[0].selectedSingle).to.equal('Bar');  
54 - expect(vm.$children[0].model).to.equal(2);  
55 - done(); 35 + template: `
  36 + <Select :value="value">
  37 + <Option v-for="item in options" :value="item.value" :key="item.value">{{ item.label }}</Option>
  38 + </Select>
  39 + `,
  40 + data() {
  41 + return {
  42 + value: 2,
  43 + options: [{value: 1, label: 'Foo'}, {value: 2, label: 'Bar'}]
  44 + };
  45 + }
56 }); 46 });
  47 + waitForIt(
  48 + () => {
  49 + const selectedValueSpan = vm.$el.querySelector('.ivu-select-selected-value');
  50 + return selectedValueSpan.textContent === 'Bar';
  51 + },
  52 + () => {
  53 + const selectedValueSpan = vm.$el.querySelector('.ivu-select-selected-value');
  54 + const {label, value} = vm.$children[0].values[0];
  55 +
  56 + expect(selectedValueSpan.textContent).to.equal('Bar');
  57 + expect(selectedValueSpan.style.display).to.not.equal('none');
  58 + expect(label).to.equal('Bar');
  59 + expect(value).to.equal(2);
  60 + done();
  61 + }
  62 + );
57 }); 63 });
58 64
59 it('should accept normal characters', done => { 65 it('should accept normal characters', done => {
@@ -112,13 +118,20 @@ describe(&#39;Select.vue&#39;, () =&gt; { @@ -112,13 +118,20 @@ describe(&#39;Select.vue&#39;, () =&gt; {
112 }; 118 };
113 } 119 }
114 }); 120 });
115 - vm.$nextTick(() => {  
116 - const placeholderSpan = vm.$el.querySelector('.ivu-select-placeholder');  
117 - const selectedValueSpan = vm.$el.querySelector('.ivu-select-selected-value');  
118 - expect(placeholderSpan.style.display).to.equal('none');  
119 - expect(selectedValueSpan.style.display).to.not.equal('none');  
120 - done();  
121 - }); 121 + waitForIt(
  122 + () => {
  123 + const selectedValueSpan = vm.$el.querySelector('.ivu-select-selected-value');
  124 + return selectedValueSpan.textContent === 'Bar';
  125 + },
  126 + () => {
  127 + const placeholderSpan = vm.$el.querySelector('.ivu-select-placeholder');
  128 + const selectedValueSpan = vm.$el.querySelector('.ivu-select-selected-value');
  129 + expect(placeholderSpan).to.equal(null);
  130 + expect(!!selectedValueSpan.style.display).to.not.equal('none');
  131 + expect(selectedValueSpan.textContent).to.equal('Bar');
  132 + done();
  133 + }
  134 + );
122 }); 135 });
123 136
124 it('should set different classes for different sizes', done => { 137 it('should set different classes for different sizes', done => {
@@ -158,12 +171,10 @@ describe(&#39;Select.vue&#39;, () =&gt; { @@ -158,12 +171,10 @@ describe(&#39;Select.vue&#39;, () =&gt; {
158 } 171 }
159 }); 172 });
160 const condition = function() { 173 const condition = function() {
161 - return vm.$children[0].options.length > 0; 174 + const componentOptions = vm.$children[0].flatOptions;
  175 + return componentOptions && componentOptions.length > 0;
162 }; 176 };
163 const callback = function() { 177 const callback = function() {
164 - if (vm.$children[0].options == 0) return setTimeout(waitForIt.bind(null, done), 50);  
165 - expect(JSON.stringify(vm.$children[0].options)).to.equal(JSON.stringify(laterOptions));  
166 -  
167 const renderedOptions = vm.$el.querySelectorAll('.ivu-select-dropdown-list li'); 178 const renderedOptions = vm.$el.querySelectorAll('.ivu-select-dropdown-list li');
168 expect(renderedOptions.length).to.equal(laterOptions.length); 179 expect(renderedOptions.length).to.equal(laterOptions.length);
169 180
@@ -177,79 +188,234 @@ describe(&#39;Select.vue&#39;, () =&gt; { @@ -177,79 +188,234 @@ describe(&#39;Select.vue&#39;, () =&gt; {
177 }); 188 });
178 189
179 describe('Behavior tests', () => { 190 describe('Behavior tests', () => {
180 - it('should create different and independent instances', done => {  
181 - const options = [  
182 - {value: 'beijing', label: 'Beijing'},  
183 - {value: 'stockholm', label: 'Stockholm'},  
184 - {value: 'lisboa', label: 'Lisboa'}  
185 - ]; 191 + it('should create different and independent instances', done => {
  192 + const options = [
  193 + {value: 'beijing', label: 'Beijing'},
  194 + {value: 'stockholm', label: 'Stockholm'},
  195 + {value: 'lisboa', label: 'Lisboa'}
  196 + ];
186 197
187 - vm = createVue({  
188 - template: `  
189 - <div>  
190 - <i-select v-model="modelA" multiple style="width:260px">  
191 - <i-option v-for="item in cityList" :value="item.value" :key="item.value">{{ item.label }}</i-option>  
192 - </i-select>  
193 - <i-select v-model="modelB" multiple style="width:260px">  
194 - <i-option v-for="item in cityList" :value="item.value" :key="item.value">{{ item.label }}</i-option>  
195 - </i-select>  
196 - </div>  
197 - `,  
198 - data() {  
199 - return {  
200 - cityList: [],  
201 - modelA: [],  
202 - modelB: []  
203 - };  
204 - },  
205 - mounted() {  
206 - setTimeout(() => (this.cityList = options), 200);  
207 - } 198 + vm = createVue({
  199 + template: `
  200 + <div>
  201 + <i-select v-model="modelA" multiple style="width:260px">
  202 + <i-option v-for="item in cityList" :value="item.value" :key="item.value">{{ item.label }}</i-option>
  203 + </i-select>
  204 + <i-select v-model="modelB" multiple style="width:260px">
  205 + <i-option v-for="item in cityList" :value="item.value" :key="item.value">{{ item.label }}</i-option>
  206 + </i-select>
  207 + </div>
  208 + `,
  209 + data() {
  210 + return {
  211 + cityList: [],
  212 + modelA: [],
  213 + modelB: []
  214 + };
  215 + },
  216 + mounted() {
  217 + setTimeout(() => (this.cityList = options), 200);
  218 + }
  219 + });
  220 + const [SelectA, SelectB] = vm.$children;
  221 + SelectA.toggleMenu(null, true);
  222 + SelectB.toggleMenu(null, true);
  223 +
  224 + new Promise(resolve => {
  225 + const condition = function() {
  226 + const optionsA = SelectA.$el.querySelectorAll('.ivu-select-item');
  227 + const optionsB = SelectB.$el.querySelectorAll('.ivu-select-item');
  228 + return optionsA.length > 0 && optionsB.length > 0;
  229 + };
  230 + waitForIt(condition, resolve);
  231 + })
  232 + .then(() => {
  233 + // click in A options
  234 + const optionsA = SelectA.$el.querySelectorAll('.ivu-select-item');
  235 + optionsA[0].click();
  236 + return promissedTick(SelectA);
  237 + })
  238 + .then(() => {
  239 + expect(SelectA.value[0]).to.equal(options[0].value);
  240 + expect(SelectA.value.length).to.equal(1);
  241 + expect(SelectB.value.length).to.equal(0);
  242 +
  243 + // click in B options
  244 + const optionsB = SelectB.$el.querySelectorAll('.ivu-select-item');
  245 + optionsB[1].click();
  246 + optionsB[2].click();
  247 + return promissedTick(SelectB);
  248 + })
  249 + .then(() => {
  250 + // lets check the values!
  251 + const getSelections = component => {
  252 + const tags = component.$el.querySelectorAll('.ivu-select-selection .ivu-tag');
  253 + return [...tags].map(el => el.textContent.trim()).join(',');
  254 + };
  255 + const selectAValue = getSelections(SelectA);
  256 + const selectBValue = getSelections(SelectB);
  257 +
  258 + expect(selectAValue).to.equal(options[0].label);
  259 + expect(selectBValue).to.equal(options.slice(1, 3).map(obj => obj.label.trim()).join(','));
  260 +
  261 + done();
  262 + }).catch(err => {
  263 + console.log(err);
  264 + done(false);
  265 + });
208 }); 266 });
209 - const [SelectA, SelectB] = vm.$children;  
210 - SelectA.toggleMenu();  
211 - SelectB.toggleMenu();  
212 -  
213 - new Promise(resolve => {  
214 - const condition = function() {  
215 - const optionsA = SelectA.$el.querySelectorAll('.ivu-select-item');  
216 - const optionsB = SelectB.$el.querySelectorAll('.ivu-select-item');  
217 - return optionsA.length > 0 && optionsB.length > 0;  
218 - };  
219 - waitForIt(condition, resolve);  
220 - })  
221 - .then(() => {  
222 - // click in A options  
223 - const optionsA = SelectA.$el.querySelectorAll('.ivu-select-item');  
224 - optionsA[0].click();  
225 - return promissedTick(SelectA);  
226 - })  
227 - .then(() => {  
228 - expect(SelectA.value[0]).to.equal(options[0].value);  
229 - expect(SelectA.value.length).to.equal(1);  
230 - expect(SelectB.value.length).to.equal(0);  
231 -  
232 - // click in B options  
233 - const optionsB = SelectB.$el.querySelectorAll('.ivu-select-item');  
234 - optionsB[1].click();  
235 - optionsB[2].click();  
236 - return promissedTick(SelectB);  
237 - })  
238 - .then(() => {  
239 - // lets check the values!  
240 - const getSelections = component => {  
241 - const tags = component.$el.querySelectorAll('.ivu-select-selection .ivu-tag');  
242 - return [...tags].map(el => el.textContent.trim()).join(',');  
243 - };  
244 - const selectAValue = getSelections(SelectA);  
245 - const selectBValue = getSelections(SelectB);  
246 267
247 - expect(selectAValue).to.equal(options[0].label);  
248 - expect(selectBValue).to.equal(options.slice(1, 3).map(obj => obj.label.trim()).join(',')); 268 + it('should create update model with value, and label when asked', done => {
  269 + const options = [
  270 + {value: 'beijing', label: 'Beijing'},
  271 + {value: 'stockholm', label: 'Stockholm'},
  272 + {value: 'lisboa', label: 'Lisboa'}
  273 + ];
  274 + let onChangeValueA, onChangeValueB;
249 275
250 - done();  
251 - });  
252 - }); 276 +
  277 + vm = createVue({
  278 + template: `
  279 + <div>
  280 + <i-select v-model="modelA" style="width:260px" @on-change="onChangeA">
  281 + <i-option v-for="item in cityList" :value="item.value" :key="item.value">{{ item.label }}</i-option>
  282 + </i-select>
  283 + <i-select v-model="modelB" label-in-value style="width:260px" @on-change="onChangeB">
  284 + <i-option v-for="item in cityList" :value="item.value" :key="item.value">{{ item.label }}</i-option>
  285 + </i-select>
  286 + </div>
  287 + `,
  288 + data() {
  289 + return {
  290 + cityList: options,
  291 + modelA: [],
  292 + modelB: []
  293 + };
  294 + },
  295 + methods: {
  296 + onChangeA(val){
  297 + onChangeValueA = val;
  298 + },
  299 + onChangeB(val){
  300 + onChangeValueB = val;
  301 + }
  302 + }
  303 + });
  304 + const [SelectA, SelectB] = vm.$children;
  305 + SelectA.toggleMenu(null, true);
  306 + SelectB.toggleMenu(null, true);
  307 +
  308 +
  309 + new Promise(resolve => {
  310 + const condition = function() {
  311 + const optionsA = SelectA.$el.querySelectorAll('.ivu-select-item');
  312 + const optionsB = SelectB.$el.querySelectorAll('.ivu-select-item');
  313 + return optionsA.length > 0 && optionsB.length > 0;
  314 + };
  315 + waitForIt(condition, resolve);
  316 + })
  317 + .then(() => {
  318 + // click in A options
  319 + const optionsA = SelectA.$el.querySelectorAll('.ivu-select-item');
  320 + optionsA[0].click();
  321 + return promissedTick(SelectA);
  322 + })
  323 + .then(() => {
  324 + expect(vm.modelA).to.equal(options[0].value);
  325 + expect(onChangeValueA).to.equal(options[0].value);
  326 +
  327 + // click in B options
  328 + const optionsB = SelectB.$el.querySelectorAll('.ivu-select-item');
  329 + optionsB[2].click();
  330 + return promissedTick(SelectB);
  331 + })
  332 + .then(() => {
  333 + expect(vm.modelB).to.equal(options[2].value);
  334 + expect(JSON.stringify(onChangeValueB)).to.equal(JSON.stringify(options[2]));
  335 + done();
  336 + });
  337 + });
  338 + });
  339 +
  340 + describe('Public API', () => {
  341 + it('The "setQuery" method should behave as expected', (done) => {
  342 +
  343 + const options = [
  344 + {value: 'beijing', label: 'Beijing'},
  345 + {value: 'stockholm', label: 'Stockholm'},
  346 + {value: 'lisboa', label: 'Lisboa'}
  347 + ];
  348 +
  349 + vm = createVue({
  350 + template: `
  351 + <Select v-model="value" filterable>
  352 + <Option v-for="item in options" :value="item.value" :key="item.value">{{ item.label }}</Option>
  353 + </Select>
  354 + `,
  355 + data() {
  356 + return {
  357 + value: '',
  358 + options: options
  359 + };
  360 + }
  361 + });
  362 + const [Select] = vm.$children;
  363 + Select.setQuery('i');
  364 + vm.$nextTick(() => {
  365 + const query = 'i';
  366 + const input = vm.$el.querySelector('.ivu-select-input');
  367 + expect(input.value).to.equal(query);
  368 +
  369 + const renderedOptions = [...vm.$el.querySelectorAll('.ivu-select-item')].map(el => el.textContent);
  370 + const filteredOptions = options.filter(option => JSON.stringify(option).includes(query)).map(({label}) => label);
  371 + expect(JSON.stringify(renderedOptions)).to.equal(JSON.stringify(filteredOptions));
  372 +
  373 + // reset query
  374 + // setQuery(null) should clear the select
  375 + Select.setQuery(null);
  376 + vm.$nextTick(() => {
  377 + const input = vm.$el.querySelector('.ivu-select-input');
  378 + expect(input.value).to.equal('');
  379 +
  380 + const renderedOptions = [...vm.$el.querySelectorAll('.ivu-select-item')].map(el => el.textContent);
  381 + expect(JSON.stringify(renderedOptions)).to.equal(JSON.stringify(options.map(({label}) => label)));
  382 + done();
  383 + });
  384 + });
  385 +
  386 + });
  387 +
  388 + it('The "clearSingleSelect" method should behave as expected', (done) => {
  389 +
  390 + // clearSingleSelect
  391 + const options = [
  392 + {value: 'beijing', label: 'Beijing'},
  393 + {value: 'stockholm', label: 'Stockholm'},
  394 + {value: 'lisboa', label: 'Lisboa'}
  395 + ];
  396 + const preSelected = 'lisboa';
  397 +
  398 + vm = createVue({
  399 + template: `
  400 + <Select v-model="value" clearable>
  401 + <Option v-for="item in options" :value="item.value" :key="item.value">{{ item.label }}</Option>
  402 + </Select>
  403 + `,
  404 + data() {
  405 + return {
  406 + value: preSelected,
  407 + options: options
  408 + };
  409 + }
  410 + });
  411 + const [Select] = vm.$children;
  412 + vm.$nextTick(() => {
  413 + expect(Select.publicValue).to.equal(preSelected);
  414 + Select.clearSingleSelect();
  415 + expect(typeof Select.publicValue).to.equal('undefined');
  416 + done();
  417 + });
  418 + });
253 }); 419 });
254 420
255 describe('Performance tests', () => { 421 describe('Performance tests', () => {
@@ -278,7 +444,8 @@ describe(&#39;Select.vue&#39;, () =&gt; { @@ -278,7 +444,8 @@ describe(&#39;Select.vue&#39;, () =&gt; {
278 } 444 }
279 }); 445 });
280 const condition = function() { 446 const condition = function() {
281 - return vm.$children[0].options.length == manyLaterOptions.length; 447 + const componentOptions = vm.$children[0].flatOptions;
  448 + return componentOptions && componentOptions.length === manyLaterOptions.length;
282 }; 449 };
283 const callback = function() { 450 const callback = function() {
284 const end = +new Date(); 451 const end = +new Date();