import Vue from 'vue' describe('Directive v-if', () => { it('should check if value is truthy', () => { const vm = new Vue({ template: '
hello
', data: { foo: true } }).$mount() expect(vm.$el.innerHTML).toBe('hello') }) it('should check if value is falsy', () => { const vm = new Vue({ template: '
hello
', data: { foo: false } }).$mount() expect(vm.$el.innerHTML).toBe('') }) it('should update if value changed', done => { const vm = new Vue({ template: '
hello
', data: { foo: true } }).$mount() expect(vm.$el.innerHTML).toBe('hello') vm.foo = false waitForUpdate(() => { expect(vm.$el.innerHTML).toBe('') vm.foo = {} }) .then(() => { expect(vm.$el.innerHTML).toBe('hello') vm.foo = 0 }) .then(() => { expect(vm.$el.innerHTML).toBe('') vm.foo = [] }) .then(() => { expect(vm.$el.innerHTML).toBe('hello') vm.foo = null }) .then(() => { expect(vm.$el.innerHTML).toBe('') vm.foo = '0' }) .then(() => { expect(vm.$el.innerHTML).toBe('hello') vm.foo = undefined }) .then(() => { expect(vm.$el.innerHTML).toBe('') vm.foo = 1 }) .then(() => { expect(vm.$el.innerHTML).toBe('hello') }) .then(done) }) it('should work well with v-else', done => { const vm = new Vue({ template: `
hello bye
`, data: { foo: true } }).$mount() expect(vm.$el.innerHTML.trim()).toBe('hello') vm.foo = false waitForUpdate(() => { expect(vm.$el.innerHTML.trim()).toBe('bye') vm.foo = {} }) .then(() => { expect(vm.$el.innerHTML.trim()).toBe('hello') vm.foo = 0 }) .then(() => { expect(vm.$el.innerHTML.trim()).toBe('bye') vm.foo = [] }) .then(() => { expect(vm.$el.innerHTML.trim()).toBe('hello') vm.foo = null }) .then(() => { expect(vm.$el.innerHTML.trim()).toBe('bye') vm.foo = '0' }) .then(() => { expect(vm.$el.innerHTML.trim()).toBe('hello') vm.foo = undefined }) .then(() => { expect(vm.$el.innerHTML.trim()).toBe('bye') vm.foo = 1 }) .then(() => { expect(vm.$el.innerHTML.trim()).toBe('hello') }) .then(done) }) it('should work well with v-else-if', done => { const vm = new Vue({ template: `
hello elseif bye
`, data: { foo: true, bar: false } }).$mount() expect(vm.$el.innerHTML.trim()).toBe('hello') vm.foo = false waitForUpdate(() => { expect(vm.$el.innerHTML.trim()).toBe('bye') vm.bar = true }) .then(() => { expect(vm.$el.innerHTML.trim()).toBe('elseif') vm.bar = false }) .then(() => { expect(vm.$el.innerHTML.trim()).toBe('bye') vm.foo = true }) .then(() => { expect(vm.$el.innerHTML.trim()).toBe('hello') vm.foo = false vm.bar = {} }) .then(() => { expect(vm.$el.innerHTML.trim()).toBe('elseif') vm.bar = 0 }) .then(() => { expect(vm.$el.innerHTML.trim()).toBe('bye') vm.bar = [] }) .then(() => { expect(vm.$el.innerHTML.trim()).toBe('elseif') vm.bar = null }) .then(() => { expect(vm.$el.innerHTML.trim()).toBe('bye') vm.bar = '0' }) .then(() => { expect(vm.$el.innerHTML.trim()).toBe('elseif') vm.bar = undefined }) .then(() => { expect(vm.$el.innerHTML.trim()).toBe('bye') vm.bar = 1 }) .then(() => { expect(vm.$el.innerHTML.trim()).toBe('elseif') }) .then(done) }) it('should work well with v-for', done => { const vm = new Vue({ template: `
{{i}}
`, data: { list: [{ value: true }, { value: false }, { value: true }] } }).$mount() expect(vm.$el.innerHTML).toBe('02') vm.list[0].value = false waitForUpdate(() => { expect(vm.$el.innerHTML).toBe('2') vm.list.push({ value: true }) }) .then(() => { expect(vm.$el.innerHTML).toBe( '23' ) vm.list.splice(1, 2) }) .then(() => { expect(vm.$el.innerHTML).toBe('1') }) .then(done) }) it('should work well with v-for and v-else', done => { const vm = new Vue({ template: `
hello bye
`, data: { list: [{ value: true }, { value: false }, { value: true }] } }).$mount() expect(vm.$el.innerHTML.trim()).toBe( 'hellobyehello' ) vm.list[0].value = false waitForUpdate(() => { expect(vm.$el.innerHTML.trim()).toBe( 'byebyehello' ) vm.list.push({ value: true }) }) .then(() => { expect(vm.$el.innerHTML.trim()).toBe( 'byebyehellohello' ) vm.list.splice(1, 2) }) .then(() => { expect(vm.$el.innerHTML.trim()).toBe( 'byehello' ) }) .then(done) }) it('should work with v-for on v-else branch', done => { const vm = new Vue({ template: `
hello {{ item }}
`, data: { list: [1, 2, 3] } }).$mount() expect(vm.$el.textContent.trim()).toBe('123') vm.list.reverse() waitForUpdate(() => { expect(vm.$el.textContent.trim()).toBe('321') }).then(done) }) it('should work properly on component root', done => { const vm = new Vue({ template: `
`, components: { test: { data() { return { ok: true } }, template: '
test
' } } }).$mount() expect(vm.$el.children[0].id).toBe('ok') expect(vm.$el.children[0].className).toBe('inner test') vm.$children[0].ok = false waitForUpdate(() => { // attrs / class modules should not attempt to patch the comment node expect(vm.$el.innerHTML).toBe('') vm.$children[0].ok = true }) .then(() => { expect(vm.$el.children[0].id).toBe('ok') expect(vm.$el.children[0].className).toBe('inner test') }) .then(done) }) it('should maintain stable list to avoid unnecessary patches', done => { const created = vi.fn() const destroyed = vi.fn() const vm = new Vue({ data: { ok: true }, // when the first div is toggled, the second div should be reused // instead of re-created/destroyed template: `
`, components: { test: { template: '
', created, destroyed } } }).$mount() expect(created.mock.calls.length).toBe(1) vm.ok = false waitForUpdate(() => { expect(created.mock.calls.length).toBe(1) expect(destroyed).not.toHaveBeenCalled() }).then(done) }) })