| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338 |
- /**
- * Test property proxy, scope inheritance,
- * data event propagation and data sync
- */
- var Vue = require('../../../../src/vue')
- var Observer = require('../../../../src/observe/observer')
- Observer.pathDelimiter = '.'
- function mockBinding () {
- return {
- _notify: jasmine.createSpy('binding')
- }
- }
- 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._bindings['b.c'] = mockBinding()
- parent.b.c = 3
- expect(b._notify).toHaveBeenCalled()
- // array path
- b = child._bindings['arr.0.a'] = mockBinding()
- parent.arr[0].a = 2
- expect(b._notify).toHaveBeenCalled()
- // add
- b = child._bindings['e'] = mockBinding()
- parent.$add('e', 123)
- expect(b._notify).toHaveBeenCalled()
- // delete
- b = child._bindings['e'] = mockBinding()
- parent.$delete('e')
- expect(b._notify).toHaveBeenCalled()
- })
- it('parent event should not propagate when child has shadowing key', function () {
- var b = child._bindings['c'] = mockBinding()
- child.$add('c', 123)
- expect(b._notify.calls.count()).toBe(1)
- parent.c = 456
- expect(b._notify.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._bindings['arr.0.a'] = mockBinding()
- var childSpy = child._bindings['arr.0.a'] = mockBinding()
- var childSpy2 = child._bindings['a'] = mockBinding()
- 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()
- })
- })
- describe('computed', function () {
-
- var vm = new Vue({
- data: {
- a: 'a',
- b: 'b'
- },
- computed: {
- c: function () {
- expect(this).toBe(vm)
- return this.a + this.b
- },
- d: {
- get: function () {
- expect(this).toBe(vm)
- return this.a + this.b
- },
- set: function (newVal) {
- expect(this).toBe(vm)
- var vals = newVal.split(' ')
- this.a = vals[0]
- this.b = vals[1]
- }
- }
- }
- })
- it('get', function () {
- expect(vm.c).toBe('ab')
- expect(vm.d).toBe('ab')
- })
- it('set', function () {
- vm.c = 123 // should do nothing
- vm.d = 'c d'
- expect(vm.a).toBe('c')
- expect(vm.b).toBe('d')
- expect(vm.c).toBe('cd')
- expect(vm.d).toBe('cd')
- })
- it('inherit', function () {
- var child = vm.$addChild()
- expect(child.c).toBe('cd')
- child.d = 'e f'
- expect(vm.a).toBe('e')
- expect(vm.b).toBe('f')
- expect(vm.c).toBe('ef')
- expect(vm.d).toBe('ef')
- expect(child.a).toBe('e')
- expect(child.b).toBe('f')
- expect(child.c).toBe('ef')
- expect(child.d).toBe('ef')
- })
- })
- describe('methods', function () {
- it('should work and have correct context', function () {
- var vm = new Vue({
- data: {
- a: 1
- },
- methods: {
- test: function () {
- expect(this instanceof Vue).toBe(true)
- return this.a
- }
- }
- })
- expect(vm.test()).toBe(1)
- var child = vm.$addChild()
- expect(child.test()).toBe(1)
- })
- })
- })
|