Commit afef4ce7f7870df129d29786cfaf64e9ab41c169
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('Select.vue', () => { | @@ -112,13 +118,20 @@ describe('Select.vue', () => { | ||
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('Select.vue', () => { | @@ -158,12 +171,10 @@ describe('Select.vue', () => { | ||
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('Select.vue', () => { | @@ -177,79 +188,234 @@ describe('Select.vue', () => { | ||
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('Select.vue', () => { | @@ -278,7 +444,8 @@ describe('Select.vue', () => { | ||
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(); |