fix part of the tests

This commit is contained in:
Evan You 2014-09-02 05:37:34 -07:00
parent e0b33d3d1a
commit 1dfb10e491
7 changed files with 20 additions and 668 deletions

View File

@ -45,6 +45,7 @@ exports.$set = function (exp, val) {
exports.$add = function (key, val) {
if (!_.isReserved(key)) {
this._data.$add(key, val)
this._proxy(key)
}
}
@ -57,6 +58,7 @@ exports.$add = function (key, val) {
exports.$delete = function (key) {
if (!_.isReserved(key)) {
this._data.$delete(key)
this._unproxy(key)
}
}

View File

@ -103,7 +103,6 @@ function compileExpFns (exp, needSet) {
var getter = makeGetter(body)
if (getter) {
return {
computed : true,
get : getter,
body : body,
set : needSet

View File

@ -6,34 +6,28 @@ describe('Binding', function () {
beforeEach(function () {
b = new Binding()
})
it('addChild', function () {
var child = new Binding()
b._addChild('test', child)
expect(b.test).toBe(child)
})
it('addSub', function () {
var sub = {}
b._addSub(sub)
expect(b._subs.length).toBe(1)
expect(b._subs.indexOf(sub)).toBe(0)
b.addSub(sub)
expect(b.subs.length).toBe(1)
expect(b.subs.indexOf(sub)).toBe(0)
})
it('removeSub', function () {
var sub = {}
b._addSub(sub)
b._removeSub(sub)
expect(b._subs.length).toBe(0)
expect(b._subs.indexOf(sub)).toBe(-1)
b.addSub(sub)
b.removeSub(sub)
expect(b.subs.length).toBe(0)
expect(b.subs.indexOf(sub)).toBe(-1)
})
it('notify', function () {
var sub = {
update: jasmine.createSpy('sub')
}
b._addSub(sub)
b._notify()
b.addSub(sub)
b.notify()
expect(sub.update).toHaveBeenCalled()
})

View File

@ -4,265 +4,12 @@
*/
var Vue = require('../../../../src/vue')
var Observer = require('../../../../src/observe/observer')
var Observer = require('../../../../src/observer')
Observer.pathDelimiter = '.'
describe('Scope', function () {
describe('basic', function () {
var vm = new Vue({
data: {
a: 1,
b: {
c: 2
}
}
})
it('should proxy data properties', function () {
expect(vm.a).toBe(vm.$data.a)
expect(vm.b).toBe(vm.$data.b)
})
it('should trigger set events', function () {
var spy = jasmine.createSpy('basic')
vm.$observer.on('set', spy)
// simple
vm.a = 2
expect(spy.calls.count()).toBe(1)
expect(spy).toHaveBeenCalledWith('a', 2, undefined, undefined)
// nested path
vm.b.c = 3
expect(spy.calls.count()).toBe(2)
expect(spy).toHaveBeenCalledWith('b.c', 3, undefined, undefined)
})
it('should trigger add/delete events', function () {
var spy = jasmine.createSpy('instantiation')
vm.$observer
.on('add', spy)
.on('delete', spy)
// add
vm.$add('c', 123)
expect(spy.calls.count()).toBe(1)
expect(spy).toHaveBeenCalledWith('c', 123, undefined, undefined)
// delete
vm.$delete('c')
expect(spy.calls.count()).toBe(2)
expect(spy).toHaveBeenCalledWith('c', undefined, undefined, undefined)
// meta
vm._defineMeta('$index', 1)
expect(spy.calls.count()).toBe(3)
expect(spy).toHaveBeenCalledWith('$index', 1, undefined, undefined)
})
})
describe('data sync', function () {
var data = {
a: 1,
b: {
c: 2
}
}
var vm = new Vue({
data: data
})
it('should retain data reference', function () {
expect(vm.$data).toBe(data)
})
it('should sync set', function () {
// vm -> data
vm.a = 2
expect(data.a).toBe(2)
// data -> vm
data.b = {d:3}
expect(vm.b).toBe(data.b)
})
it('should sync add', function () {
// vm -> data
vm.$add('c', 123)
expect(data.c).toBe(123)
// data -> vm
data.$add('d', 456)
expect(vm.d).toBe(456)
})
it('should sync delete', function () {
// vm -> data
vm.$delete('d')
expect(data.hasOwnProperty('d')).toBe(false)
// data -> vm
data.$delete('c')
expect(vm.hasOwnProperty('c')).toBe(false)
})
})
describe('inheritance', function () {
var parent = new Vue({
data: {
a: 'parent a',
b: { c: 2 },
c: 'parent c',
arr: [{a:1},{a:2}]
}
})
var child = parent.$addChild({
data: {
a: 'child a'
}
})
it('child should inherit parent data on scope', function () {
expect(child.b).toBe(parent.b) // object
expect(child.c).toBe(parent.c) // primitive value
})
it('child should shadow parent property with same key', function () {
expect(parent.a).toBe('parent a')
expect(child.a).toBe('child a')
})
it('setting scope properties on child should affect parent', function () {
child.c = 'modified by child'
expect(parent.c).toBe('modified by child')
})
it('parent event should propagate when child has same binding', function () {
// object path
var b = child._createBindingAt('b.c')
b._notify = jasmine.createSpy('binding')
parent.b.c = 3
expect(b._notify).toHaveBeenCalled()
// array path
var b = child._createBindingAt('arr.0.a')
b._notify = jasmine.createSpy('binding')
parent.arr[0].a = 2
expect(b._notify).toHaveBeenCalled()
// add
var b = child._createBindingAt('e')
b._notify = jasmine.createSpy('binding')
parent.$add('e', 123)
expect(b._notify).toHaveBeenCalled()
// delete
parent.$delete('e')
expect(b._notify.calls.count()).toBe(2)
})
it('parent event should not propagate when child has shadowing key', function () {
var b = child._createBindingAt('c')
b._notify = jasmine.createSpy('binding')
child.$add('c', 123)
expect(b._notify.calls.count()).toBe(1)
parent.c = 456
expect(b._notify.calls.count()).toBe(1)
})
it('parent event should not even traverse if child doesn\'t have changed binding', function () {
parent._notifyChildren = jasmine.createSpy()
parent.c = 123
expect(parent._notifyChildren.calls.count()).toBe(1)
// should not be called after binding teardown
child._teardownBindingAt('c')
parent.c = 234
expect(parent._notifyChildren.calls.count()).toBe(1)
})
})
describe('inheritance with data sync on parent data', function () {
var parent = new Vue({
data: {
arr: [{a:1},{a:2}]
}
})
var child = parent.$addChild({
data: parent.arr[0]
})
it('should trigger proper events', function () {
var parentSpy = parent._createBindingAt('arr.0.a')
parentSpy._notify = jasmine.createSpy('binding')
var childSpy = child._createBindingAt('arr.0.a')
childSpy._notify = jasmine.createSpy('binding')
var childSpy2 = child._createBindingAt('a')
childSpy2._notify = jasmine.createSpy('binding')
child.a = 3
// make sure data sync is working
expect(parent.arr[0].a).toBe(3)
expect(parentSpy._notify).toHaveBeenCalled()
expect(childSpy._notify).toHaveBeenCalled()
expect(childSpy2._notify).toHaveBeenCalled()
})
})
describe('swapping $data', function () {
var oldData = { a: 1, c: 4 }
var newData = { a: 2, b: 3 }
var vm = new Vue({
data: oldData
})
var vmSpy = jasmine.createSpy('vm')
var vmAddSpy = jasmine.createSpy('vmAdd')
var oldDataSpy = jasmine.createSpy('oldData')
vm.$observer.on('set', vmSpy)
vm.$observer.on('add', vmAddSpy)
oldData.__ob__.on('set', oldDataSpy)
vm.$data = newData
it('should sync new data', function () {
expect(vm._data).toBe(newData)
expect(vm.a).toBe(2)
expect(vm.b).toBe(3)
expect(vmSpy).toHaveBeenCalledWith('a', 2, undefined, undefined)
expect(vmAddSpy).toHaveBeenCalledWith('b', 3, undefined, undefined)
})
it('should unsync old data', function () {
expect(vm.hasOwnProperty('c')).toBe(false)
vm.a = 3
expect(oldDataSpy.calls.count()).toBe(0)
expect(oldData.a).toBe(1)
expect(newData.a).toBe(3)
})
})
describe('scope teardown', function () {
var parent = new Vue({
data: {
a: 123
}
})
var child = new Vue({
parent: parent
})
var spy = jasmine.createSpy('teardown')
child.$observer.on('set', spy)
it('should stop relaying parent events', function () {
child._teardownScope()
parent.a = 234
expect(spy.calls.count()).toBe(0)
expect(child._data).toBeNull()
})
})
// TODO
describe('computed', function () {

View File

@ -1,10 +1,5 @@
/**
* Test data observation.
*/
var Observer = require('../../../src/observe/observer')
var Observer = require('../../../src/observer')
var _ = require('../../../src/util')
Observer.pathDelimiter = '.'
describe('Observer', function () {
@ -13,386 +8,8 @@ describe('Observer', function () {
spy = jasmine.createSpy('observer')
})
it('get', function () {
Observer.emitGet = true
var obj = {
a: 1,
b: {
c: 2
}
}
var ob = Observer.create(obj)
ob.on('get', spy)
var t = obj.a
expect(spy).toHaveBeenCalledWith('a', undefined, undefined, undefined)
expect(spy.calls.count()).toBe(1)
t = obj.b.c
expect(spy).toHaveBeenCalledWith('b', undefined, undefined, undefined)
expect(spy).toHaveBeenCalledWith('b.c', undefined, undefined, undefined)
expect(spy.calls.count()).toBe(3)
Observer.emitGet = false
})
it('set', function () {
var obj = {
a: 1,
b: {
c: 2
}
}
var ob = Observer.create(obj)
ob.on('set', spy)
obj.a = 3
expect(spy).toHaveBeenCalledWith('a', 3, undefined, undefined)
expect(spy.calls.count()).toBe(1)
obj.b.c = 4
expect(spy).toHaveBeenCalledWith('b.c', 4, undefined, undefined)
expect(spy.calls.count()).toBe(2)
// swap set
var newB = { c: 5 }
obj.b = newB
expect(spy).toHaveBeenCalledWith('b', newB, undefined, undefined)
expect(spy.calls.count()).toBe(3)
// same value set should not emit events
obj.a = 3
expect(spy.calls.count()).toBe(3)
})
it('ignore prefix', function () {
var obj = {
_test: 123,
$test: 234
}
var ob = Observer.create(obj)
ob.on('set', spy)
obj._test = 234
obj.$test = 345
expect(spy.calls.count()).toBe(0)
})
it('warn duplicate value', function () {
spyOn(_, 'warn')
var obj = {
a: { b: 123 },
b: null
}
var ob = Observer.create(obj)
obj.b = obj.a
expect(_.warn).toHaveBeenCalled()
})
it('array get', function () {
Observer.emitGet = true
var obj = {
arr: [{a:1}, {a:2}]
}
var ob = Observer.create(obj)
ob.on('get', spy)
var t = obj.arr[0].a
expect(spy).toHaveBeenCalledWith('arr', undefined, undefined, undefined)
expect(spy).toHaveBeenCalledWith('arr.0.a', undefined, undefined, undefined)
expect(spy.calls.count()).toBe(2)
Observer.emitGet = false
})
it('array set', function () {
var obj = {
arr: [{a:1}, {a:2}]
}
var ob = Observer.create(obj)
ob.on('set', spy)
obj.arr[0].a = 2
expect(spy).toHaveBeenCalledWith('arr.0.a', 2, undefined, undefined)
// set events after mutation
obj.arr.reverse()
obj.arr[0].a = 3
expect(spy).toHaveBeenCalledWith('arr.0.a', 3, undefined, undefined)
})
it('array push', function () {
var arr = [{a:1}, {a:2}]
var ob = Observer.create(arr)
ob.on('mutate', spy)
arr.push({a:3})
expect(spy.calls.mostRecent().args[0]).toBe('')
expect(spy.calls.mostRecent().args[1]).toBe(arr)
var mutation = spy.calls.mostRecent().args[2]
expect(mutation).toBeDefined()
expect(mutation.method).toBe('push')
expect(mutation.index).toBe(2)
expect(mutation.removed.length).toBe(0)
expect(mutation.inserted.length).toBe(1)
expect(mutation.inserted[0]).toBe(arr[2])
// test index update after mutation
ob.on('set', spy)
arr[2].a = 4
expect(spy).toHaveBeenCalledWith('2.a', 4, undefined, undefined)
})
it('array pop', function () {
var arr = [{a:1}, {a:2}]
var popped = arr[1]
var ob = Observer.create(arr)
ob.on('mutate', spy)
arr.pop()
expect(spy.calls.mostRecent().args[0]).toBe('')
expect(spy.calls.mostRecent().args[1]).toBe(arr)
var mutation = spy.calls.mostRecent().args[2]
expect(mutation).toBeDefined()
expect(mutation.method).toBe('pop')
expect(mutation.index).toBe(1)
expect(mutation.inserted.length).toBe(0)
expect(mutation.removed.length).toBe(1)
expect(mutation.removed[0]).toBe(popped)
})
it('array shift', function () {
var arr = [{a:1}, {a:2}]
var shifted = arr[0]
var ob = Observer.create(arr)
ob.on('mutate', spy)
arr.shift()
expect(spy.calls.mostRecent().args[0]).toBe('')
expect(spy.calls.mostRecent().args[1]).toBe(arr)
var mutation = spy.calls.mostRecent().args[2]
expect(mutation).toBeDefined()
expect(mutation.method).toBe('shift')
expect(mutation.index).toBe(0)
expect(mutation.inserted.length).toBe(0)
expect(mutation.removed.length).toBe(1)
expect(mutation.removed[0]).toBe(shifted)
// test index update after mutation
ob.on('set', spy)
arr[0].a = 4
expect(spy).toHaveBeenCalledWith('0.a', 4, undefined, undefined)
})
it('array unshift', function () {
var arr = [{a:1}, {a:2}]
var unshifted = {a:3}
var ob = Observer.create(arr)
ob.on('mutate', spy)
arr.unshift(unshifted)
expect(spy.calls.mostRecent().args[0]).toBe('')
expect(spy.calls.mostRecent().args[1]).toBe(arr)
var mutation = spy.calls.mostRecent().args[2]
expect(mutation).toBeDefined()
expect(mutation.method).toBe('unshift')
expect(mutation.index).toBe(0)
expect(mutation.removed.length).toBe(0)
expect(mutation.inserted.length).toBe(1)
expect(mutation.inserted[0]).toBe(unshifted)
// test index update after mutation
ob.on('set', spy)
arr[1].a = 4
expect(spy).toHaveBeenCalledWith('1.a', 4, undefined, undefined)
})
it('array splice', function () {
var arr = [{a:1}, {a:2}]
var inserted = {a:3}
var removed = arr[1]
var ob = Observer.create(arr)
ob.on('mutate', spy)
arr.splice(1, 1, inserted)
expect(spy.calls.mostRecent().args[0]).toBe('')
expect(spy.calls.mostRecent().args[1]).toBe(arr)
var mutation = spy.calls.mostRecent().args[2]
expect(mutation).toBeDefined()
expect(mutation.method).toBe('splice')
expect(mutation.index).toBe(1)
expect(mutation.removed.length).toBe(1)
expect(mutation.inserted.length).toBe(1)
expect(mutation.removed[0]).toBe(removed)
expect(mutation.inserted[0]).toBe(inserted)
// test index update after mutation
ob.on('set', spy)
arr[1].a = 4
expect(spy).toHaveBeenCalledWith('1.a', 4, undefined, undefined)
})
it('array sort', function () {
var arr = [{a:1}, {a:2}]
var ob = Observer.create(arr)
ob.on('mutate', spy)
arr.sort(function (a, b) {
return a.a < b.a ? 1 : -1
})
expect(spy.calls.mostRecent().args[0]).toBe('')
expect(spy.calls.mostRecent().args[1]).toBe(arr)
var mutation = spy.calls.mostRecent().args[2]
expect(mutation).toBeDefined()
expect(mutation.method).toBe('sort')
expect(mutation.index).toBeUndefined()
expect(mutation.removed.length).toBe(0)
expect(mutation.inserted.length).toBe(0)
// test index update after mutation
ob.on('set', spy)
arr[1].a = 4
expect(spy).toHaveBeenCalledWith('1.a', 4, undefined, undefined)
})
it('array reverse', function () {
var arr = [{a:1}, {a:2}]
var ob = Observer.create(arr)
ob.on('mutate', spy)
arr.reverse()
expect(spy.calls.mostRecent().args[0]).toBe('')
expect(spy.calls.mostRecent().args[1]).toBe(arr)
var mutation = spy.calls.mostRecent().args[2]
expect(mutation).toBeDefined()
expect(mutation.method).toBe('reverse')
expect(mutation.index).toBeUndefined()
expect(mutation.removed.length).toBe(0)
expect(mutation.inserted.length).toBe(0)
// test index update after mutation
ob.on('set', spy)
arr[1].a = 4
expect(spy).toHaveBeenCalledWith('1.a', 4, undefined, undefined)
})
it('object.$add', function () {
var obj = {a:{b:1}}
var ob = Observer.create(obj)
ob.on('add', spy)
// ignore existing keys
obj.$add('a', 123)
expect(spy.calls.count()).toBe(0)
// add event
var add = {d:2}
obj.a.$add('c', add)
expect(spy).toHaveBeenCalledWith('a.c', add, undefined, undefined)
// check if add object is properly observed
ob.on('set', spy)
obj.a.c.d = 3
expect(spy).toHaveBeenCalledWith('a.c.d', 3, undefined, undefined)
})
it('object.$delete', function () {
var obj = {a:{b:1}}
var ob = Observer.create(obj)
ob.on('delete', spy)
// ignore non-present key
obj.$delete('c')
expect(spy.calls.count()).toBe(0)
obj.a.$delete('b')
expect(spy).toHaveBeenCalledWith('a.b', undefined, undefined, undefined)
})
it('array.$set', function () {
var arr = [{a:1}, {a:2}]
var ob = Observer.create(arr)
ob.on('mutate', spy)
var inserted = {a:3}
var removed = arr[1]
arr.$set(1, inserted)
expect(spy.calls.mostRecent().args[0]).toBe('')
expect(spy.calls.mostRecent().args[1]).toBe(arr)
var mutation = spy.calls.mostRecent().args[2]
expect(mutation).toBeDefined()
expect(mutation.method).toBe('splice')
expect(mutation.index).toBe(1)
expect(mutation.removed.length).toBe(1)
expect(mutation.inserted.length).toBe(1)
expect(mutation.removed[0]).toBe(removed)
expect(mutation.inserted[0]).toBe(inserted)
ob.on('set', spy)
arr[1].a = 4
expect(spy).toHaveBeenCalledWith('1.a', 4, undefined, undefined)
})
it('array.$set with out of bound length', function () {
var arr = [{a:1}, {a:2}]
var ob = Observer.create(arr)
var inserted = {a:3}
arr.$set(3, inserted)
expect(arr.length).toBe(4)
expect(arr[2]).toBeUndefined()
expect(arr[3]).toBe(inserted)
})
it('array.$remove', function () {
var arr = [{a:1}, {a:2}]
var ob = Observer.create(arr)
ob.on('mutate', spy)
var removed = arr.$remove(0)
expect(spy.calls.mostRecent().args[0]).toBe('')
expect(spy.calls.mostRecent().args[1]).toBe(arr)
var mutation = spy.calls.mostRecent().args[2]
expect(mutation).toBeDefined()
expect(mutation.method).toBe('splice')
expect(mutation.index).toBe(0)
expect(mutation.removed.length).toBe(1)
expect(mutation.inserted.length).toBe(0)
expect(mutation.removed[0]).toBe(removed)
ob.on('set', spy)
arr[0].a = 3
expect(spy).toHaveBeenCalledWith('0.a', 3, undefined, undefined)
})
it('array.$remove object', function () {
var arr = [{a:1}, {a:2}]
var ob = Observer.create(arr)
ob.on('mutate', spy)
var removed = arr.$remove(arr[0])
expect(spy.calls.mostRecent().args[0]).toBe('')
expect(spy.calls.mostRecent().args[1]).toBe(arr)
var mutation = spy.calls.mostRecent().args[2]
expect(mutation).toBeDefined()
expect(mutation.method).toBe('splice')
expect(mutation.index).toBe(0)
expect(mutation.removed.length).toBe(1)
expect(mutation.inserted.length).toBe(0)
expect(mutation.removed[0]).toBe(removed)
ob.on('set', spy)
arr[0].a = 3
expect(spy).toHaveBeenCalledWith('0.a', 3, undefined, undefined)
})
it('shared observe', function () {
var obj = { a: 1 }
var parentA = { child1: obj }
var parentB = { child2: obj }
var obA = Observer.create(parentA)
var obB = Observer.create(parentB)
obA.on('set', spy)
obB.on('set', spy)
obj.a = 2
expect(spy.calls.count()).toBe(2)
expect(spy).toHaveBeenCalledWith('child1.a', 2, undefined, undefined)
expect(spy).toHaveBeenCalledWith('child2.a', 2, undefined, undefined)
// test unobserve
parentA.child1 = null
obj.a = 3
expect(spy.calls.count()).toBe(4)
expect(spy).toHaveBeenCalledWith('child1', null, undefined, undefined)
expect(spy).toHaveBeenCalledWith('child2.a', 3, undefined, undefined)
it('should work', function () {
// TODO
})
})

View File

@ -1,15 +1,6 @@
var expParser = require('../../../../src/parse/expression')
var _ = require('../../../../src/util')
function assertExp (testCase) {
var res = expParser.parse(testCase.exp)
expect(res.get(testCase.scope)).toEqual(testCase.expected)
expect(res.paths.length).toBe(testCase.paths.length)
res.paths.forEach(function (p, i) {
expect(p).toBe(testCase.paths[i])
})
}
var testCases = [
{
// simple path that doesn't exist
@ -190,7 +181,10 @@ var testCases = [
describe('Expression Parser', function () {
it('parse getter', function () {
testCases.forEach(assertExp)
testCases.forEach(function assertExp (testCase) {
var res = expParser.parse(testCase.exp, true)
expect(res.get(testCase.scope)).toEqual(testCase.expected)
})
})
it('dynamic setter', function () {

View File

@ -1,5 +1,4 @@
var Path = require('../../../../src/parse/path')
var Observer = require('../../../../src/observe/observer')
function assertPath (str, expected) {
var path = Path.parse(str)