// test cases for edge cases & bug fixes var Vue = require('../../../src/vue') // spies on different objects var _ = require('../../../src/util/debug') var __ = Vue.util describe('Misc', function () { beforeEach(function () { spyOn(_, 'warn') spyOn(__, 'warn') }) it('should handle directive.bind() altering its childNode structure', function () { var vm = new Vue({ el: document.createElement('div'), template: '
{{test}}
', data: { test: 'hi' }, directives: { test: { bind: function () { this.el.insertBefore(document.createTextNode('yo '), this.el.firstChild) } } } }) expect(vm.$el.textContent).toBe('yo hi') }) it('attached/detached hooks for transcluded components', function () { var spy1 = jasmine.createSpy('attached') var spy2 = jasmine.createSpy('detached') var el = document.createElement('div') el.innerHTML = '' document.body.appendChild(el) var vm = new Vue({ el: el, components: { outer: { template: '' }, inner: { template: 'hi', attached: spy1, detached: spy2 } } }) expect(spy1).toHaveBeenCalled() vm.$refs.outter.$remove() expect(spy2).toHaveBeenCalled() }) it('v-for on component root node with replace:true', function () { var el = document.createElement('div') var vm = new Vue({ el: el, template: '', components: { test: { data: function () { return { list: [1, 2, 3] } }, template: '
{{n}}
', replace: true } } }) expect(vm.$el.innerHTML).toBe('
1
2
3
') }) // #922 it('template v-for inside svg', function () { var el = document.createElement('div') new Vue({ el: el, template: '', data: { list: [1, 2, 3] } }) // IE inlines svg namespace var xmlns = /\s?xmlns=".*svg"/ expect(el.innerHTML.replace(xmlns, '')).toBe('123') }) // #1005 it('call lifecycle hooks for child components', function () { Vue.options.replace = true var el = document.createElement('div') var logs = [] function log (n) { return function () { logs.push(n) } } document.body.appendChild(el) var vm = new Vue({ el: el, attached: log(0), ready: log(1), detached: log(2), beforeDestroy: log(3), destroyed: log(4), template: '
', components: { test: { template: 'hi', attached: log(5), ready: log(6), detached: log(7), beforeDestroy: log(8), destroyed: log(9) } } }) expect(vm.$el.innerHTML).toBe('hihi') expect(logs.join()).toBe('0,5,6,5,6,1') logs = [] vm.$destroy(true) expect(logs.join()).toBe('3,8,9,8,9,2,7,7,4') Vue.options.replace = false }) // #1006 it('destroyed hook for components inside v-if', function (done) { var spy = jasmine.createSpy('v-if destroyed hook') var vm = new Vue({ el: document.createElement('div'), template: '', data: { ok: true }, components: { test: { destroyed: spy } } }) vm.ok = false Vue.nextTick(function () { expect(spy).toHaveBeenCalled() done() }) }) it('frozen model, root', function (done) { var vm = new Vue({ el: document.createElement('div'), template: '{{msg}}', data: Object.freeze({ msg: 'hi!' }) }) expect(vm.$el.textContent).toBe('hi!') vm.msg = 'ho!' Vue.nextTick(function () { expect(vm.$el.textContent).toBe('hi!') done() }) }) it('frozen model, non-root', function (done) { var vm = new Vue({ el: document.createElement('div'), template: '{{msg}} {{frozen.msg}}', data: { msg: 'hi', frozen: Object.freeze({ msg: 'frozen' }) } }) expect(vm.$el.textContent).toBe('hi frozen') vm.msg = 'ho' vm.frozen.msg = 'changed' Vue.nextTick(function () { expect(vm.$el.textContent).toBe('ho frozen') done() }) }) it('should not trigger deep/Array watchers when digesting', function (done) { var spy1 = jasmine.createSpy('deep') var spy2 = jasmine.createSpy('Array') var spy3 = jasmine.createSpy('test') var spy4 = jasmine.createSpy('deep-mutated') var vm = new Vue({ el: document.createElement('div'), data: { obj: {}, arr: [], obj2: {} }, watch: { obj: { handler: spy1, deep: true }, arr: spy2, // if the watcher is watching the added value, // it should still trigger properly test: { handler: spy3, deep: true }, // if the object is in fact mutated, it should // still trigger. obj2: { handler: spy4, deep: true } } }) var test = [] var obj2 = vm.obj2 vm.$set('test', test) obj2.$set('test', 123) Vue.nextTick(function () { expect(spy1).not.toHaveBeenCalled() expect(spy2).not.toHaveBeenCalled() expect(spy3).toHaveBeenCalledWith(test, undefined) expect(spy4).toHaveBeenCalledWith(obj2, obj2) done() }) }) it('handle interpolated textarea', function (done) { var el = document.createElement('div') el.innerHTML = '' var vm = new Vue({ el: el, data: { msg: 'test' } }) expect(el.innerHTML).toBe('') vm.msg = 'world' Vue.nextTick(function () { expect(el.innerHTML).toBe('') done() }) }) it('nested object $set should trigger parent array notify', function (done) { var vm = new Vue({ el: document.createElement('div'), template: '{{items | json}}{{items[0].a}}', data: { items: [{}] } }) expect(vm.$el.textContent).toBe(JSON.stringify(vm.items, null, 2)) vm.items[0].$set('a', 123) Vue.nextTick(function () { expect(vm.$el.textContent).toBe(JSON.stringify(vm.items, null, 2) + '123') done() }) }) it('warn unkown custom element', function () { new Vue({ el: document.createElement('div'), template: '' }) expect(hasWarned(__, 'Unknown custom element')).toBe(true) }) })