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: '
{{item}}
' }).$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: '
{{item}}
' }).$mount() expect(vm.$el.textContent).toBe('12') }) it('range v-for', () => { const vm = new Vue({ template: '
{{n}}
' }).$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: '
{{ item.msg }}
' }).$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: '
{{ item.msg }}
' }).$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( '

0 1 0 1

1 2 0 1

' + '

0 3 1 2

1 4 1 2

' ) }) it('template v-for', done => { const vm = new Vue({ data: { list: [ { a: 1 }, { a: 2 }, { a: 3 } ] }, template: '
' + '' + '
' }).$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: `
{{ k }}
` }).$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) }) })