Commit 3b9de2499e4b1405aa1801bbed4a2f02cf75810c
1 parent
62f5dd0c
Add simple unit tests for Select component
Showing
2 changed files
with
206 additions
and
0 deletions
Show diff stats
| 1 | +import {createVue, destroyVM, waitForIt} from '../util'; | |
| 2 | + | |
| 3 | +describe('Select.vue', () => { | |
| 4 | + let vm; | |
| 5 | + afterEach(() => { | |
| 6 | + destroyVM(vm); | |
| 7 | + }); | |
| 8 | + | |
| 9 | + describe('Props tests', () => { | |
| 10 | + it('should create a Select component with passed placeholder', done => { | |
| 11 | + const placeholder = 'Hi! Select something!'; | |
| 12 | + vm = createVue({ | |
| 13 | + template: ` | |
| 14 | + <Select placeholder="${placeholder}"> | |
| 15 | + <Option v-for="item in options" :value="item.value" :key="item.value">{{ item.label }}</Option> | |
| 16 | + </Select> | |
| 17 | + `, | |
| 18 | + data() { | |
| 19 | + return { | |
| 20 | + value: '', | |
| 21 | + options: [{value: 1, label: 'Foo'}, {value: 2, label: 'Bar'}] | |
| 22 | + }; | |
| 23 | + } | |
| 24 | + }); | |
| 25 | + vm.$nextTick(() => { | |
| 26 | + const placeholderSpan = vm.$el.querySelector('.ivu-select-placeholder'); | |
| 27 | + expect(placeholderSpan.textContent).to.equal(placeholder); | |
| 28 | + expect(placeholderSpan.style.display).to.not.equal('none'); | |
| 29 | + | |
| 30 | + expect(vm.$children[0].showPlaceholder).to.equal(true); | |
| 31 | + done(); | |
| 32 | + }); | |
| 33 | + }); | |
| 34 | + | |
| 35 | + it('should create a Select component and take a pre-selected value', done => { | |
| 36 | + 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(); | |
| 56 | + }); | |
| 57 | + }); | |
| 58 | + | |
| 59 | + xit('should accept normal characters', done => { | |
| 60 | + vm = createVue({ | |
| 61 | + template: ` | |
| 62 | + <Select :value="2"> | |
| 63 | + <Option v-for="item in options" :value="item.value" :key="item.value">{{ item.label }}</Option> | |
| 64 | + </Select> | |
| 65 | + `, | |
| 66 | + data() { | |
| 67 | + return { | |
| 68 | + value: '', | |
| 69 | + options: [{value: 1, label: '> 100$'}, {value: 2, label: '< 100$'}] | |
| 70 | + }; | |
| 71 | + } | |
| 72 | + }); | |
| 73 | + vm.$nextTick(() => { | |
| 74 | + const selectedValueSpan = vm.$el.querySelector('.ivu-select-selected-value'); | |
| 75 | + expect(selectedValueSpan.textContent).to.equal('< 100$'); | |
| 76 | + done(); | |
| 77 | + }); | |
| 78 | + }); | |
| 79 | + | |
| 80 | + it('should use the value\'s label instead of placeholder when both are set', done => { | |
| 81 | + vm = createVue({ | |
| 82 | + template: ` | |
| 83 | + <Select placeholder="Choose anything!" :value="2"> | |
| 84 | + <Option v-for="item in options" :value="item.value" :key="item.value">{{ item.label }}</Option> | |
| 85 | + </Select> | |
| 86 | + `, | |
| 87 | + data() { | |
| 88 | + return { | |
| 89 | + value: '', | |
| 90 | + options: [{value: 1, label: 'Foo'}, {value: 2, label: 'Bar'}] | |
| 91 | + }; | |
| 92 | + } | |
| 93 | + }); | |
| 94 | + vm.$nextTick(() => { | |
| 95 | + const placeholderSpan = vm.$el.querySelector('.ivu-select-placeholder'); | |
| 96 | + const selectedValueSpan = vm.$el.querySelector('.ivu-select-selected-value'); | |
| 97 | + expect(placeholderSpan.style.display).to.equal('none'); | |
| 98 | + expect(selectedValueSpan.style.display).to.not.equal('none'); | |
| 99 | + done(); | |
| 100 | + }); | |
| 101 | + }); | |
| 102 | + | |
| 103 | + it('should set different classes for different sizes', done => { | |
| 104 | + vm = createVue(` | |
| 105 | + <div> | |
| 106 | + <Select placeholder="Choose anything!"><Option v-for="item in []" :value="item" :key="item">{{item}}</Option></Select> | |
| 107 | + <Select placeholder="Choose anything!" size="large"><Option v-for="item in []" :value="item" :key="item">{{item}}</Option></Select> | |
| 108 | + <Select placeholder="Choose anything!" size="small"><Option v-for="item in []" :value="item" :key="item">{{item}}</Option></Select> | |
| 109 | + </div> | |
| 110 | + `); | |
| 111 | + vm.$nextTick(() => { | |
| 112 | + const [defaultSelect, largeSelect, smallSelect] = [...vm.$el.querySelectorAll('.ivu-select')]; | |
| 113 | + expect(defaultSelect.className).to.equal('ivu-select ivu-select-single'); | |
| 114 | + expect(largeSelect.classList.contains('ivu-select-large')).to.equal(true); | |
| 115 | + expect(smallSelect.classList.contains('ivu-select-small')).to.equal(true); | |
| 116 | + done(); | |
| 117 | + }); | |
| 118 | + }); | |
| 119 | + | |
| 120 | + it('should set new options', done => { | |
| 121 | + const laterOptions = [{value: 1, label: 'Foo'}, {value: 2, label: 'Bar'}]; | |
| 122 | + | |
| 123 | + vm = createVue({ | |
| 124 | + template: ` | |
| 125 | + <Select> | |
| 126 | + <Option v-for="item in options" :value="item.value" :key="item.value">{{ item.label }}</Option> | |
| 127 | + </Select> | |
| 128 | + `, | |
| 129 | + data() { | |
| 130 | + return { | |
| 131 | + value: '', | |
| 132 | + options: [] | |
| 133 | + }; | |
| 134 | + }, | |
| 135 | + mounted() { | |
| 136 | + this.$nextTick(() => (this.options = laterOptions)); | |
| 137 | + } | |
| 138 | + }); | |
| 139 | + const condition = function() { | |
| 140 | + return vm.$children[0].options.length > 0; | |
| 141 | + }; | |
| 142 | + const callback = function() { | |
| 143 | + if (vm.$children[0].options == 0) return setTimeout(waitForIt.bind(null, done), 50); | |
| 144 | + expect(JSON.stringify(vm.$children[0].options)).to.equal(JSON.stringify(laterOptions)); | |
| 145 | + | |
| 146 | + const renderedOptions = vm.$el.querySelectorAll('.ivu-select-dropdown-list li'); | |
| 147 | + expect(renderedOptions.length).to.equal(laterOptions.length); | |
| 148 | + | |
| 149 | + const labels = [...renderedOptions].map(el => el.textContent).join('<>'); | |
| 150 | + const expected = laterOptions.map(o => o.label).join('<>'); | |
| 151 | + expect(labels).to.equal(expected); | |
| 152 | + done(); | |
| 153 | + }; | |
| 154 | + waitForIt(condition, callback); | |
| 155 | + }); | |
| 156 | + }); | |
| 157 | + | |
| 158 | + describe('Performance tests', () => { | |
| 159 | + xit('should handle big numbers of options', done => { | |
| 160 | + const manyLaterOptions = Array.apply(null, Array(200)).map((_, i) => { | |
| 161 | + return { | |
| 162 | + value: i + 1, | |
| 163 | + label: Math.random().toString(36).slice(2).toUpperCase() | |
| 164 | + }; | |
| 165 | + }); | |
| 166 | + const start = +new Date(); | |
| 167 | + vm = createVue({ | |
| 168 | + template: ` | |
| 169 | + <Select> | |
| 170 | + <Option v-for="item in options" :value="item.value" :key="item.value">{{ item.label }}</Option> | |
| 171 | + </Select> | |
| 172 | + `, | |
| 173 | + data() { | |
| 174 | + return { | |
| 175 | + value: '', | |
| 176 | + options: [] | |
| 177 | + }; | |
| 178 | + }, | |
| 179 | + mounted() { | |
| 180 | + this.$nextTick(() => (this.options = manyLaterOptions)); | |
| 181 | + } | |
| 182 | + }); | |
| 183 | + const condition = function() { | |
| 184 | + return vm.$children[0].options.length == manyLaterOptions.length; | |
| 185 | + }; | |
| 186 | + const callback = function() { | |
| 187 | + const end = +new Date(); | |
| 188 | + const renderedOptions = vm.$el.querySelectorAll('.ivu-select-dropdown-list li'); | |
| 189 | + expect(renderedOptions.length).to.equal(manyLaterOptions.length); | |
| 190 | + expect(end - start).to.be.not.above(1000); | |
| 191 | + done(); | |
| 192 | + }; | |
| 193 | + waitForIt(condition, callback); | |
| 194 | + }); | |
| 195 | + }); | |
| 196 | +}); | ... | ... |
test/unit/util.js
| ... | ... | @@ -83,3 +83,13 @@ exports.triggerEvent = function(elm, name, ...opts) { |
| 83 | 83 | |
| 84 | 84 | return elm; |
| 85 | 85 | }; |
| 86 | + | |
| 87 | +/** | |
| 88 | +* Wait for components inner async process, when this.$nextTick is not enough | |
| 89 | +* @param {Function} the condition to verify before calling the callback | |
| 90 | +* @param {Function} the callback to call when condition is true | |
| 91 | +*/ | |
| 92 | +exports.waitForIt = function waitForIt(condition, callback) { | |
| 93 | + if (condition()) callback(); | |
| 94 | + else setTimeout(() => waitForIt(condition, callback), 50); | |
| 95 | +}; | ... | ... |