2014-08-09 05:56:21 +08:00
|
|
|
var Vue = require('../../../src/vue')
|
2014-08-09 07:02:25 +08:00
|
|
|
var nextTick = Vue.nextTick
|
2014-08-09 05:56:21 +08:00
|
|
|
var Watcher = require('../../../src/watcher')
|
|
|
|
|
|
|
|
|
|
describe('Watcher', function () {
|
|
|
|
|
|
|
|
|
|
var vm, spy
|
|
|
|
|
|
|
|
|
|
beforeEach(function () {
|
|
|
|
|
vm = new Vue({
|
2014-08-23 03:03:52 +08:00
|
|
|
filters: {},
|
2014-08-09 05:56:21 +08:00
|
|
|
data: {
|
|
|
|
|
a: 1,
|
|
|
|
|
b: {
|
|
|
|
|
c: 2,
|
|
|
|
|
d: 4
|
|
|
|
|
},
|
|
|
|
|
c: 'c'
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
spy = jasmine.createSpy('watcher')
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('simple path', function (done) {
|
|
|
|
|
var watcher = new Watcher(vm, 'b.c', spy)
|
|
|
|
|
expect(watcher.value).toBe(2)
|
|
|
|
|
vm.b.c = 3
|
2014-08-09 07:02:25 +08:00
|
|
|
nextTick(function () {
|
2014-08-09 05:56:21 +08:00
|
|
|
expect(watcher.value).toBe(3)
|
|
|
|
|
expect(spy).toHaveBeenCalledWith(3, 2)
|
|
|
|
|
vm.b = { c: 4 } // swapping the object
|
2014-08-09 07:02:25 +08:00
|
|
|
nextTick(function () {
|
2014-08-09 05:56:21 +08:00
|
|
|
expect(watcher.value).toBe(4)
|
|
|
|
|
expect(spy).toHaveBeenCalledWith(4, 3)
|
|
|
|
|
done()
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('bracket access path', function (done) {
|
|
|
|
|
var watcher = new Watcher(vm, 'b["c"]', spy)
|
|
|
|
|
expect(watcher.value).toBe(2)
|
|
|
|
|
vm.b.c = 3
|
2014-08-09 07:02:25 +08:00
|
|
|
nextTick(function () {
|
2014-08-09 05:56:21 +08:00
|
|
|
expect(watcher.value).toBe(3)
|
|
|
|
|
expect(spy).toHaveBeenCalledWith(3, 2)
|
|
|
|
|
vm.b = { c: 4 } // swapping the object
|
2014-08-09 07:02:25 +08:00
|
|
|
nextTick(function () {
|
2014-08-09 05:56:21 +08:00
|
|
|
expect(watcher.value).toBe(4)
|
|
|
|
|
expect(spy).toHaveBeenCalledWith(4, 3)
|
|
|
|
|
done()
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('dynamic path', function (done) {
|
|
|
|
|
var watcher = new Watcher(vm, 'b[c]', spy)
|
|
|
|
|
expect(watcher.value).toBe(2)
|
|
|
|
|
vm.b.c = 3
|
2014-08-09 07:02:25 +08:00
|
|
|
nextTick(function () {
|
2014-08-09 05:56:21 +08:00
|
|
|
expect(watcher.value).toBe(3)
|
|
|
|
|
expect(spy).toHaveBeenCalledWith(3, 2)
|
|
|
|
|
vm.c = 'd' // changing the dynamic segment in path
|
2014-08-09 07:02:25 +08:00
|
|
|
nextTick(function () {
|
2014-08-09 05:56:21 +08:00
|
|
|
expect(watcher.value).toBe(4)
|
|
|
|
|
expect(spy).toHaveBeenCalledWith(4, 3)
|
|
|
|
|
done()
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('simple expression', function (done) {
|
|
|
|
|
var watcher = new Watcher(vm, 'a + b.c', spy)
|
|
|
|
|
expect(watcher.value).toBe(3)
|
|
|
|
|
vm.b.c = 3
|
2014-08-09 07:02:25 +08:00
|
|
|
nextTick(function () {
|
2014-08-09 05:56:21 +08:00
|
|
|
expect(watcher.value).toBe(4)
|
2014-08-09 07:02:25 +08:00
|
|
|
expect(spy.calls.count()).toBe(1)
|
2014-08-09 05:56:21 +08:00
|
|
|
expect(spy).toHaveBeenCalledWith(4, 3)
|
|
|
|
|
// change two dependencies at once
|
|
|
|
|
vm.a = 2
|
|
|
|
|
vm.b.c = 4
|
2014-08-09 07:02:25 +08:00
|
|
|
nextTick(function () {
|
2014-08-09 05:56:21 +08:00
|
|
|
expect(watcher.value).toBe(6)
|
|
|
|
|
// should trigger only once callback,
|
|
|
|
|
// because it was in the same event loop.
|
2014-08-09 07:02:25 +08:00
|
|
|
expect(spy.calls.count()).toBe(2)
|
2014-08-09 05:56:21 +08:00
|
|
|
expect(spy).toHaveBeenCalledWith(6, 4)
|
|
|
|
|
done()
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('ternary expression', function (done) {
|
|
|
|
|
// we're actually testing for the dependency re-calculation here
|
|
|
|
|
var watcher = new Watcher(vm, 'a > 1 ? b.c : b.d', spy)
|
|
|
|
|
expect(watcher.value).toBe(4)
|
|
|
|
|
vm.a = 2
|
2014-08-09 07:02:25 +08:00
|
|
|
nextTick(function () {
|
2014-08-09 05:56:21 +08:00
|
|
|
expect(watcher.value).toBe(2)
|
|
|
|
|
expect(spy).toHaveBeenCalledWith(2, 4)
|
|
|
|
|
vm.b.c = 3
|
2014-08-09 07:02:25 +08:00
|
|
|
nextTick(function () {
|
2014-08-09 05:56:21 +08:00
|
|
|
expect(watcher.value).toBe(3)
|
|
|
|
|
expect(spy).toHaveBeenCalledWith(3, 2)
|
|
|
|
|
done()
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('non-existent path, $add later', function (done) {
|
|
|
|
|
var watcher = new Watcher(vm, 'd.e', spy)
|
2014-08-10 06:57:46 +08:00
|
|
|
var watcher2 = new Watcher(vm, 'b.e', spy)
|
2014-08-09 05:56:21 +08:00
|
|
|
expect(watcher.value).toBeUndefined()
|
2014-08-10 06:57:46 +08:00
|
|
|
expect(watcher2.value).toBeUndefined()
|
2014-08-25 12:07:58 +08:00
|
|
|
vm.$add('d', { e: 123 })
|
2014-08-10 06:57:46 +08:00
|
|
|
vm.b.$add('e', 234)
|
2014-08-09 07:02:25 +08:00
|
|
|
nextTick(function () {
|
2014-08-09 05:56:21 +08:00
|
|
|
expect(watcher.value).toBe(123)
|
2014-08-10 06:57:46 +08:00
|
|
|
expect(watcher2.value).toBe(234)
|
2014-08-09 05:56:21 +08:00
|
|
|
expect(spy).toHaveBeenCalledWith(123, undefined)
|
2014-08-10 06:57:46 +08:00
|
|
|
expect(spy).toHaveBeenCalledWith(234, undefined)
|
2014-08-09 05:56:21 +08:00
|
|
|
done()
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('$delete', function (done) {
|
|
|
|
|
var watcher = new Watcher(vm, 'b.c', spy)
|
|
|
|
|
expect(watcher.value).toBe(2)
|
2014-08-25 12:07:58 +08:00
|
|
|
vm.$delete('b')
|
2014-08-09 07:02:25 +08:00
|
|
|
nextTick(function () {
|
2014-08-09 05:56:21 +08:00
|
|
|
expect(watcher.value).toBeUndefined()
|
|
|
|
|
expect(spy).toHaveBeenCalledWith(undefined, 2)
|
|
|
|
|
done()
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('swapping $data', function (done) {
|
|
|
|
|
var watcher = new Watcher(vm, 'b.c', spy)
|
|
|
|
|
expect(watcher.value).toBe(2)
|
|
|
|
|
vm.$data = { b: { c: 3}}
|
2014-08-09 07:02:25 +08:00
|
|
|
nextTick(function () {
|
2014-08-09 05:56:21 +08:00
|
|
|
expect(watcher.value).toBe(3)
|
|
|
|
|
expect(spy).toHaveBeenCalledWith(3, 2)
|
|
|
|
|
done()
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('path containing $data', function (done) {
|
|
|
|
|
var watcher = new Watcher(vm, '$data.b.c', spy)
|
|
|
|
|
expect(watcher.value).toBe(2)
|
|
|
|
|
vm.b = { c: 3 }
|
2014-08-09 07:02:25 +08:00
|
|
|
nextTick(function () {
|
2014-08-09 05:56:21 +08:00
|
|
|
expect(watcher.value).toBe(3)
|
|
|
|
|
expect(spy).toHaveBeenCalledWith(3, 2)
|
|
|
|
|
vm.$data = { b: {c: 4}}
|
2014-08-09 07:02:25 +08:00
|
|
|
nextTick(function () {
|
2014-08-09 05:56:21 +08:00
|
|
|
expect(watcher.value).toBe(4)
|
|
|
|
|
expect(spy).toHaveBeenCalledWith(4, 3)
|
|
|
|
|
done()
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('watching $data', function (done) {
|
|
|
|
|
var oldData = vm.$data
|
|
|
|
|
var watcher = new Watcher(vm, '$data', spy)
|
|
|
|
|
expect(watcher.value).toBe(oldData)
|
|
|
|
|
vm.a = 2
|
2014-08-09 07:02:25 +08:00
|
|
|
nextTick(function () {
|
2014-08-09 05:56:21 +08:00
|
|
|
expect(spy).toHaveBeenCalledWith(oldData, oldData)
|
|
|
|
|
var newData = {}
|
|
|
|
|
vm.$data = newData
|
2014-08-09 07:02:25 +08:00
|
|
|
nextTick(function() {
|
2014-08-09 05:56:21 +08:00
|
|
|
expect(spy).toHaveBeenCalledWith(newData, oldData)
|
|
|
|
|
expect(watcher.value).toBe(newData)
|
|
|
|
|
done()
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
2014-08-23 22:38:13 +08:00
|
|
|
it('watching parent scope properties', function (done) {
|
2014-08-28 23:58:56 +08:00
|
|
|
var child = vm.$addChild()
|
2014-08-23 22:38:13 +08:00
|
|
|
var spy2 = jasmine.createSpy('watch')
|
|
|
|
|
var watcher1 = new Watcher(child, '$data', spy)
|
|
|
|
|
var watcher2 = new Watcher(child, 'a', spy2)
|
|
|
|
|
vm.a = 123
|
|
|
|
|
nextTick(function () {
|
|
|
|
|
// $data should only be called on self data change
|
|
|
|
|
expect(watcher1.value).toBe(child.$data)
|
|
|
|
|
expect(spy.calls.count()).toBe(0)
|
|
|
|
|
expect(watcher2.value).toBe(123)
|
|
|
|
|
expect(spy2).toHaveBeenCalledWith(123, 1)
|
|
|
|
|
done()
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
2014-08-09 05:56:21 +08:00
|
|
|
it('callback context', function (done) {
|
|
|
|
|
var context = {}
|
|
|
|
|
var watcher = new Watcher(vm, 'b.c', function () {
|
|
|
|
|
spy.apply(this, arguments)
|
|
|
|
|
expect(this).toBe(context)
|
|
|
|
|
}, context)
|
|
|
|
|
vm.b.c = 3
|
2014-08-09 07:02:25 +08:00
|
|
|
nextTick(function () {
|
2014-08-09 05:56:21 +08:00
|
|
|
expect(spy).toHaveBeenCalledWith(3, 2)
|
|
|
|
|
done()
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('filters', function (done) {
|
|
|
|
|
vm.$options.filters.test = function (val, multi) {
|
|
|
|
|
return val * multi
|
|
|
|
|
}
|
|
|
|
|
vm.$options.filters.test2 = function (val, str) {
|
|
|
|
|
return val + str
|
|
|
|
|
}
|
|
|
|
|
var watcher = new Watcher(vm, 'b.c', spy, null, [
|
|
|
|
|
{ name: 'test', args: [3] },
|
|
|
|
|
{ name: 'test2', args: ['yo']}
|
|
|
|
|
])
|
|
|
|
|
expect(watcher.value).toBe('6yo')
|
|
|
|
|
vm.b.c = 3
|
2014-08-09 07:02:25 +08:00
|
|
|
nextTick(function () {
|
2014-08-09 05:56:21 +08:00
|
|
|
expect(watcher.value).toBe('9yo')
|
|
|
|
|
expect(spy).toHaveBeenCalledWith('9yo', '6yo')
|
|
|
|
|
done()
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('setter', function (done) {
|
|
|
|
|
vm.$options.filters.test = {
|
|
|
|
|
write: function (val, oldVal, arg) {
|
|
|
|
|
return val > arg ? val : oldVal
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
var watcher = new Watcher(vm, 'b["c"]', spy, null, [
|
|
|
|
|
{ name: 'test', args: [5] }
|
|
|
|
|
], true)
|
|
|
|
|
expect(watcher.value).toBe(2)
|
|
|
|
|
watcher.set(4) // shoud not change the value
|
2014-08-09 07:02:25 +08:00
|
|
|
nextTick(function () {
|
2014-08-09 05:56:21 +08:00
|
|
|
expect(vm.b.c).toBe(2)
|
|
|
|
|
expect(watcher.value).toBe(2)
|
2014-08-09 07:02:25 +08:00
|
|
|
expect(spy.calls.count()).toBe(0)
|
2014-08-09 05:56:21 +08:00
|
|
|
watcher.set(6)
|
2014-08-09 07:02:25 +08:00
|
|
|
nextTick(function () {
|
2014-08-09 05:56:21 +08:00
|
|
|
expect(vm.b.c).toBe(6)
|
|
|
|
|
expect(watcher.value).toBe(6)
|
|
|
|
|
expect(spy).toHaveBeenCalledWith(6, 2)
|
|
|
|
|
done()
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
2014-08-15 23:10:42 +08:00
|
|
|
it('set non-existent values', function (done) {
|
|
|
|
|
var watcher = new Watcher(vm, 'd.e.f', spy)
|
|
|
|
|
expect(watcher.value).toBeUndefined()
|
|
|
|
|
watcher.set(123)
|
|
|
|
|
nextTick(function () {
|
|
|
|
|
expect(vm.d.e.f).toBe(123)
|
|
|
|
|
expect(watcher.value).toBe(123)
|
|
|
|
|
expect(spy).toHaveBeenCalledWith(123, undefined)
|
|
|
|
|
done()
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
2014-08-09 07:02:25 +08:00
|
|
|
it('teardown', function (done) {
|
|
|
|
|
var watcher = new Watcher(vm, 'b.c', spy)
|
|
|
|
|
watcher.teardown()
|
|
|
|
|
vm.b.c = 3
|
|
|
|
|
nextTick(function () {
|
|
|
|
|
expect(watcher.active).toBe(false)
|
|
|
|
|
expect(spy.calls.count()).toBe(0)
|
|
|
|
|
done()
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
2014-08-09 05:56:21 +08:00
|
|
|
})
|