1import Vue from 'vue'23describe('Options lifecycle hooks', () => {4 let spy5 beforeEach(() => {6 spy = vi.fn()7 })89 describe('beforeCreate', () => {10 it('should allow modifying options', () => {11 const vm = new Vue({12 data: {13 a: 114 },15 beforeCreate() {16 spy()17 expect(this.a).toBeUndefined()18 this.$options.computed = {19 b() {20 return this.a + 121 }22 }23 }24 })25 expect(spy).toHaveBeenCalled()26 expect(vm.b).toBe(2)27 })28 })2930 describe('created', () => {31 it('should have completed observation', () => {32 new Vue({33 data: {34 a: 135 },36 created() {37 expect(this.a).toBe(1)38 spy()39 }40 })41 expect(spy).toHaveBeenCalled()42 })43 })4445 describe('beforeMount', () => {46 it('should not have mounted', () => {47 const vm = new Vue({48 render() {},49 beforeMount() {50 spy()51 expect(this._isMounted).toBe(false)52 expect(this.$el).toBeUndefined() // due to empty mount53 expect(this._vnode).toBeNull()54 expect(this._watcher).toBeNull()55 }56 })57 expect(spy).not.toHaveBeenCalled()58 vm.$mount()59 expect(spy).toHaveBeenCalled()60 })61 })6263 describe('mounted', () => {64 it('should have mounted', () => {65 const vm = new Vue({66 template: '<div></div>',67 mounted() {68 spy()69 expect(this._isMounted).toBe(true)70 expect(this.$el.tagName).toBe('DIV')71 expect(this._vnode.tag).toBe('div')72 }73 })74 expect(spy).not.toHaveBeenCalled()75 vm.$mount()76 expect(spy).toHaveBeenCalled()77 })7879 // #389880 it('should call for manually mounted instance with parent', () => {81 const parent = new Vue()82 expect(spy).not.toHaveBeenCalled()83 new Vue({84 parent,85 template: '<div></div>',86 mounted() {87 spy()88 }89 }).$mount()90 expect(spy).toHaveBeenCalled()91 })9293 it('should mount child parent in correct order', () => {94 const calls: any[] = []95 new Vue({96 template: '<div><test></test></div>',97 mounted() {98 calls.push('parent')99 },100 components: {101 test: {102 template: '<nested></nested>',103 mounted() {104 expect(this.$el.parentNode).toBeTruthy()105 calls.push('child')106 },107 components: {108 nested: {109 template: '<div></div>',110 mounted() {111 expect(this.$el.parentNode).toBeTruthy()112 calls.push('nested')113 }114 }115 }116 }117 }118 }).$mount()119 expect(calls).toEqual(['nested', 'child', 'parent'])120 })121 })122123 describe('beforeUpdate', () => {124 it('should be called before update', done => {125 const vm = new Vue({126 template: '<div>{{ msg }}</div>',127 data: { msg: 'foo' },128 beforeUpdate() {129 spy()130 expect(this.$el.textContent).toBe('foo')131 }132 }).$mount()133 expect(spy).not.toHaveBeenCalled()134 vm.msg = 'bar'135 expect(spy).not.toHaveBeenCalled() // should be async136 waitForUpdate(() => {137 expect(spy).toHaveBeenCalled()138 }).then(done)139 })140141 it('should be called before render and allow mutating state', done => {142 const vm = new Vue({143 template: '<div>{{ msg }}</div>',144 data: { msg: 'foo' },145 beforeUpdate() {146 this.msg += '!'147 }148 }).$mount()149 expect(vm.$el.textContent).toBe('foo')150 vm.msg = 'bar'151 waitForUpdate(() => {152 expect(vm.$el.textContent).toBe('bar!')153 }).then(done)154 })155156 // #8076157 it('should not be called after destroy', done => {158 const beforeUpdate = vi.fn()159 const destroyed = vi.fn()160161 Vue.component('todo', {162 template: '<div>{{todo.done}}</div>',163 props: ['todo'],164 destroyed,165 beforeUpdate166 })167168 const vm = new Vue({169 template: `170 <div>171 <todo v-for="t in pendingTodos" :todo="t" :key="t.id"></todo>172 </div>173 `,174 data() {175 return {176 todos: [{ id: 1, done: false }]177 }178 },179 computed: {180 pendingTodos() {181 return this.todos.filter(t => !t.done)182 }183 }184 }).$mount()185186 vm.todos[0].done = true187 waitForUpdate(() => {188 expect(destroyed).toHaveBeenCalled()189 expect(beforeUpdate).not.toHaveBeenCalled()190 }).then(done)191 })192 })193194 describe('updated', () => {195 it('should be called after update', done => {196 const vm = new Vue({197 template: '<div>{{ msg }}</div>',198 data: { msg: 'foo' },199 updated() {200 spy()201 expect(this.$el.textContent).toBe('bar')202 }203 }).$mount()204 expect(spy).not.toHaveBeenCalled()205 vm.msg = 'bar'206 expect(spy).not.toHaveBeenCalled() // should be async207 waitForUpdate(() => {208 expect(spy).toHaveBeenCalled()209 }).then(done)210 })211212 it('should be called after children are updated', done => {213 const calls: any[] = []214 const vm = new Vue({215 template: '<div><test ref="child">{{ msg }}</test></div>',216 data: { msg: 'foo' },217 components: {218 test: {219 template: `<div><slot></slot></div>`,220 updated() {221 expect(this.$el.textContent).toBe('bar')222 calls.push('child')223 }224 }225 },226 updated() {227 expect(this.$el.textContent).toBe('bar')228 calls.push('parent')229 }230 }).$mount()231232 expect(calls).toEqual([])233 vm.msg = 'bar'234 expect(calls).toEqual([])235 waitForUpdate(() => {236 expect(calls).toEqual(['child', 'parent'])237 }).then(done)238 })239240 // #8076241 it('should not be called after destroy', done => {242 const updated = vi.fn()243 const destroyed = vi.fn()244245 Vue.component('todo', {246 template: '<div>{{todo.done}}</div>',247 props: ['todo'],248 destroyed,249 updated250 })251252 const vm = new Vue({253 template: `254 <div>255 <todo v-for="t in pendingTodos" :todo="t" :key="t.id"></todo>256 </div>257 `,258 data() {259 return {260 todos: [{ id: 1, done: false }]261 }262 },263 computed: {264 pendingTodos() {265 return this.todos.filter(t => !t.done)266 }267 }268 }).$mount()269270 vm.todos[0].done = true271 waitForUpdate(() => {272 expect(destroyed).toHaveBeenCalled()273 expect(updated).not.toHaveBeenCalled()274 }).then(done)275 })276 })277278 describe('beforeDestroy', () => {279 it('should be called before destroy', () => {280 const vm = new Vue({281 render() {},282 beforeDestroy() {283 spy()284 expect(this._isBeingDestroyed).toBe(false)285 expect(this._isDestroyed).toBe(false)286 }287 }).$mount()288 expect(spy).not.toHaveBeenCalled()289 vm.$destroy()290 vm.$destroy()291 expect(spy).toHaveBeenCalled()292 expect(spy.mock.calls.length).toBe(1)293 })294 })295296 describe('destroyed', () => {297 it('should be called after destroy', () => {298 const vm = new Vue({299 render() {},300 destroyed() {301 spy()302 expect(this._isBeingDestroyed).toBe(true)303 expect(this._isDestroyed).toBe(true)304 }305 }).$mount()306 expect(spy).not.toHaveBeenCalled()307 vm.$destroy()308 vm.$destroy()309 expect(spy).toHaveBeenCalled()310 expect(spy.mock.calls.length).toBe(1)311 })312 })313314 it('should emit hook events', () => {315 const created = vi.fn()316 const mounted = vi.fn()317 const destroyed = vi.fn()318 const vm = new Vue({319 render() {},320 beforeCreate() {321 this.$on('hook:created', created)322 this.$on('hook:mounted', mounted)323 this.$on('hook:destroyed', destroyed)324 }325 })326327 expect(created).toHaveBeenCalled()328 expect(mounted).not.toHaveBeenCalled()329 expect(destroyed).not.toHaveBeenCalled()330331 vm.$mount()332 expect(mounted).toHaveBeenCalled()333 expect(destroyed).not.toHaveBeenCalled()334335 vm.$destroy()336 expect(destroyed).toHaveBeenCalled()337 })338})
Findings
✓ No findings reported for this file.