mirror of
https://gitee.com/vuejs/vue.git
synced 2024-12-05 05:27:59 +08:00
instance methods tests
This commit is contained in:
parent
f5bc3e584f
commit
20758d554f
@ -29,6 +29,7 @@ export function lifecycleMixin (Vue: Class<Component>) {
|
|||||||
if (!vm.$options.render) {
|
if (!vm.$options.render) {
|
||||||
vm.$options.render = () => emptyVNode
|
vm.$options.render = () => emptyVNode
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
|
/* istanbul ignore if */
|
||||||
if (vm.$options.template) {
|
if (vm.$options.template) {
|
||||||
warn(
|
warn(
|
||||||
'You are using the runtime-only build of Vue where the template ' +
|
'You are using the runtime-only build of Vue where the template ' +
|
||||||
@ -120,7 +121,7 @@ export function lifecycleMixin (Vue: Class<Component>) {
|
|||||||
|
|
||||||
Vue.prototype.$destroy = function () {
|
Vue.prototype.$destroy = function () {
|
||||||
const vm: Component = this
|
const vm: Component = this
|
||||||
if (vm._isDestroyed) {
|
if (vm._isBeingDestroyed) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
callHook(vm, 'beforeDestroy')
|
callHook(vm, 'beforeDestroy')
|
||||||
@ -131,6 +132,9 @@ export function lifecycleMixin (Vue: Class<Component>) {
|
|||||||
remove(parent.$children, vm)
|
remove(parent.$children, vm)
|
||||||
}
|
}
|
||||||
// teardown watchers
|
// teardown watchers
|
||||||
|
if (vm._watcher) {
|
||||||
|
vm._watcher.teardown()
|
||||||
|
}
|
||||||
let i = vm._watchers.length
|
let i = vm._watchers.length
|
||||||
while (i--) {
|
while (i--) {
|
||||||
vm._watchers[i].teardown()
|
vm._watchers[i].teardown()
|
||||||
|
59
test/unit/features/instance/methods-events.spec.js
Normal file
59
test/unit/features/instance/methods-events.spec.js
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import Vue from 'vue'
|
||||||
|
|
||||||
|
describe('Instance methods events', () => {
|
||||||
|
let vm, spy
|
||||||
|
beforeEach(() => {
|
||||||
|
vm = new Vue()
|
||||||
|
spy = jasmine.createSpy('emitter')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('$on', () => {
|
||||||
|
vm.$on('test', function () {
|
||||||
|
// expect correct context
|
||||||
|
expect(this).toBe(vm)
|
||||||
|
spy.apply(this, arguments)
|
||||||
|
})
|
||||||
|
vm.$emit('test', 1, 2, 3, 4)
|
||||||
|
expect(spy.calls.count()).toBe(1)
|
||||||
|
expect(spy).toHaveBeenCalledWith(1, 2, 3, 4)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('$once', () => {
|
||||||
|
vm.$once('test', spy)
|
||||||
|
vm.$emit('test', 1, 2, 3)
|
||||||
|
vm.$emit('test', 2, 3, 4)
|
||||||
|
expect(spy.calls.count()).toBe(1)
|
||||||
|
expect(spy).toHaveBeenCalledWith(1, 2, 3)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('$off', () => {
|
||||||
|
vm.$on('test1', spy)
|
||||||
|
vm.$on('test2', spy)
|
||||||
|
vm.$off()
|
||||||
|
vm.$emit('test1')
|
||||||
|
vm.$emit('test2')
|
||||||
|
expect(spy).not.toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('$off event', () => {
|
||||||
|
vm.$on('test1', spy)
|
||||||
|
vm.$on('test2', spy)
|
||||||
|
vm.$off('test1')
|
||||||
|
vm.$off('test1') // test off something that's already off
|
||||||
|
vm.$emit('test1', 1)
|
||||||
|
vm.$emit('test2', 2)
|
||||||
|
expect(spy.calls.count()).toBe(1)
|
||||||
|
expect(spy).toHaveBeenCalledWith(2)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('$off event + fn', () => {
|
||||||
|
var spy2 = jasmine.createSpy('emitter')
|
||||||
|
vm.$on('test', spy)
|
||||||
|
vm.$on('test', spy2)
|
||||||
|
vm.$off('test', spy)
|
||||||
|
vm.$emit('test', 1, 2, 3)
|
||||||
|
expect(spy).not.toHaveBeenCalled()
|
||||||
|
expect(spy2.calls.count()).toBe(1)
|
||||||
|
expect(spy2).toHaveBeenCalledWith(1, 2, 3)
|
||||||
|
})
|
||||||
|
})
|
113
test/unit/features/instance/methods-lifecycle.spec.js
Normal file
113
test/unit/features/instance/methods-lifecycle.spec.js
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
import Vue from 'vue'
|
||||||
|
|
||||||
|
describe('Instance methods lifecycle', () => {
|
||||||
|
describe('$mount', () => {
|
||||||
|
it('empty mount', () => {
|
||||||
|
const vm = new Vue({
|
||||||
|
data: { msg: 'hi' },
|
||||||
|
template: '<div>{{ msg }}</div>'
|
||||||
|
}).$mount()
|
||||||
|
expect(vm.$el.tagName).toBe('DIV')
|
||||||
|
expect(vm.$el.textContent).toBe('hi')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('mount to existing element', () => {
|
||||||
|
const el = document.createElement('div')
|
||||||
|
el.innerHTML = '{{ msg }}'
|
||||||
|
const vm = new Vue({
|
||||||
|
data: { msg: 'hi' }
|
||||||
|
}).$mount(el)
|
||||||
|
expect(vm.$el.tagName).toBe('DIV')
|
||||||
|
expect(vm.$el.textContent).toBe('hi')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('mount to id', () => {
|
||||||
|
const el = document.createElement('div')
|
||||||
|
el.id = 'mount-test'
|
||||||
|
el.innerHTML = '{{ msg }}'
|
||||||
|
document.body.appendChild(el)
|
||||||
|
const vm = new Vue({
|
||||||
|
data: { msg: 'hi' }
|
||||||
|
}).$mount('#mount-test')
|
||||||
|
expect(vm.$el.tagName).toBe('DIV')
|
||||||
|
expect(vm.$el.textContent).toBe('hi')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('$destroy', () => {
|
||||||
|
it('remove self from parent', () => {
|
||||||
|
const vm = new Vue({
|
||||||
|
template: '<test></test>',
|
||||||
|
components: {
|
||||||
|
test: { template: '<div></div>' }
|
||||||
|
}
|
||||||
|
}).$mount()
|
||||||
|
vm.$children[0].$destroy()
|
||||||
|
expect(vm.$children.length).toBe(0)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('teardown watchers', () => {
|
||||||
|
const vm = new Vue({
|
||||||
|
data: { a: 123 },
|
||||||
|
template: '<div></div>'
|
||||||
|
}).$mount()
|
||||||
|
vm.$watch('a', () => {})
|
||||||
|
vm.$destroy()
|
||||||
|
expect(vm._watcher.active).toBe(false)
|
||||||
|
expect(vm._watchers.every(w => !w.active)).toBe(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('remove self from data observer', () => {
|
||||||
|
const vm = new Vue({ data: { a: 1 }})
|
||||||
|
vm.$destroy()
|
||||||
|
expect(vm.$data.__ob__.vms.length).toBe(0)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('avoid duplicate calls', () => {
|
||||||
|
const spy = jasmine.createSpy('destroy')
|
||||||
|
const vm = new Vue({
|
||||||
|
beforeDestroy: spy
|
||||||
|
})
|
||||||
|
vm.$destroy()
|
||||||
|
vm.$destroy()
|
||||||
|
expect(spy.calls.count()).toBe(1)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('$forceUpdate', () => {
|
||||||
|
it('should force update', done => {
|
||||||
|
const vm = new Vue({
|
||||||
|
data: {
|
||||||
|
a: {}
|
||||||
|
},
|
||||||
|
template: '<div>{{ a.b }}</div>'
|
||||||
|
}).$mount()
|
||||||
|
expect(vm.$el.textContent).toBe('')
|
||||||
|
vm.a.b = 'foo'
|
||||||
|
waitForUpdate(() => {
|
||||||
|
// should not work because adding new property
|
||||||
|
expect(vm.$el.textContent).toBe('')
|
||||||
|
vm.$forceUpdate()
|
||||||
|
}).then(() => {
|
||||||
|
expect(vm.$el.textContent).toBe('foo')
|
||||||
|
}).then(done)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('$nextTick', () => {
|
||||||
|
it('should be called after DOM update in correct context', done => {
|
||||||
|
const vm = new Vue({
|
||||||
|
template: '<div>{{ msg }}</div>',
|
||||||
|
data: {
|
||||||
|
msg: 'foo'
|
||||||
|
}
|
||||||
|
}).$mount()
|
||||||
|
vm.msg = 'bar'
|
||||||
|
vm.$nextTick(function () {
|
||||||
|
expect(this).toBe(vm)
|
||||||
|
expect(vm.$el.textContent).toBe('bar')
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
70
test/unit/features/instance/methods-watch.spec.js
Normal file
70
test/unit/features/instance/methods-watch.spec.js
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
import Vue from 'vue'
|
||||||
|
|
||||||
|
describe('Instance methods watch', () => {
|
||||||
|
let vm, spy
|
||||||
|
beforeEach(() => {
|
||||||
|
vm = new Vue({
|
||||||
|
data: {
|
||||||
|
a: {
|
||||||
|
b: 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
spy = jasmine.createSpy('watch')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('basic usage', done => {
|
||||||
|
vm.$watch('a.b', spy)
|
||||||
|
vm.a.b = 2
|
||||||
|
waitForUpdate(() => {
|
||||||
|
expect(spy.calls.count()).toBe(1)
|
||||||
|
expect(spy).toHaveBeenCalledWith(2, 1)
|
||||||
|
vm.a = { b: 3 }
|
||||||
|
}).then(() => {
|
||||||
|
expect(spy.calls.count()).toBe(2)
|
||||||
|
expect(spy).toHaveBeenCalledWith(3, 2)
|
||||||
|
}).then(done)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('immediate', () => {
|
||||||
|
vm.$watch('a.b', spy, { immediate: true })
|
||||||
|
expect(spy.calls.count()).toBe(1)
|
||||||
|
expect(spy).toHaveBeenCalledWith(1)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('unwatch', done => {
|
||||||
|
const unwatch = vm.$watch('a.b', spy)
|
||||||
|
unwatch()
|
||||||
|
vm.a.b = 2
|
||||||
|
waitForUpdate(() => {
|
||||||
|
expect(spy.calls.count()).toBe(0)
|
||||||
|
}).then(done)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('function watch', done => {
|
||||||
|
vm.$watch(function () {
|
||||||
|
return this.a.b
|
||||||
|
}, spy)
|
||||||
|
vm.a.b = 2
|
||||||
|
waitForUpdate(() => {
|
||||||
|
expect(spy).toHaveBeenCalledWith(2, 1)
|
||||||
|
}).then(done)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('deep watch', done => {
|
||||||
|
var oldA = vm.a
|
||||||
|
vm.$watch('a', spy, { deep: true })
|
||||||
|
vm.a.b = 2
|
||||||
|
waitForUpdate(() => {
|
||||||
|
expect(spy).toHaveBeenCalledWith(oldA, oldA)
|
||||||
|
vm.a = { b: 3 }
|
||||||
|
}).then(() => {
|
||||||
|
expect(spy).toHaveBeenCalledWith(vm.a, oldA)
|
||||||
|
}).then(done)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('warn expresssion', () => {
|
||||||
|
vm.$watch('a + b', spy)
|
||||||
|
expect('Watcher only accepts simple dot-delimited paths').toHaveBeenWarned()
|
||||||
|
})
|
||||||
|
})
|
Loading…
Reference in New Issue
Block a user