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 | 26 | const placeholderSpan = vm.$el.querySelector('.ivu-select-placeholder'); |
27 | 27 | expect(placeholderSpan.textContent).to.equal(placeholder); |
28 | 28 | expect(placeholderSpan.style.display).to.not.equal('none'); |
29 | - | |
30 | - expect(vm.$children[0].showPlaceholder).to.equal(true); | |
31 | 29 | done(); |
32 | 30 | }); |
33 | 31 | }); |
34 | 32 | |
35 | 33 | it('should create a Select component and take a pre-selected value', done => { |
36 | 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 | 65 | it('should accept normal characters', done => { |
... | ... | @@ -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 | 137 | it('should set different classes for different sizes', done => { |
... | ... | @@ -158,12 +171,10 @@ describe('Select.vue', () => { |
158 | 171 | } |
159 | 172 | }); |
160 | 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 | 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 | 178 | const renderedOptions = vm.$el.querySelectorAll('.ivu-select-dropdown-list li'); |
168 | 179 | expect(renderedOptions.length).to.equal(laterOptions.length); |
169 | 180 | |
... | ... | @@ -177,79 +188,234 @@ describe('Select.vue', () => { |
177 | 188 | }); |
178 | 189 | |
179 | 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 | 421 | describe('Performance tests', () => { |
... | ... | @@ -278,7 +444,8 @@ describe('Select.vue', () => { |
278 | 444 | } |
279 | 445 | }); |
280 | 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 | 450 | const callback = function() { |
284 | 451 | const end = +new Date(); | ... | ... |