2013-09-10 06:04:33 +08:00
|
|
|
describe('UNIT: ViewModel', function () {
|
2013-09-11 06:57:47 +08:00
|
|
|
|
|
|
|
mock('vm-test', '{{a.b.c}}')
|
|
|
|
var data = {
|
|
|
|
b: {
|
|
|
|
c: 12345
|
|
|
|
}
|
|
|
|
},
|
|
|
|
arr = [1, 2, 3],
|
2013-12-08 06:29:17 +08:00
|
|
|
vm = new Vue({
|
2013-10-03 06:14:29 +08:00
|
|
|
el: '#vm-test',
|
2013-10-12 06:24:53 +08:00
|
|
|
scope: {
|
2013-09-11 06:57:47 +08:00
|
|
|
a: data,
|
|
|
|
b: arr
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('.$set()', function () {
|
|
|
|
vm.$set('a.b.c', 54321)
|
|
|
|
it('should set correct value', function () {
|
|
|
|
assert.strictEqual(data.b.c, 54321)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('.$watch()', function () {
|
|
|
|
|
|
|
|
it('should trigger callback when a plain value changes', function () {
|
|
|
|
var val
|
|
|
|
vm.$watch('a.b.c', function (newVal) {
|
2013-10-08 13:14:40 +08:00
|
|
|
val = newVal
|
2013-09-11 06:57:47 +08:00
|
|
|
})
|
|
|
|
data.b.c = 'new value!'
|
|
|
|
assert.strictEqual(val, data.b.c)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should trigger callback when an object value changes', function () {
|
|
|
|
var val, subVal, rootVal,
|
|
|
|
target = { c: 'hohoho' }
|
|
|
|
vm.$watch('a.b', function (newVal) {
|
|
|
|
val = newVal
|
|
|
|
})
|
|
|
|
vm.$watch('a.b.c', function (newVal) {
|
|
|
|
subVal = newVal
|
|
|
|
})
|
|
|
|
vm.$watch('a', function (newVal) {
|
|
|
|
rootVal = newVal
|
|
|
|
})
|
|
|
|
data.b = target
|
|
|
|
assert.strictEqual(val, target)
|
|
|
|
assert.strictEqual(subVal, target.c)
|
|
|
|
vm.a = 'hehehe'
|
|
|
|
assert.strictEqual(rootVal, 'hehehe')
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should trigger callback when an array mutates', function () {
|
|
|
|
var val, mut
|
|
|
|
vm.$watch('b', function (array, mutation) {
|
|
|
|
val = array
|
|
|
|
mut = mutation
|
|
|
|
})
|
|
|
|
arr.push(4)
|
|
|
|
assert.strictEqual(val, arr)
|
|
|
|
assert.strictEqual(mut.method, 'push')
|
|
|
|
assert.strictEqual(mut.args.length, 1)
|
|
|
|
assert.strictEqual(mut.args[0], 4)
|
|
|
|
})
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('.$unwatch()', function () {
|
|
|
|
|
|
|
|
it('should unwatch the stuff', function () {
|
|
|
|
var triggered = false
|
2013-10-08 13:14:40 +08:00
|
|
|
vm.$watch('a.b.c', function () {
|
2013-09-11 06:57:47 +08:00
|
|
|
triggered = true
|
|
|
|
})
|
2013-10-08 13:14:40 +08:00
|
|
|
vm.$watch('a', function () {
|
2013-09-11 06:57:47 +08:00
|
|
|
triggered = true
|
|
|
|
})
|
2013-10-08 13:14:40 +08:00
|
|
|
vm.$watch('b', function () {
|
2013-09-11 06:57:47 +08:00
|
|
|
triggered = true
|
|
|
|
})
|
|
|
|
vm.$unwatch('a')
|
|
|
|
vm.$unwatch('b')
|
|
|
|
vm.$unwatch('a.b.c')
|
|
|
|
vm.a = { b: { c:123123 }}
|
|
|
|
vm.b.push(5)
|
|
|
|
assert.notOk(triggered)
|
|
|
|
})
|
|
|
|
|
|
|
|
})
|
|
|
|
|
2013-10-09 11:19:12 +08:00
|
|
|
describe('.$on', function () {
|
|
|
|
|
|
|
|
it('should register listener on vm\'s compiler\'s emitter', function () {
|
2013-12-08 06:29:17 +08:00
|
|
|
var t = new Vue(),
|
2013-10-09 11:19:12 +08:00
|
|
|
triggered = false,
|
|
|
|
msg = 'on test'
|
|
|
|
t.$on('test', function (m) {
|
|
|
|
assert.strictEqual(m, msg)
|
|
|
|
triggered = true
|
|
|
|
})
|
|
|
|
t.$compiler.emitter.emit('test', msg)
|
|
|
|
assert.ok(triggered)
|
|
|
|
})
|
|
|
|
|
2013-10-09 10:26:25 +08:00
|
|
|
})
|
|
|
|
|
2013-10-18 00:19:58 +08:00
|
|
|
describe('.$once', function () {
|
|
|
|
|
|
|
|
it('should invoke the listener only once', function () {
|
2013-12-08 06:29:17 +08:00
|
|
|
var t = new Vue(),
|
2013-10-18 00:19:58 +08:00
|
|
|
triggered = 0,
|
|
|
|
msg = 'on once'
|
|
|
|
t.$once('test', function (m) {
|
|
|
|
assert.strictEqual(m, msg)
|
|
|
|
triggered++
|
|
|
|
})
|
|
|
|
t.$compiler.emitter.emit('test', msg)
|
|
|
|
t.$compiler.emitter.emit('test', msg)
|
|
|
|
assert.strictEqual(triggered, 1)
|
|
|
|
})
|
|
|
|
|
|
|
|
})
|
|
|
|
|
2013-10-09 11:19:12 +08:00
|
|
|
describe('$off', function () {
|
|
|
|
|
|
|
|
it('should turn off the listener', function () {
|
2013-12-08 06:29:17 +08:00
|
|
|
var t = new Vue(),
|
2013-10-09 11:19:12 +08:00
|
|
|
triggered1 = false,
|
|
|
|
triggered2 = false,
|
|
|
|
f1 = function () {
|
|
|
|
triggered1 = true
|
|
|
|
},
|
|
|
|
f2 = function () {
|
|
|
|
triggered2 = true
|
|
|
|
}
|
|
|
|
t.$on('test', f1)
|
|
|
|
t.$on('test', f2)
|
|
|
|
t.$off('test', f1)
|
|
|
|
t.$compiler.emitter.emit('test')
|
|
|
|
assert.notOk(triggered1)
|
|
|
|
assert.ok(triggered2)
|
|
|
|
})
|
|
|
|
|
2013-10-09 10:26:25 +08:00
|
|
|
})
|
|
|
|
|
2013-10-09 11:19:12 +08:00
|
|
|
describe('.$broadcast()', function () {
|
|
|
|
|
|
|
|
it('should notify all child VMs', function () {
|
|
|
|
var triggered = 0,
|
|
|
|
msg = 'broadcast test'
|
2013-12-08 06:29:17 +08:00
|
|
|
var Child = Vue.extend({
|
2013-10-09 11:19:12 +08:00
|
|
|
init: function () {
|
|
|
|
this.$on('hello', function (m) {
|
|
|
|
assert.strictEqual(m, msg)
|
|
|
|
triggered++
|
|
|
|
})
|
|
|
|
}
|
|
|
|
})
|
2013-12-08 06:29:17 +08:00
|
|
|
var Test = Vue.extend({
|
|
|
|
template: '<div v-component="test"></div><div v-component="test"></div>',
|
2013-11-14 10:51:51 +08:00
|
|
|
components: {
|
2013-10-09 11:19:12 +08:00
|
|
|
test: Child
|
|
|
|
}
|
|
|
|
})
|
|
|
|
var t = new Test()
|
|
|
|
t.$broadcast('hello', msg)
|
|
|
|
assert.strictEqual(triggered, 2)
|
|
|
|
})
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('.$emit', function () {
|
|
|
|
|
|
|
|
it('should notify all ancestor VMs', function (done) {
|
|
|
|
var topTriggered = false,
|
|
|
|
midTriggered = false,
|
|
|
|
msg = 'emit test'
|
2013-12-08 06:29:17 +08:00
|
|
|
var Bottom = Vue.extend({
|
2013-10-09 11:19:12 +08:00
|
|
|
init: function () {
|
|
|
|
var self = this
|
|
|
|
setTimeout(function () {
|
|
|
|
self.$emit('hello', msg)
|
|
|
|
assert.ok(topTriggered)
|
|
|
|
assert.ok(midTriggered)
|
|
|
|
done()
|
|
|
|
}, 0)
|
|
|
|
}
|
|
|
|
})
|
2013-12-08 06:29:17 +08:00
|
|
|
var Middle = Vue.extend({
|
|
|
|
template: '<div v-component="bottom"></div>',
|
2013-11-14 10:51:51 +08:00
|
|
|
components: { bottom: Bottom },
|
2013-10-09 11:19:12 +08:00
|
|
|
init: function () {
|
|
|
|
this.$on('hello', function (m) {
|
|
|
|
assert.strictEqual(m, msg)
|
|
|
|
midTriggered = true
|
|
|
|
})
|
|
|
|
}
|
|
|
|
})
|
2013-12-08 06:29:17 +08:00
|
|
|
var Top = Vue.extend({
|
|
|
|
template: '<div v-component="middle"></div>',
|
2013-11-14 10:51:51 +08:00
|
|
|
components: { middle: Middle },
|
2013-10-09 11:19:12 +08:00
|
|
|
init: function () {
|
|
|
|
this.$on('hello', function (m) {
|
|
|
|
assert.strictEqual(m, msg)
|
|
|
|
topTriggered = true
|
|
|
|
})
|
|
|
|
}
|
|
|
|
})
|
2013-10-12 05:40:39 +08:00
|
|
|
new Top()
|
2013-10-09 11:19:12 +08:00
|
|
|
})
|
|
|
|
|
2013-10-09 10:26:25 +08:00
|
|
|
})
|
|
|
|
|
2013-11-03 10:19:52 +08:00
|
|
|
describe('.$destroy', function () {
|
|
|
|
|
|
|
|
// since this simply delegates to Compiler.prototype.destroy(),
|
|
|
|
// that's what we are actually testing here.
|
2013-12-08 06:29:17 +08:00
|
|
|
var destroy = require('vue/src/compiler').prototype.destroy
|
2013-11-03 10:19:52 +08:00
|
|
|
|
|
|
|
var tearDownCalled = false,
|
|
|
|
observerOffCalled = false,
|
|
|
|
emitterOffCalled = false,
|
|
|
|
dirUnbindCalled = false,
|
|
|
|
expUnbindCalled = false,
|
|
|
|
bindingUnbindCalled = false,
|
|
|
|
unobserveCalled = 0,
|
|
|
|
elRemoved = false,
|
|
|
|
externalBindingUnbindCalled = false
|
|
|
|
|
|
|
|
var dirMock = {
|
|
|
|
binding: {
|
|
|
|
compiler: null,
|
|
|
|
instances: []
|
|
|
|
},
|
|
|
|
unbind: function () {
|
|
|
|
dirUnbindCalled = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
dirMock.binding.instances.push(dirMock)
|
|
|
|
|
|
|
|
var bindingsMock = Object.create({
|
|
|
|
'test2': {
|
|
|
|
unbind: function () {
|
|
|
|
externalBindingUnbindCalled = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
bindingsMock.test = {
|
|
|
|
root: true,
|
|
|
|
key: 'test',
|
|
|
|
value: {
|
|
|
|
__observer__: {
|
|
|
|
off: function () {
|
|
|
|
unobserveCalled++
|
|
|
|
return this
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
unbind: function () {
|
|
|
|
bindingUnbindCalled = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var compilerMock = {
|
|
|
|
options: {
|
|
|
|
teardown: function () {
|
|
|
|
tearDownCalled = true
|
|
|
|
}
|
|
|
|
},
|
|
|
|
observer: {
|
|
|
|
off: function () {
|
|
|
|
observerOffCalled = true
|
|
|
|
},
|
|
|
|
proxies: {
|
|
|
|
'test.': {}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
emitter: {
|
|
|
|
off: function () {
|
|
|
|
emitterOffCalled = true
|
|
|
|
}
|
|
|
|
},
|
|
|
|
dirs: [dirMock],
|
|
|
|
exps: [{
|
|
|
|
unbind: function () {
|
|
|
|
expUnbindCalled = true
|
|
|
|
}
|
|
|
|
}],
|
|
|
|
bindings: bindingsMock,
|
|
|
|
childId: 'test',
|
|
|
|
parentCompiler: {
|
|
|
|
childCompilers: [],
|
|
|
|
vm: {
|
|
|
|
$: {
|
|
|
|
'test': true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
el: {
|
2013-11-12 07:07:10 +08:00
|
|
|
getAttribute: function () {},
|
2013-11-03 10:19:52 +08:00
|
|
|
parentNode: {
|
|
|
|
removeChild: function () {
|
|
|
|
elRemoved = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
compilerMock.parentCompiler.childCompilers.push(compilerMock)
|
|
|
|
|
|
|
|
destroy.call(compilerMock)
|
|
|
|
|
|
|
|
it('should call the teardown option', function () {
|
|
|
|
assert.ok(tearDownCalled)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should turn observer and emitter off', function () {
|
|
|
|
assert.ok(observerOffCalled)
|
|
|
|
assert.ok(emitterOffCalled)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should unbind all directives', function () {
|
|
|
|
assert.ok(dirUnbindCalled)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should remove directives from external bindings', function () {
|
|
|
|
assert.strictEqual(dirMock.binding.instances.indexOf(dirMock), -1)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should unbind all expressions', function () {
|
|
|
|
assert.ok(expUnbindCalled)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should unbind and unobserve own bindings', function () {
|
|
|
|
assert.ok(bindingUnbindCalled)
|
|
|
|
assert.strictEqual(unobserveCalled, 3)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should not unbind external bindings', function () {
|
|
|
|
assert.notOk(externalBindingUnbindCalled)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should remove self from parentCompiler', function () {
|
|
|
|
var parent = compilerMock.parentCompiler
|
|
|
|
assert.ok(parent.childCompilers.indexOf(compilerMock), -1)
|
|
|
|
assert.strictEqual(parent.vm.$[compilerMock.childId], undefined)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should remove the dom element', function () {
|
|
|
|
assert.ok(elRemoved)
|
|
|
|
})
|
|
|
|
|
|
|
|
})
|
|
|
|
|
2013-09-10 06:04:33 +08:00
|
|
|
})
|