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 })