var _ = require('src/util')
var Vue = require('src')
describe('v-for', function () {
var el
beforeEach(function () {
el = document.createElement('div')
})
it('objects', function (done) {
var vm = new Vue({
el: el,
data: {
items: [{a: 1}, {a: 2}]
},
template: '
{{$index}} {{item.a}}
'
})
assertMutations(vm, el, done)
})
it('primitives', function (done) {
var vm = new Vue({
el: el,
data: {
items: [1, 2, 3]
},
template: '
{{$index}} {{item}}
'
})
assertPrimitiveMutations(vm, el, done)
})
it('object of objects', function (done) {
var vm = new Vue({
el: el,
data: {
items: {
a: {a: 1},
b: {a: 2}
}
},
template: '
{{$index}} {{$key}} {{item.a}}
'
})
assertObjectMutations(vm, el, done)
})
it('object of primitives', function (done) {
var vm = new Vue({
el: el,
data: {
items: {
a: 1,
b: 2
}
},
template: '
{{$index}} {{$key}} {{item}}
'
})
assertObjectPrimitiveMutations(vm, el, done)
})
it('array of arrays', function () {
var vm = new Vue({
el: el,
data: {
items: [[1, 1], [2, 2], [3, 3]]
},
template: '
'
})
.slice(0, 2)
.join('')
expect(el.innerHTML).toBe(markup)
}
})
it('orderBy supporting $key for object repeaters', function (done) {
var vm = new Vue({
el: el,
template: '
')
})
it('track by id', function (done) {
var vm = new Vue({
el: el,
template: '',
data: {
list: [
{ id: 1, msg: 'hi' },
{ id: 2, msg: 'ha' },
{ id: 3, msg: 'ho' }
]
},
components: {
test: {
props: ['item'],
template: '{{item.msg}}'
}
}
})
assertMarkup()
var oldVms = vm.$children.slice()
// swap the data with different objects, but with
// the same ID!
vm.list = [
{ id: 1, msg: 'wa' },
{ id: 2, msg: 'wo' }
]
_.nextTick(function () {
assertMarkup()
// should reuse old vms!
var i = 2
while (i--) {
expect(vm.$children[i]).toBe(oldVms[i])
}
done()
})
function assertMarkup () {
var markup = vm.list.map(function (item) {
return '' + item.msg + ''
}).join('')
expect(el.innerHTML).toBe(markup)
}
})
it('track by $index', function (done) {
var vm = new Vue({
el: el,
data: {
items: [{a: 1}, {a: 2}]
},
template: '
{{$index}} {{item.a}}
'
})
assertMarkup()
var el1 = el.children[0]
var el2 = el.children[1]
vm.items = [{a: 3}, {a: 2}, {a: 1}]
_.nextTick(function () {
assertMarkup()
// should mutate the DOM in-place
expect(el.children[0]).toBe(el1)
expect(el.children[1]).toBe(el2)
done()
})
function assertMarkup () {
expect(el.innerHTML).toBe(vm.items.map(function (item, i) {
return '
' + i + ' ' + item.a + '
'
}).join(''))
}
})
it('primitive values track by $index', function (done) {
var vm = new Vue({
el: el,
data: {
items: [1, 2, 3]
},
template: '
{{$index}} {{item}}
'
})
assertPrimitiveMutationsWithDuplicates(vm, el, done)
})
it('warn missing alias', function () {
new Vue({
el: el,
template: ''
})
expect('Alias is required in v-for').toHaveBeenWarned()
})
it('warn duplicate objects', function () {
var obj = {}
new Vue({
el: el,
template: '',
data: {
items: [obj, obj]
}
})
expect('Duplicate value').toHaveBeenWarned()
})
it('warn duplicate objects on diff', function (done) {
var obj = {}
var vm = new Vue({
el: el,
template: '',
data: {
items: [obj]
}
})
expect(getWarnCount()).toBe(0)
vm.items.push(obj)
_.nextTick(function () {
expect('Duplicate value').toHaveBeenWarned()
done()
})
})
it('warn duplicate trackby id', function () {
new Vue({
el: el,
template: '',
data: {
items: [{id: 1}, {id: 1}]
}
})
expect('Duplicate value').toHaveBeenWarned()
})
it('key val syntax with object', function (done) {
var vm = new Vue({
el: el,
template: '
{{$index}} {{key}} {{val.a}}
',
data: {
items: {
a: {a: 1},
b: {a: 2}
}
}
})
assertObjectMutations(vm, el, done)
})
it('key val syntax with array', function (done) {
var vm = new Vue({
el: el,
template: '
{{i}} {{item.a}}
',
data: {
items: [{a: 1}, {a: 2}]
}
})
assertMutations(vm, el, done)
})
it('key val syntax with nested v-for s', function () {
new Vue({
el: el,
template: '
')
})
it('repeat number', function () {
new Vue({
el: el,
template: '
{{$index}} {{n}}
'
})
expect(el.innerHTML).toBe('
0 0
1 1
2 2
')
})
it('repeat string', function () {
new Vue({
el: el,
template: '
{{$index}} {{letter}}
'
})
expect(el.innerHTML).toBe('
0 v
1 u
2 e
')
})
it('teardown', function () {
var vm = new Vue({
el: el,
template: '',
data: {
items: [{a: 1}, {a: 2}]
}
})
vm._directives[0].unbind()
expect(vm.$children.length).toBe(0)
})
it('with transition', function (done) {
document.body.appendChild(el)
var vm = new Vue({
el: el,
template: '
'
)
document.body.removeChild(el)
done()
}, 100)
})
it('v-model binding on alias', function () {
var vm = new Vue({
el: el,
template:
'' +
'',
data: {
items: ['a'],
obj: { foo: 'a' }
}
})
var a = getInput(1)
a.value = 'b'
trigger(a, 'input')
expect(vm.items[0]).toBe('b')
var b = getInput(2)
b.value = 'bar'
trigger(b, 'input')
expect(vm.obj.foo).toBe('bar')
function getInput (x) {
return vm.$el.querySelector('div:nth-child(' + x + ') input')
}
})
it('warn v-model on alias with filters', function () {
var vm = new Vue({
el: el,
template:
'
' +
'' +
'
',
data: {
items: ['a', 'b']
}
})
trigger(vm.$el.querySelector('input'), 'input')
expect('It seems you are using two-way binding').toHaveBeenWarned()
})
it('nested track by', function (done) {
var vm = new Vue({
el: el,
template:
'