| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- /**
- * Test property proxy, scope inheritance,
- * data event propagation and data sync
- */
- var Vue = require('../../src/vue')
- var Observer = require('../../src/observe/observer')
- var u = undefined
- Observer.pathDelimiter = '.'
- describe('Scope', function () {
-
- describe('basic', function () {
-
- var vm = new Vue({
- data: {
- a: 1,
- b: {
- c: 2
- }
- }
- })
- it('should copy over data properties', function () {
- expect(vm.$scope.a).toBe(vm.$data.a)
- expect(vm.$scope.b).toBe(vm.$data.b)
- })
- it('should proxy these properties', function () {
- expect(vm.a).toBe(vm.$scope.a)
- expect(vm.b).toBe(vm.$scope.b)
- })
- it('should trigger set events', function () {
- var spy = jasmine.createSpy('basic')
- vm._observer.on('set', spy)
- // set on scope
- vm.$scope.a = 2
- expect(spy.callCount).toBe(1)
- expect(spy).toHaveBeenCalledWith('a', 2, u)
- // set on vm
- vm.b.c = 3
- expect(spy.callCount).toBe(2)
- expect(spy).toHaveBeenCalledWith('b.c', 3, u)
- })
- it('should trigger add/delete events', function () {
- var spy = jasmine.createSpy('instantiation')
- vm._observer
- .on('add', spy)
- .on('delete', spy)
- // add on scope
- vm.$scope.$add('c', 123)
- expect(spy.callCount).toBe(1)
- expect(spy).toHaveBeenCalledWith('c', 123, u)
- // delete on scope
- vm.$scope.$delete('c')
- expect(spy.callCount).toBe(2)
- expect(spy).toHaveBeenCalledWith('c', u, u)
- // vm $add/$delete are tested in the api suite
- })
- })
- describe('data sync', function () {
- var data = {
- a: 1,
- b: {
- c: 2
- }
- }
-
- var vm = new Vue({
- syncData: true,
- 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.$scope.b).toBe(data.b)
- expect(vm.b).toBe(data.b)
- })
- it('should sync add', function () {
- // vm -> data
- vm.$scope.$add('c', 123)
- expect(data.c).toBe(123)
- // data -> vm
- data.$add('d', 456)
- expect(vm.$scope.d).toBe(456)
- expect(vm.d).toBe(456)
- })
- it('should sync delete', function () {
- // vm -> data
- vm.$scope.$delete('d')
- expect(data.hasOwnProperty('d')).toBe(false)
- // data -> vm
- data.$delete('c')
- expect(vm.$scope.hasOwnProperty('c')).toBe(false)
- 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 = new Vue({
- parent: parent,
- data: {
- a: 'child a'
- }
- })
- it('child should inherit parent data on scope', function () {
- expect(child.$scope.b).toBe(parent.b) // object
- expect(child.$scope.c).toBe(parent.c) // primitive value
- })
- it('child should not ineherit data on instance', function () {
- expect(child.b).toBeUndefined()
- expect(child.c).toBeUndefined()
- })
- it('child should shadow parent property with same key', function () {
- expect(parent.a).toBe('parent a')
- expect(child.$scope.a).toBe('child a')
- expect(child.a).toBe('child a')
- })
- it('setting scope properties on child should affect parent', function () {
- child.$scope.c = 'modified by child'
- expect(parent.c).toBe('modified by child')
- })
- it('events on parent should propagate down to child', function () {
- // when a shadowed property changed on parent scope,
- // the event should NOT be propagated down
- var spy = jasmine.createSpy('inheritance')
- child._observer.on('set', spy)
- parent.c = 'c changed'
- expect(spy.callCount).toBe(1)
- expect(spy).toHaveBeenCalledWith('c', 'c changed', u)
- spy = jasmine.createSpy('inheritance')
- child._observer.on('add', spy)
- parent.$scope.$add('e', 123)
- expect(spy.callCount).toBe(1)
- expect(spy).toHaveBeenCalledWith('e', 123, u)
- spy = jasmine.createSpy('inheritance')
- child._observer.on('delete', spy)
- parent.$scope.$delete('e')
- expect(spy.callCount).toBe(1)
- expect(spy).toHaveBeenCalledWith('e', u, u)
- spy = jasmine.createSpy('inheritance')
- child._observer.on('mutate', spy)
- parent.arr.reverse()
- expect(spy.mostRecentCall.args[0]).toBe('arr')
- expect(spy.mostRecentCall.args[1]).toBe(parent.arr)
- expect(spy.mostRecentCall.args[2].method).toBe('reverse')
- })
- it('shadowed properties change on parent should not propagate down', function () {
- // when a shadowed property changed on parent scope,
- // the event should NOT be propagated down
- var spy = jasmine.createSpy('inheritance')
- child._observer.on('set', spy)
- parent.a = 'a changed'
- expect(spy.callCount).toBe(0)
- })
- })
- describe('inheritance with data sync on parent data', function () {
-
- var parent = new Vue({
- data: {
- arr: [{a:1},{a:2}]
- }
- })
- var child = new Vue({
- parent: parent,
- syncData: true,
- data: parent.arr[0]
- })
- it('should trigger proper events', function () {
-
- var parentSpy = jasmine.createSpy('parent')
- var childSpy = jasmine.createSpy('child')
- parent._observer.on('set', parentSpy)
- child._observer.on('set', childSpy)
- child.a = 3
- // make sure data sync is working
- expect(parent.arr[0].a).toBe(3)
- expect(parentSpy.callCount).toBe(1)
- expect(parentSpy).toHaveBeenCalledWith('arr.0.a', 3, u)
- expect(childSpy.callCount).toBe(2)
- expect(childSpy).toHaveBeenCalledWith('a', 3, u)
- expect(childSpy).toHaveBeenCalledWith('arr.0.a', 3, u)
- })
- })
- })
|