Skip to content

Commit 38a6e1f

Browse files
committed
tests for v-model select
1 parent d2283e0 commit 38a6e1f

File tree

2 files changed

+175
-11
lines changed

2 files changed

+175
-11
lines changed

src/directives/model/select.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ function initOptions (expression) {
5858
var self = this
5959
function optionUpdateWatcher (value) {
6060
if (_.isArray(value)) {
61-
self.el.innerHTML = value.map(formatOption)
61+
self.el.innerHTML = value.map(formatOption).join('')
6262
if (self._watcher) {
6363
self.update(self._watcher.value)
6464
}
@@ -93,7 +93,7 @@ function formatOption (op) {
9393
'</option>'
9494
} else if (op.options) {
9595
return '<optgroup label="' + op.label + '">' +
96-
op.options.map(formatOption) +
96+
op.options.map(formatOption).join('') +
9797
'</optgroup>'
9898
}
9999
} else {
@@ -108,9 +108,8 @@ function formatOption (op) {
108108
function checkInitialValue () {
109109
var initValue
110110
var options = this.el.options
111-
var i = options.length
112-
while (i--) {
113-
if (options[i].selected) {
111+
for (var i = 0, l = options.length; i < l; i++) {
112+
if (options[i].hasAttribute('selected')) {
114113
if (this.multiple) {
115114
(initValue || (initValue = []))
116115
.push(options[i].value)

test/unit/specs/directives/model_spec.js

Lines changed: 171 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,168 @@ if (_.inBrowser) {
9191
expect(vm.test).toBe(true)
9292
})
9393

94-
it('select', function () {
95-
94+
it('select', function (done) {
95+
var vm = new Vue({
96+
el: el,
97+
data: {
98+
test: 'b'
99+
},
100+
template:
101+
'<select v-model="test">' +
102+
'<option>a</option>' +
103+
'<option>b</option>' +
104+
'<option>c</option>' +
105+
'</select>'
106+
})
107+
expect(vm.test).toBe('b')
108+
expect(el.firstChild.value).toBe('b')
109+
expect(el.firstChild.childNodes[1].selected).toBe(true)
110+
vm.test = 'c'
111+
_.nextTick(function () {
112+
expect(el.firstChild.value).toBe('c')
113+
expect(el.firstChild.childNodes[2].selected).toBe(true)
114+
el.firstChild.value = 'a'
115+
trigger(el.firstChild, 'change')
116+
expect(vm.test).toBe('a')
117+
done()
118+
})
96119
})
97120

98-
it('select + options', function () {
99-
121+
it('select default value', function () {
122+
var vm = new Vue({
123+
el: el,
124+
data: {
125+
test: 'a'
126+
},
127+
template:
128+
'<select v-model="test">' +
129+
'<option>a</option>' +
130+
'<option selected>b</option>' +
131+
'</select>'
132+
})
133+
expect(vm.test).toBe('b')
134+
expect(el.firstChild.value).toBe('b')
135+
expect(el.firstChild.childNodes[1].selected).toBe(true)
136+
})
137+
138+
it('select + multiple', function (done) {
139+
var vm = new Vue({
140+
el: el,
141+
data: {
142+
test: ['b']
143+
},
144+
template:
145+
'<select v-model="test" multiple>' +
146+
'<option>a</option>' +
147+
'<option>b</option>' +
148+
'<option>c</option>' +
149+
'</select>'
150+
})
151+
var opts = el.firstChild.options
152+
expect(opts[0].selected).toBe(false)
153+
expect(opts[1].selected).toBe(true)
154+
expect(opts[2].selected).toBe(false)
155+
vm.test = ['a', 'c']
156+
_.nextTick(function () {
157+
expect(opts[0].selected).toBe(true)
158+
expect(opts[1].selected).toBe(false)
159+
expect(opts[2].selected).toBe(true)
160+
opts[0].selected = false
161+
opts[1].selected = true
162+
trigger(el.firstChild, 'change')
163+
expect(vm.test[0]).toBe('b')
164+
expect(vm.test[1]).toBe('c')
165+
done()
166+
})
167+
})
168+
169+
it('select + multiple default value', function () {
170+
var vm = new Vue({
171+
el: el,
172+
data: {},
173+
template:
174+
'<select v-model="test" multiple>' +
175+
'<option>a</option>' +
176+
'<option selected>b</option>' +
177+
'<option selected>c</option>' +
178+
'</select>'
179+
})
180+
expect(vm.test[0]).toBe('b')
181+
expect(vm.test[1]).toBe('c')
182+
})
183+
184+
it('select + options', function (done) {
185+
var vm = new Vue({
186+
el: el,
187+
data: {
188+
test: 'b',
189+
opts: ['a', 'b', 'c']
190+
},
191+
template: '<select v-model="test" options="opts"></select>'
192+
})
193+
var opts = el.firstChild.options
194+
expect(opts.length).toBe(3)
195+
expect(opts[0].selected).toBe(false)
196+
expect(opts[1].selected).toBe(true)
197+
expect(opts[2].selected).toBe(false)
198+
vm.opts = ['b', 'c']
199+
_.nextTick(function () {
200+
expect(opts.length).toBe(2)
201+
expect(opts[0].selected).toBe(true)
202+
expect(opts[1].selected).toBe(false)
203+
// should teardown option watcher when unbind
204+
expect(vm._watcherList.length).toBe(2)
205+
vm._directives[0].unbind()
206+
expect(vm._watcherList.length).toBe(0)
207+
done()
208+
})
209+
})
210+
211+
it('select + options + label', function () {
212+
var vm = new Vue({
213+
el: el,
214+
data: {
215+
test: 'b',
216+
opts: [
217+
{ label: 'A', value: 'a' },
218+
{ label: 'B', value: 'b' }
219+
]
220+
},
221+
template: '<select v-model="test" options="opts"></select>'
222+
})
223+
expect(el.firstChild.innerHTML).toBe(
224+
'<option value="a">A</option>' +
225+
'<option value="b">B</option>'
226+
)
227+
var opts = el.firstChild.options
228+
expect(opts[0].selected).toBe(false)
229+
expect(opts[1].selected).toBe(true)
230+
})
231+
232+
it('select + options + optgroup', function () {
233+
var vm = new Vue({
234+
el: el,
235+
data: {
236+
test: 'b',
237+
opts: [
238+
{ label: 'A', options: ['a','b'] },
239+
{ label: 'B', options: ['c'] }
240+
]
241+
},
242+
template: '<select v-model="test" options="opts"></select>'
243+
})
244+
expect(el.firstChild.innerHTML).toBe(
245+
'<optgroup label="A">' +
246+
'<option>a</option><option>b</option>' +
247+
'</optgroup>' +
248+
'<optgroup label="B">' +
249+
'<option>c</option>' +
250+
'</optgroup>'
251+
)
252+
var opts = el.firstChild.options
253+
expect(opts[0].selected).toBe(false)
254+
expect(opts[1].selected).toBe(true)
255+
expect(opts[2].selected).toBe(false)
100256
})
101257

102258
it('text', function () {
@@ -111,10 +267,19 @@ if (_.inBrowser) {
111267

112268
})
113269

114-
it('warn invalid', function () {
270+
it('warn invalid tag', function () {
271+
var vm = new Vue({
272+
el: el,
273+
template: '<div v-model="test"></div>'
274+
})
275+
expect(_.warn).toHaveBeenCalled()
276+
})
277+
278+
it('warn invalid option value', function () {
115279
var vm = new Vue({
116280
el: el,
117-
template: '<div v-model="test"></div<'
281+
data: { a: 123 },
282+
template: '<select v-model="test" options="a"></select>'
118283
})
119284
expect(_.warn).toHaveBeenCalled()
120285
})

0 commit comments

Comments
 (0)