import Vue from 'vue'
describe('Directive v-for', () => {
it('should render array of primitive values', done => {
const vm = new Vue({
template: `
{{item}}
`,
data: {
list: ['a', 'b', 'c']
}
}).$mount()
expect(vm.$el.innerHTML).toBe('abc')
Vue.set(vm.list, 0, 'd')
waitForUpdate(() => {
expect(vm.$el.innerHTML).toBe('dbc')
vm.list.push('d')
}).then(() => {
expect(vm.$el.innerHTML).toBe('dbcd')
vm.list.splice(1, 2)
}).then(() => {
expect(vm.$el.innerHTML).toBe('dd')
vm.list = ['x', 'y']
}).then(() => {
expect(vm.$el.innerHTML).toBe('xy')
}).then(done)
})
it('should render array of primitive values with index', done => {
const vm = new Vue({
template: `
{{i}}-{{item}}
`,
data: {
list: ['a', 'b', 'c']
}
}).$mount()
expect(vm.$el.innerHTML).toBe('0-a1-b2-c')
Vue.set(vm.list, 0, 'd')
waitForUpdate(() => {
expect(vm.$el.innerHTML).toBe('0-d1-b2-c')
vm.list.push('d')
}).then(() => {
expect(vm.$el.innerHTML).toBe('0-d1-b2-c3-d')
vm.list.splice(1, 2)
}).then(() => {
expect(vm.$el.innerHTML).toBe('0-d1-d')
vm.list = ['x', 'y']
}).then(() => {
expect(vm.$el.innerHTML).toBe('0-x1-y')
}).then(done)
})
it('should render array of object values', done => {
const vm = new Vue({
template: `
{{item.value}}
`,
data: {
list: [
{ value: 'a' },
{ value: 'b' },
{ value: 'c' }
]
}
}).$mount()
expect(vm.$el.innerHTML).toBe('abc')
Vue.set(vm.list, 0, { value: 'd' })
waitForUpdate(() => {
expect(vm.$el.innerHTML).toBe('dbc')
vm.list[0].value = 'e'
}).then(() => {
expect(vm.$el.innerHTML).toBe('ebc')
vm.list.push({})
}).then(() => {
expect(vm.$el.innerHTML).toBe('ebc')
vm.list.splice(1, 2)
}).then(() => {
expect(vm.$el.innerHTML).toBe('e')
vm.list = [{ value: 'x' }, { value: 'y' }]
}).then(() => {
expect(vm.$el.innerHTML).toBe('xy')
}).then(done)
})
it('should render array of object values with index', done => {
const vm = new Vue({
template: `
{{i}}-{{item.value}}
`,
data: {
list: [
{ value: 'a' },
{ value: 'b' },
{ value: 'c' }
]
}
}).$mount()
expect(vm.$el.innerHTML).toBe('0-a1-b2-c')
Vue.set(vm.list, 0, { value: 'd' })
waitForUpdate(() => {
expect(vm.$el.innerHTML).toBe('0-d1-b2-c')
vm.list[0].value = 'e'
}).then(() => {
expect(vm.$el.innerHTML).toBe('0-e1-b2-c')
vm.list.push({})
}).then(() => {
expect(vm.$el.innerHTML).toBe('0-e1-b2-c3-')
vm.list.splice(1, 2)
}).then(() => {
expect(vm.$el.innerHTML).toBe('0-e1-')
vm.list = [{ value: 'x' }, { value: 'y' }]
}).then(() => {
expect(vm.$el.innerHTML).toBe('0-x1-y')
}).then(done)
})
it('should render an Object', done => {
const vm = new Vue({
template: `
{{val}}
`,
data: {
obj: { a: 0, b: 1, c: 2 }
}
}).$mount()
expect(vm.$el.innerHTML).toBe('012')
vm.obj.a = 3
waitForUpdate(() => {
expect(vm.$el.innerHTML).toBe('312')
Vue.set(vm.obj, 'd', 4)
}).then(() => {
expect(vm.$el.innerHTML).toBe('3124')
Vue.delete(vm.obj, 'a')
}).then(() => {
expect(vm.$el.innerHTML).toBe('124')
}).then(done)
})
it('should render an Object with key', done => {
const vm = new Vue({
template: `
{{val}}-{{key}}
`,
data: {
obj: { a: 0, b: 1, c: 2 }
}
}).$mount()
expect(vm.$el.innerHTML).toBe('0-a1-b2-c')
vm.obj.a = 3
waitForUpdate(() => {
expect(vm.$el.innerHTML).toBe('3-a1-b2-c')
Vue.set(vm.obj, 'd', 4)
}).then(() => {
expect(vm.$el.innerHTML).toBe('3-a1-b2-c4-d')
Vue.delete(vm.obj, 'a')
}).then(() => {
expect(vm.$el.innerHTML).toBe('1-b2-c4-d')
}).then(done)
})
it('should render an Object with key and index', done => {
const vm = new Vue({
template: `
{{val}}-{{key}}-{{i}}
`,
data: {
obj: { a: 0, b: 1, c: 2 }
}
}).$mount()
expect(vm.$el.innerHTML).toBe('0-a-01-b-12-c-2')
vm.obj.a = 3
waitForUpdate(() => {
expect(vm.$el.innerHTML).toBe('3-a-01-b-12-c-2')
Vue.set(vm.obj, 'd', 4)
}).then(() => {
expect(vm.$el.innerHTML).toBe('3-a-01-b-12-c-24-d-3')
Vue.delete(vm.obj, 'a')
}).then(() => {
expect(vm.$el.innerHTML).toBe('1-b-02-c-14-d-2')
}).then(done)
})
it('should render each key of data', done => {
const vm = new Vue({
template: `
{{val}}-{{key}}
`,
data: { a: 0, b: 1, c: 2 }
}).$mount()
expect(vm.$el.innerHTML).toBe('0-a1-b2-c')
vm.a = 3
waitForUpdate(() => {
expect(vm.$el.innerHTML).toBe('3-a1-b2-c')
}).then(done)
})
it('check priorities: v-if before v-for', function () {
const vm = new Vue({
data: {
items: [1, 2, 3]
},
template: ''
}).$mount()
expect(vm.$el.textContent).toBe('12')
})
it('check priorities: v-if after v-for', function () {
const vm = new Vue({
data: {
items: [1, 2, 3]
},
template: ''
}).$mount()
expect(vm.$el.textContent).toBe('12')
})
it('range v-for', () => {
const vm = new Vue({
template: ''
}).$mount()
expect(vm.$el.textContent).toBe('123')
})
it('without key', done => {
const vm = new Vue({
data: {
items: [
{ id: 1, msg: 'a' },
{ id: 2, msg: 'b' },
{ id: 3, msg: 'c' }
]
},
template: ''
}).$mount()
expect(vm.$el.textContent).toBe('abc')
const first = vm.$el.children[0]
vm.items.reverse()
waitForUpdate(() => {
expect(vm.$el.textContent).toBe('cba')
// assert reusing DOM element in place
expect(vm.$el.children[0]).toBe(first)
}).then(done)
})
it('with key', done => {
const vm = new Vue({
data: {
items: [
{ id: 1, msg: 'a' },
{ id: 2, msg: 'b' },
{ id: 3, msg: 'c' }
]
},
template: ''
}).$mount()
expect(vm.$el.textContent).toBe('abc')
const first = vm.$el.children[0]
vm.items.reverse()
waitForUpdate(() => {
expect(vm.$el.textContent).toBe('cba')
// assert moving DOM element
expect(vm.$el.children[0]).not.toBe(first)
expect(vm.$el.children[2]).toBe(first)
}).then(done)
})
it('nested loops', () => {
const vm = new Vue({
data: {
items: [
{ items: [{ a: 1 }, { a: 2 }], a: 1 },
{ items: [{ a: 3 }, { a: 4 }], a: 2 }
]
},
template:
'' +
'
' +
'
{{j}} {{subItem.a}} {{i}} {{item.a}}
' +
'
' +
'
'
}).$mount()
expect(vm.$el.innerHTML).toBe(
'' +
''
)
})
it('template v-for', done => {
const vm = new Vue({
data: {
list: [
{ a: 1 },
{ a: 2 },
{ a: 3 }
]
},
template:
'' +
'
' +
'{{item.a}}
' +
'{{item.a + 1}}
' +
'' +
'
'
}).$mount()
assertMarkup()
vm.list.reverse()
waitForUpdate(() => {
assertMarkup()
vm.list.splice(1, 1)
}).then(() => {
assertMarkup()
vm.list.splice(1, 0, { a: 2 })
}).then(done)
function assertMarkup () {
var markup = vm.list.map(function (item) {
return '' + item.a + '
' + (item.a + 1) + '
'
}).join('')
expect(vm.$el.innerHTML).toBe(markup)
}
})
it('component v-for', done => {
const vm = new Vue({
data: {
list: [
{ a: 1 },
{ a: 2 },
{ a: 3 }
]
},
template:
'' +
'' +
'{{item.a}}' +
'' +
'
',
components: {
test: {
props: ['msg'],
template: '{{msg}}
'
}
}
}).$mount()
assertMarkup()
vm.list.reverse()
waitForUpdate(() => {
assertMarkup()
vm.list.splice(1, 1)
}).then(() => {
assertMarkup()
vm.list.splice(1, 0, { a: 2 })
}).then(done)
function assertMarkup () {
var markup = vm.list.map(function (item) {
return `${item.a}${item.a}
`
}).join('')
expect(vm.$el.innerHTML).toBe(markup)
}
})
it('dynamic component v-for', done => {
const vm = new Vue({
data: {
list: [
{ type: 'one' },
{ type: 'two' }
]
},
template:
'' +
'' +
'
',
components: {
one: {
template: 'One!
'
},
two: {
template: 'Two!
'
}
}
}).$mount()
expect(vm.$el.innerHTML).toContain('One!
Two!
')
vm.list.reverse()
waitForUpdate(() => {
expect(vm.$el.innerHTML).toContain('Two!
One!
')
}).then(done)
})
it('should warn component v-for without keys', () => {
const warn = console.warn
console.warn = jasmine.createSpy()
new Vue({
template: `
`,
components: {
test: {
render () {}
}
}
}).$mount()
expect(console.warn.calls.argsFor(0)[0]).toContain(
`: component lists rendered with v-for should have explicit keys`
)
console.warn = warn
})
it('multi nested array reactivity', done => {
const vm = new Vue({
data: {
list: [[['foo']]]
},
template: `
`
}).$mount()
expect(vm.$el.textContent).toMatch(/\s+foo\s+/)
vm.list[0][0].push('bar')
waitForUpdate(() => {
expect(vm.$el.textContent).toMatch(/\s+foo\s+bar\s+/)
}).then(done)
})
it('strings', done => {
const vm = new Vue({
data: {
text: 'foo'
},
template: `
{{ letter }}.
`
}).$mount()
expect(vm.$el.textContent).toMatch('f.o.o.')
vm.text += 'bar'
waitForUpdate(() => {
expect(vm.$el.textContent).toMatch('f.o.o.b.a.r.')
}).then(done)
})
})