浏览代码

more observer tests & bench

Evan You 11 年之前
父节点
当前提交
320b36c63e
共有 5 个文件被更改,包括 223 次插入16 次删除
  1. 30 2
      benchmarks/observer.js
  2. 1 0
      breaks.md
  3. 4 2
      src/observer/array-augmentations.js
  4. 4 2
      src/observer/object-augmentations.js
  5. 184 10
      test/unit/observer.js

+ 30 - 2
benchmarks/observer.js

@@ -1,10 +1,10 @@
 var Observer = require('../src/observer/observer')
 var Emitter = require('../src/emitter')
 var OldObserver = require('../../vue/src/observer')
-var sideEffect = 0
+var sideEffect = true
 var runs = 1000
 function cb () {
-  sideEffect++
+  sideEffect = !sideEffect
 }
 
 var loadTime = getNano()
@@ -237,6 +237,34 @@ bench(
   }
 )
 
+bench(
+  'swap set      ',
+  function () {
+    var a = {a:{b:{c:1}}}
+    var ob = new Observer()
+    ob.observe('', a)
+    ob.on('set', cb)
+    return a
+  },
+  function (o) {
+    o.a = {b:{c:2}}
+  }
+)
+
+bench(
+  'old swap set  ',
+  function () {
+    var a = {a:{b:{c:1}}}
+    var ob = new Emitter()
+    OldObserver.observe(a, '', ob)
+    ob.on('set', cb)
+    return a
+  },
+  function (o) {
+    o.a = {b:{c:2}}
+  }
+)
+
 bench(
   'array push    ',
   function () {

+ 1 - 0
breaks.md

@@ -0,0 +1 @@
+- array.$remove now only accepts number index as argument.

+ 4 - 2
src/observer/array-augmentations.js

@@ -70,9 +70,11 @@ var arrayAugmentations = Object.create(Array.prototype)
       args     : args,
       result   : result,
       index    : index,
-      inserted : inserted,
-      removed  : removed
+      inserted : inserted || [],
+      removed  : removed || []
     })
+
+    return result
   })
 })
 

+ 4 - 2
src/observer/object-augmentations.js

