github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/themes/wind/static/libs/vue-1.0.24/test/unit/specs/watcher_spec.js (about)

     1  var Vue = require('src')
     2  var nextTick = Vue.nextTick
     3  var Watcher = require('src/watcher')
     4  var _ = Vue.util
     5  var config = Vue.config
     6  
     7  describe('Watcher', function () {
     8    var vm, spy
     9    beforeEach(function () {
    10      vm = new Vue({
    11        filters: {},
    12        data: {
    13          a: 1,
    14          b: {
    15            c: 2,
    16            d: 4
    17          },
    18          c: 'c',
    19          msg: 'yo'
    20        }
    21      })
    22      spy = jasmine.createSpy('watcher')
    23    })
    24  
    25    it('simple path', function (done) {
    26      var watcher = new Watcher(vm, 'b.c', spy)
    27      expect(watcher.value).toBe(2)
    28      vm.b.c = 3
    29      nextTick(function () {
    30        expect(watcher.value).toBe(3)
    31        expect(spy).toHaveBeenCalledWith(3, 2)
    32        vm.b = { c: 4 } // swapping the object
    33        nextTick(function () {
    34          expect(watcher.value).toBe(4)
    35          expect(spy).toHaveBeenCalledWith(4, 3)
    36          done()
    37        })
    38      })
    39    })
    40  
    41    it('bracket access path', function (done) {
    42      var watcher = new Watcher(vm, 'b["c"]', spy)
    43      expect(watcher.value).toBe(2)
    44      vm.b.c = 3
    45      nextTick(function () {
    46        expect(watcher.value).toBe(3)
    47        expect(spy).toHaveBeenCalledWith(3, 2)
    48        vm.b = { c: 4 } // swapping the object
    49        nextTick(function () {
    50          expect(watcher.value).toBe(4)
    51          expect(spy).toHaveBeenCalledWith(4, 3)
    52          done()
    53        })
    54      })
    55    })
    56  
    57    it('dynamic path', function (done) {
    58      var watcher = new Watcher(vm, 'b[c]', spy)
    59      expect(watcher.value).toBe(2)
    60      vm.b.c = 3
    61      nextTick(function () {
    62        expect(watcher.value).toBe(3)
    63        expect(spy).toHaveBeenCalledWith(3, 2)
    64        vm.c = 'd' // changing the dynamic segment in path
    65        nextTick(function () {
    66          expect(watcher.value).toBe(4)
    67          expect(spy).toHaveBeenCalledWith(4, 3)
    68          done()
    69        })
    70      })
    71    })
    72  
    73    it('simple expression', function (done) {
    74      var watcher = new Watcher(vm, 'a + b.c', spy)
    75      expect(watcher.value).toBe(3)
    76      vm.b.c = 3
    77      nextTick(function () {
    78        expect(watcher.value).toBe(4)
    79        expect(spy.calls.count()).toBe(1)
    80        expect(spy).toHaveBeenCalledWith(4, 3)
    81        // change two dependencies at once
    82        vm.a = 2
    83        vm.b.c = 4
    84        nextTick(function () {
    85          expect(watcher.value).toBe(6)
    86          // should trigger only once callback,
    87          // because it was in the same event loop.
    88          expect(spy.calls.count()).toBe(2)
    89          expect(spy).toHaveBeenCalledWith(6, 4)
    90          done()
    91        })
    92      })
    93    })
    94  
    95    it('ternary expression', function (done) {
    96      // we're actually testing for the dependency re-calculation here
    97      var watcher = new Watcher(vm, 'a > 1 ? b.c : b.d', spy)
    98      expect(watcher.value).toBe(4)
    99      vm.a = 2
   100      nextTick(function () {
   101        expect(watcher.value).toBe(2)
   102        expect(spy).toHaveBeenCalledWith(2, 4)
   103        vm.b.c = 3
   104        nextTick(function () {
   105          expect(watcher.value).toBe(3)
   106          expect(spy).toHaveBeenCalledWith(3, 2)
   107          done()
   108        })
   109      })
   110    })
   111  
   112    it('meta properties', function (done) {
   113      _.defineReactive(vm, '$index', 1)
   114      var watcher = new Watcher(vm, '$index + 1', spy)
   115      expect(watcher.value).toBe(2)
   116      vm.$index = 2
   117      nextTick(function () {
   118        expect(watcher.value).toBe(3)
   119        done()
   120      })
   121    })
   122  
   123    it('non-existent path, set later', function (done) {
   124      var watcher = new Watcher(vm, 'd.e', spy)
   125      var watcher2 = new Watcher(vm, 'b.e', spy)
   126      expect(watcher.value).toBeUndefined()
   127      expect(watcher2.value).toBeUndefined()
   128      // check $add should not affect isolated children
   129      var child2 = new Vue({ parent: vm })
   130      var watcher3 = new Watcher(child2, 'd.e', spy)
   131      expect(watcher3.value).toBeUndefined()
   132      vm.$set('d', { e: 123 })
   133      _.set(vm.b, 'e', 234)
   134      nextTick(function () {
   135        expect(watcher.value).toBe(123)
   136        expect(watcher2.value).toBe(234)
   137        expect(watcher3.value).toBeUndefined()
   138        expect(spy.calls.count()).toBe(2)
   139        expect(spy).toHaveBeenCalledWith(123, undefined)
   140        expect(spy).toHaveBeenCalledWith(234, undefined)
   141        done()
   142      })
   143    })
   144  
   145    it('$delete', function (done) {
   146      var watcher = new Watcher(vm, 'b.c', spy)
   147      expect(watcher.value).toBe(2)
   148      vm.$delete('b')
   149      nextTick(function () {
   150        expect(watcher.value).toBeUndefined()
   151        expect(spy).toHaveBeenCalledWith(undefined, 2)
   152        done()
   153      })
   154    })
   155  
   156    it('swapping $data', function (done) {
   157      // existing path
   158      var watcher = new Watcher(vm, 'b.c', spy)
   159      var spy2 = jasmine.createSpy()
   160      // non-existing path
   161      var watcher2 = new Watcher(vm, 'e', spy2)
   162      expect(watcher.value).toBe(2)
   163      expect(watcher2.value).toBeUndefined()
   164      vm.$data = { b: { c: 3 }, e: 4 }
   165      nextTick(function () {
   166        expect(watcher.value).toBe(3)
   167        expect(watcher2.value).toBe(4)
   168        expect(spy).toHaveBeenCalledWith(3, 2)
   169        expect(spy2).toHaveBeenCalledWith(4, undefined)
   170        done()
   171      })
   172    })
   173  
   174    it('path containing $data', function (done) {
   175      var watcher = new Watcher(vm, '$data.b.c', spy)
   176      expect(watcher.value).toBe(2)
   177      vm.b = { c: 3 }
   178      nextTick(function () {
   179        expect(watcher.value).toBe(3)
   180        expect(spy).toHaveBeenCalledWith(3, 2)
   181        vm.$data = { b: { c: 4 }}
   182        nextTick(function () {
   183          expect(watcher.value).toBe(4)
   184          expect(spy).toHaveBeenCalledWith(4, 3)
   185          done()
   186        })
   187      })
   188    })
   189  
   190    it('watching $data', function (done) {
   191      var oldData = vm.$data
   192      var watcher = new Watcher(vm, '$data', spy)
   193      expect(watcher.value).toBe(oldData)
   194      var newData = {}
   195      vm.$data = newData
   196      nextTick(function () {
   197        expect(spy).toHaveBeenCalledWith(newData, oldData)
   198        expect(watcher.value).toBe(newData)
   199        done()
   200      })
   201    })
   202  
   203    it('filters', function (done) {
   204      vm.$options.filters.test = function (val, multi) {
   205        return val * multi
   206      }
   207      vm.$options.filters.test2 = function (val, str) {
   208        return val + str
   209      }
   210      var watcher = new Watcher(vm, 'b.c', spy, {
   211        filters: [
   212          { name: 'test', args: [{ value: 3, dynamic: false }] },
   213          { name: 'test2', args: [{ value: 'msg', dynamic: true }] }
   214        ]
   215      })
   216      expect(watcher.value).toBe('6yo')
   217      vm.b.c = 3
   218      nextTick(function () {
   219        expect(watcher.value).toBe('9yo')
   220        expect(spy).toHaveBeenCalledWith('9yo', '6yo')
   221        done()
   222      })
   223    })
   224  
   225    it('setter', function (done) {
   226      vm.$options.filters.test = {
   227        write: function (val, oldVal, arg) {
   228          return val > arg ? val : oldVal
   229        }
   230      }
   231      var watcher = new Watcher(vm, 'b["c"]', spy, {
   232        filters: [
   233          { name: 'test', args: [{value: 5, dynamic: false}] }
   234        ],
   235        twoWay: true
   236      })
   237      expect(watcher.value).toBe(2)
   238      watcher.set(4) // shoud not change the value
   239      nextTick(function () {
   240        expect(vm.b.c).toBe(2)
   241        expect(watcher.value).toBe(2)
   242        expect(spy).not.toHaveBeenCalled()
   243        watcher.set(6)
   244        nextTick(function () {
   245          expect(vm.b.c).toBe(6)
   246          expect(watcher.value).toBe(6)
   247          expect(spy).toHaveBeenCalledWith(6, 2)
   248          done()
   249        })
   250      })
   251    })
   252  
   253    it('set non-existent values', function (done) {
   254      var watcher = new Watcher(vm, 'd.e.f', spy, {
   255        twoWay: true
   256      })
   257      expect(watcher.value).toBeUndefined()
   258      watcher.set(123)
   259      nextTick(function () {
   260        expect(vm.d.e.f).toBe(123)
   261        expect(watcher.value).toBe(123)
   262        expect(spy).toHaveBeenCalledWith(123, undefined)
   263        done()
   264      })
   265    })
   266  
   267    it('deep watch', function (done) {
   268      new Watcher(vm, 'b', spy, {
   269        deep: true
   270      })
   271      vm.b.c = { d: 4 }
   272      nextTick(function () {
   273        expect(spy).toHaveBeenCalledWith(vm.b, vm.b)
   274        var oldB = vm.b
   275        vm.b = { c: [{ a: 1 }]}
   276        nextTick(function () {
   277          expect(spy).toHaveBeenCalledWith(vm.b, oldB)
   278          expect(spy.calls.count()).toBe(2)
   279          vm.b.c[0].a = 2
   280          nextTick(function () {
   281            expect(spy).toHaveBeenCalledWith(vm.b, vm.b)
   282            expect(spy.calls.count()).toBe(3)
   283            done()
   284          })
   285        })
   286      })
   287    })
   288  
   289    it('deep watch with circular references', function (done) {
   290      new Watcher(vm, 'b', spy, {
   291        deep: true
   292      })
   293      Vue.set(vm.b, '_', vm.b)
   294      nextTick(function () {
   295        expect(spy).toHaveBeenCalledWith(vm.b, vm.b)
   296        expect(spy.calls.count()).toBe(1)
   297        vm.b._.c = 1
   298        nextTick(function () {
   299          expect(spy).toHaveBeenCalledWith(vm.b, vm.b)
   300          expect(spy.calls.count()).toBe(2)
   301          done()
   302        })
   303      })
   304    })
   305  
   306    it('fire change for prop addition/deletion in non-deep mode', function (done) {
   307      new Watcher(vm, 'b', spy)
   308      Vue.set(vm.b, 'e', 123)
   309      nextTick(function () {
   310        expect(spy).toHaveBeenCalledWith(vm.b, vm.b)
   311        expect(spy.calls.count()).toBe(1)
   312        Vue.delete(vm.b, 'e')
   313        nextTick(function () {
   314          expect(spy.calls.count()).toBe(2)
   315          done()
   316        })
   317      })
   318    })
   319  
   320    it('watch function', function (done) {
   321      var watcher = new Watcher(vm, function () {
   322        return this.a + this.b.d
   323      }, spy)
   324      expect(watcher.value).toBe(5)
   325      vm.a = 2
   326      nextTick(function () {
   327        expect(spy).toHaveBeenCalledWith(6, 5)
   328        vm.b = { d: 2 }
   329        nextTick(function () {
   330          expect(spy).toHaveBeenCalledWith(4, 6)
   331          done()
   332        })
   333      })
   334    })
   335  
   336    it('lazy mode', function (done) {
   337      var watcher = new Watcher(vm, function () {
   338        return this.a + this.b.d
   339      }, null, { lazy: true })
   340      expect(watcher.lazy).toBe(true)
   341      expect(watcher.value).toBeUndefined()
   342      expect(watcher.dirty).toBe(true)
   343      watcher.evaluate()
   344      expect(watcher.value).toBe(5)
   345      expect(watcher.dirty).toBe(false)
   346      vm.a = 2
   347      nextTick(function () {
   348        expect(watcher.value).toBe(5)
   349        expect(watcher.dirty).toBe(true)
   350        watcher.evaluate()
   351        expect(watcher.value).toBe(6)
   352        expect(watcher.dirty).toBe(false)
   353        done()
   354      })
   355    })
   356  
   357    it('teardown', function (done) {
   358      var watcher = new Watcher(vm, 'b.c', spy)
   359      watcher.teardown()
   360      vm.b.c = 3
   361      nextTick(function () {
   362        expect(watcher.active).toBe(false)
   363        expect(watcher.vm).toBe(null)
   364        expect(watcher.cb).toBe(null)
   365        expect(spy).not.toHaveBeenCalled()
   366        done()
   367      })
   368    })
   369  
   370    it('synchronous updates', function () {
   371      config.async = false
   372      new Watcher(vm, 'a', spy)
   373      vm.a = 2
   374      vm.a = 3
   375      expect(spy.calls.count()).toBe(2)
   376      expect(spy).toHaveBeenCalledWith(2, 1)
   377      expect(spy).toHaveBeenCalledWith(3, 2)
   378      config.async = true
   379    })
   380  
   381    it('warn getter errors', function () {
   382      new Watcher(vm, 'd.e + c', spy)
   383      expect('Error when evaluating expression').toHaveBeenWarned()
   384    })
   385  
   386    it('warn setter errors', function () {
   387      var watcher = new Watcher(vm, 'a + b', spy)
   388      watcher.set(123)
   389      expect('Error when evaluating setter').toHaveBeenWarned()
   390    })
   391  })