@@ -13,8 +13,10 @@ var objectAgumentations = Object.create(Object.prototype)
 _.define(objectAgumentations, '$add', function (key, val) {
   if (this.hasOwnProperty(key)) return
   this[key] = val
-  this.$observer.convert(key, val)
-  this.$observer.notify('added', key, val)
+  var ob = this.$observer
+  ob.observe(key, val)
+  ob.convert(key, val)
+  ob.notify('added', key, val)
 })
 
 /**

+ 184 - 10
test/unit/observer.js

@@ -1,4 +1,6 @@
 var Observer = require('../../src/observer/observer')
+// internal emitter has fixed 3 arguments
+// so we need to fill up the assetions with undefined
 var u = undefined
 Observer.pathDelimiter = '.'
 
@@ -52,6 +54,7 @@ describe('Observer', function () {
     expect(spy).toHaveBeenCalledWith('b.c', 4, u)
     expect(spy.callCount).toEqual(2)
 
+    // swap set
     var newB = { c: 5 }
     obj.b = newB
     expect(spy).toHaveBeenCalledWith('b', newB, u)
@@ -96,10 +99,9 @@ describe('Observer', function () {
     expect(spy).toHaveBeenCalledWith('arr.0.a', 3, u)
   })
 
-  it('array mutate', function () {
+  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.mostRecentCall.args[0]).toEqual('')
@@ -108,33 +110,205 @@ describe('Observer', function () {
     expect(mutation).toBeDefined()
     expect(mutation.method).toEqual('push')
     expect(mutation.index).toEqual(2)
+    expect(mutation.removed.length).toEqual(0)
     expect(mutation.inserted.length).toEqual(1)
     expect(mutation.inserted[0]).toEqual(arr[2])
+    // test index update after mutation
+    ob.on('set', spy)
+    arr[2].a = 4
+    expect(spy).toHaveBeenCalledWith('2.a', 4, u)
   })
 
-  it('array set after mutate', function () {
+  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.mostRecentCall.args[0]).toEqual('')
+    expect(spy.mostRecentCall.args[1]).toEqual(arr)
+    var mutation = spy.mostRecentCall.args[2]
+    expect(mutation).toBeDefined()
+    expect(mutation.method).toEqual('pop')
+    expect(mutation.index).toEqual(1)
+    expect(mutation.inserted.length).toEqual(0)
+    expect(mutation.removed.length).toEqual(1)
+    expect(mutation.removed[0]).toEqual(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.mostRecentCall.args[0]).toEqual('')
+    expect(spy.mostRecentCall.args[1]).toEqual(arr)
+    var mutation = spy.mostRecentCall.args[2]
+    expect(mutation).toBeDefined()
+    expect(mutation.method).toEqual('shift')
+    expect(mutation.index).toEqual(0)
+    expect(mutation.inserted.length).toEqual(0)
+    expect(mutation.removed.length).toEqual(1)
+    expect(mutation.removed[0]).toEqual(shifted)
+    // test index update after mutation
     ob.on('set', spy)
-    arr.push({a:3})
-    arr[2].a = 4
-    expect(spy).toHaveBeenCalledWith('2.a', 4, u)
+    arr[0].a = 4
+    expect(spy).toHaveBeenCalledWith('0.a', 4, u)
+  })
+
+  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.mostRecentCall.args[0]).toEqual('')
+    expect(spy.mostRecentCall.args[1]).toEqual(arr)
+    var mutation = spy.mostRecentCall.args[2]
+    expect(mutation).toBeDefined()
+    expect(mutation.method).toEqual('unshift')
+    expect(mutation.index).toEqual(0)
+    expect(mutation.removed.length).toEqual(0)
+    expect(mutation.inserted.length).toEqual(1)
+    expect(mutation.inserted[0]).toEqual(unshifted)
+    // test index update after mutation
+    ob.on('set', spy)
+    arr[1].a = 4
+    expect(spy).toHaveBeenCalledWith('1.a', 4, u)
+  })
+
+  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.mostRecentCall.args[0]).toEqual('')
+    expect(spy.mostRecentCall.args[1]).toEqual(arr)
+    var mutation = spy.mostRecentCall.args[2]
+    expect(mutation).toBeDefined()
+    expect(mutation.method).toEqual('splice')
+    expect(mutation.index).toEqual(1)
+    expect(mutation.removed.length).toEqual(1)
+    expect(mutation.inserted.length).toEqual(1)
+    expect(mutation.removed[0]).toEqual(removed)
+    expect(mutation.inserted[0]).toEqual(inserted)
+    // test index update after mutation
+    ob.on('set', spy)
+    arr[1].a = 4
+    expect(spy).toHaveBeenCalledWith('1.a', 4, u)
+  })
+
+  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.mostRecentCall.args[0]).toEqual('')
+    expect(spy.mostRecentCall.args[1]).toEqual(arr)
+    var mutation = spy.mostRecentCall.args[2]
+    expect(mutation).toBeDefined()
+    expect(mutation.method).toEqual('sort')
+    expect(mutation.index).toBeUndefined()
+    expect(mutation.removed.length).toEqual(0)
+    expect(mutation.inserted.length).toEqual(0)
+    // test index update after mutation
+    ob.on('set', spy)
+    arr[1].a = 4
+    expect(spy).toHaveBeenCalledWith('1.a', 4, u)
+  })
+
+  it('array reverse', function () {
+    var arr = [{a:1}, {a:2}]
+    var ob = Observer.create(arr)
+    ob.on('mutate', spy)
+    arr.reverse()
+    expect(spy.mostRecentCall.args[0]).toEqual('')
+    expect(spy.mostRecentCall.args[1]).toEqual(arr)
+    var mutation = spy.mostRecentCall.args[2]
+    expect(mutation).toBeDefined()
+    expect(mutation.method).toEqual('reverse')
+    expect(mutation.index).toBeUndefined()
+    expect(mutation.removed.length).toEqual(0)
+    expect(mutation.inserted.length).toEqual(0)
+    // test index update after mutation
+    ob.on('set', spy)
+    arr[1].a = 4
+    expect(spy).toHaveBeenCalledWith('1.a', 4, u)
   })
 
   it('object.$add', function () {
-    // body...
+    var obj = {a:{b:1}}
+    var ob = Observer.create(obj)
+    ob.on('added', spy)
+
+    // add event
+    var added = {d:2}
+    obj.a.$add('c', added)
+    expect(spy).toHaveBeenCalledWith('a.c', added, u)
+
+    // check if added object is properly observed
+    ob.on('set', spy)
+    obj.a.c.d = 3
+    expect(spy).toHaveBeenCalledWith('a.c.d', 3, u)
   })
 
   it('object.$delete', function () {
-    // body...
+    var obj = {a:{b:1}}
+    var ob = Observer.create(obj)
+    ob.on('deleted', spy)
+
+    obj.a.$delete('b')
+    expect(spy).toHaveBeenCalledWith('a.b', u, u)
   })
 
   it('array.$set', function () {
-    // body...
+    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.mostRecentCall.args[0]).toEqual('')
+    expect(spy.mostRecentCall.args[1]).toEqual(arr)
+    var mutation = spy.mostRecentCall.args[2]
+    expect(mutation).toBeDefined()
+    expect(mutation.method).toEqual('splice')
+    expect(mutation.index).toEqual(1)
+    expect(mutation.removed.length).toEqual(1)
+    expect(mutation.inserted.length).toEqual(1)
+    expect(mutation.removed[0]).toEqual(removed)
+    expect(mutation.inserted[0]).toEqual(inserted)
+
+    ob.on('set', spy)
+    arr[1].a = 4
+    expect(spy).toHaveBeenCalledWith('1.a', 4, u)
   })
 
   it('array.$remove', function () {
-    // body...
+    var arr = [{a:1}, {a:2}]
+    var ob = Observer.create(arr)
+    ob.on('mutate', spy)
+    var removed = arr.$remove(0)
+
+    expect(spy.mostRecentCall.args[0]).toEqual('')
+    expect(spy.mostRecentCall.args[1]).toEqual(arr)
+    var mutation = spy.mostRecentCall.args[2]
+    expect(mutation).toBeDefined()
+    expect(mutation.method).toEqual('splice')
+    expect(mutation.index).toEqual(0)
+    expect(mutation.removed.length).toEqual(1)
+    expect(mutation.inserted.length).toEqual(0)
+    expect(mutation.removed[0]).toEqual(removed)
+
+    ob.on('set', spy)
+    arr[0].a = 3
+    expect(spy).toHaveBeenCalledWith('0.a', 3, u)
   })
 
 })