OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 observer.records = r; | 81 observer.records = r; |
82 observer.callbackCount++; | 82 observer.callbackCount++; |
83 }; | 83 }; |
84 | 84 |
85 observer.reset(); | 85 observer.reset(); |
86 allObservers.push(observer); | 86 allObservers.push(observer); |
87 return observer; | 87 return observer; |
88 } | 88 } |
89 | 89 |
90 var observer = createObserver(); | 90 var observer = createObserver(); |
91 var observer2 = createObserver(); | |
92 | |
93 assertEquals("function", typeof observer.callback); | 91 assertEquals("function", typeof observer.callback); |
94 assertEquals("function", typeof observer2.callback); | |
95 | |
96 var obj = {}; | 92 var obj = {}; |
97 | 93 |
98 function frozenFunction() {} | 94 function frozenFunction() {} |
99 Object.freeze(frozenFunction); | 95 Object.freeze(frozenFunction); |
100 var nonFunction = {}; | 96 var nonFunction = {}; |
101 var changeRecordWithAccessor = { type: 'foo' }; | 97 var changeRecordWithAccessor = { type: 'foo' }; |
102 var recordCreated = false; | 98 var recordCreated = false; |
103 Object.defineProperty(changeRecordWithAccessor, 'name', { | 99 Object.defineProperty(changeRecordWithAccessor, 'name', { |
104 get: function() { | 100 get: function() { |
105 recordCreated = true; | 101 recordCreated = true; |
106 return "bar"; | 102 return "bar"; |
107 }, | 103 }, |
108 enumerable: true | 104 enumerable: true |
109 }) | 105 }) |
110 | 106 |
111 | 107 |
112 // Object.observe | 108 // Object.observe |
113 assertThrows(function() { Object.observe("non-object", observer.callback); }, Ty
peError); | 109 assertThrows(function() { Object.observe("non-object", observer.callback); }, Ty
peError); |
114 assertThrows(function() { Object.observe(obj, nonFunction); }, TypeError); | 110 assertThrows(function() { Object.observe(obj, nonFunction); }, TypeError); |
115 assertThrows(function() { Object.observe(obj, frozenFunction); }, TypeError); | 111 assertThrows(function() { Object.observe(obj, frozenFunction); }, TypeError); |
116 assertThrows(function() { Object.observe(obj, function() {}, 1); }, TypeError); | |
117 assertThrows(function() { Object.observe(obj, function() {}, [undefined]); }, Ty
peError); | |
118 assertThrows(function() { Object.observe(obj, function() {}, [1]); }, TypeError)
; | |
119 assertThrows(function() { Object.observe(obj, function() {}, ['foo', null]); },
TypeError); | |
120 assertEquals(obj, Object.observe(obj, observer.callback, ['foo', 'bar', 'baz']))
; | |
121 assertEquals(obj, Object.observe(obj, observer.callback, [])); | |
122 assertEquals(obj, Object.observe(obj, observer.callback, undefined)); | |
123 assertEquals(obj, Object.observe(obj, observer.callback)); | 112 assertEquals(obj, Object.observe(obj, observer.callback)); |
124 | 113 |
| 114 |
125 // Object.unobserve | 115 // Object.unobserve |
126 assertThrows(function() { Object.unobserve(4, observer.callback); }, TypeError); | 116 assertThrows(function() { Object.unobserve(4, observer.callback); }, TypeError); |
127 assertThrows(function() { Object.unobserve(obj, nonFunction); }, TypeError); | 117 assertThrows(function() { Object.unobserve(obj, nonFunction); }, TypeError); |
128 assertEquals(obj, Object.unobserve(obj, observer.callback)); | 118 assertEquals(obj, Object.unobserve(obj, observer.callback)); |
129 | 119 |
130 | 120 |
131 // Object.getNotifier | 121 // Object.getNotifier |
132 var notifier = Object.getNotifier(obj); | 122 var notifier = Object.getNotifier(obj); |
133 assertSame(notifier, Object.getNotifier(obj)); | 123 assertSame(notifier, Object.getNotifier(obj)); |
134 assertEquals(null, Object.getNotifier(Object.freeze({}))); | 124 assertEquals(null, Object.getNotifier(Object.freeze({}))); |
135 assertFalse(notifier.hasOwnProperty('notify')); | 125 assertFalse(notifier.hasOwnProperty('notify')); |
136 assertEquals([], Object.keys(notifier)); | 126 assertEquals([], Object.keys(notifier)); |
137 var notifyDesc = Object.getOwnPropertyDescriptor(notifier.__proto__, 'notify'); | 127 var notifyDesc = Object.getOwnPropertyDescriptor(notifier.__proto__, 'notify'); |
138 assertTrue(notifyDesc.configurable); | 128 assertTrue(notifyDesc.configurable); |
139 assertTrue(notifyDesc.writable); | 129 assertTrue(notifyDesc.writable); |
140 assertFalse(notifyDesc.enumerable); | 130 assertFalse(notifyDesc.enumerable); |
141 assertThrows(function() { notifier.notify({}); }, TypeError); | 131 assertThrows(function() { notifier.notify({}); }, TypeError); |
142 assertThrows(function() { notifier.notify({ type: 4 }); }, TypeError); | 132 assertThrows(function() { notifier.notify({ type: 4 }); }, TypeError); |
143 | |
144 assertThrows(function() { notifier.performChange(1, function(){}); }, TypeError)
; | |
145 assertThrows(function() { notifier.performChange(undefined, function(){}); }, Ty
peError); | |
146 assertThrows(function() { notifier.performChange('foo', undefined); }, TypeError
); | |
147 assertThrows(function() { notifier.performChange('foo', 'bar'); }, TypeError); | |
148 var testSelf = {}; | |
149 notifier.performChange('foo', function() { | |
150 assertTrue(testSelf === this); | |
151 }, testSelf); | |
152 var self = this; | |
153 notifier.performChange('foo', function() { | |
154 assertTrue(self === this); | |
155 }); | |
156 | |
157 var notify = notifier.notify; | 133 var notify = notifier.notify; |
158 assertThrows(function() { notify.call(undefined, { type: 'a' }); }, TypeError); | 134 assertThrows(function() { notify.call(undefined, { type: 'a' }); }, TypeError); |
159 assertThrows(function() { notify.call(null, { type: 'a' }); }, TypeError); | 135 assertThrows(function() { notify.call(null, { type: 'a' }); }, TypeError); |
160 assertThrows(function() { notify.call(5, { type: 'a' }); }, TypeError); | 136 assertThrows(function() { notify.call(5, { type: 'a' }); }, TypeError); |
161 assertThrows(function() { notify.call('hello', { type: 'a' }); }, TypeError); | 137 assertThrows(function() { notify.call('hello', { type: 'a' }); }, TypeError); |
162 assertThrows(function() { notify.call(false, { type: 'a' }); }, TypeError); | 138 assertThrows(function() { notify.call(false, { type: 'a' }); }, TypeError); |
163 assertThrows(function() { notify.call({}, { type: 'a' }); }, TypeError); | 139 assertThrows(function() { notify.call({}, { type: 'a' }); }, TypeError); |
164 assertFalse(recordCreated); | 140 assertFalse(recordCreated); |
165 notifier.notify(changeRecordWithAccessor); | 141 notifier.notify(changeRecordWithAccessor); |
166 assertFalse(recordCreated); // not observed yet | 142 assertFalse(recordCreated); // not observed yet |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 reset(); | 188 reset(); |
213 Object.deliverChangeRecords(observer.callback); | 189 Object.deliverChangeRecords(observer.callback); |
214 observer.assertNotCalled(); | 190 observer.assertNotCalled(); |
215 | 191 |
216 | 192 |
217 // Multiple observation has no effect. | 193 // Multiple observation has no effect. |
218 reset(); | 194 reset(); |
219 Object.observe(obj, observer.callback); | 195 Object.observe(obj, observer.callback); |
220 Object.observe(obj, observer.callback); | 196 Object.observe(obj, observer.callback); |
221 Object.getNotifier(obj).notify({ | 197 Object.getNotifier(obj).notify({ |
222 type: 'updated', | 198 type: 'foo', |
223 }); | 199 }); |
224 Object.deliverChangeRecords(observer.callback); | 200 Object.deliverChangeRecords(observer.callback); |
225 observer.assertCalled(); | 201 observer.assertCalled(); |
226 | 202 |
227 | 203 |
228 // Observation can be stopped. | 204 // Observation can be stopped. |
229 reset(); | 205 reset(); |
230 Object.unobserve(obj, observer.callback); | 206 Object.unobserve(obj, observer.callback); |
231 Object.getNotifier(obj).notify({ | 207 Object.getNotifier(obj).notify({ |
232 type: 'updated', | 208 type: 'foo', |
233 }); | 209 }); |
234 Object.deliverChangeRecords(observer.callback); | 210 Object.deliverChangeRecords(observer.callback); |
235 observer.assertNotCalled(); | 211 observer.assertNotCalled(); |
236 | 212 |
237 | 213 |
238 // Multiple unobservation has no effect | 214 // Multiple unobservation has no effect |
239 reset(); | 215 reset(); |
240 Object.unobserve(obj, observer.callback); | 216 Object.unobserve(obj, observer.callback); |
241 Object.unobserve(obj, observer.callback); | 217 Object.unobserve(obj, observer.callback); |
242 Object.getNotifier(obj).notify({ | 218 Object.getNotifier(obj).notify({ |
243 type: 'updated', | 219 type: 'foo', |
244 }); | 220 }); |
245 Object.deliverChangeRecords(observer.callback); | 221 Object.deliverChangeRecords(observer.callback); |
246 observer.assertNotCalled(); | 222 observer.assertNotCalled(); |
247 | 223 |
248 | 224 |
249 // Re-observation works and only includes changeRecords after of call. | 225 // Re-observation works and only includes changeRecords after of call. |
250 reset(); | 226 reset(); |
251 Object.getNotifier(obj).notify({ | 227 Object.getNotifier(obj).notify({ |
252 type: 'updated', | 228 type: 'foo', |
253 }); | 229 }); |
254 Object.observe(obj, observer.callback); | 230 Object.observe(obj, observer.callback); |
255 Object.getNotifier(obj).notify({ | 231 Object.getNotifier(obj).notify({ |
256 type: 'updated', | 232 type: 'foo', |
257 }); | 233 }); |
258 records = undefined; | 234 records = undefined; |
259 Object.deliverChangeRecords(observer.callback); | 235 Object.deliverChangeRecords(observer.callback); |
260 observer.assertRecordCount(1); | 236 observer.assertRecordCount(1); |
261 | 237 |
262 | 238 |
263 // Observing a continuous stream of changes, while itermittantly unobserving. | 239 // Observing a continuous stream of changes, while itermittantly unobserving. |
264 reset(); | 240 reset(); |
265 Object.observe(obj, observer.callback); | 241 Object.observe(obj, observer.callback); |
266 Object.getNotifier(obj).notify({ | 242 Object.getNotifier(obj).notify({ |
267 type: 'updated', | 243 type: 'foo', |
268 val: 1 | 244 val: 1 |
269 }); | 245 }); |
270 | 246 |
271 Object.unobserve(obj, observer.callback); | 247 Object.unobserve(obj, observer.callback); |
272 Object.getNotifier(obj).notify({ | 248 Object.getNotifier(obj).notify({ |
273 type: 'updated', | 249 type: 'foo', |
274 val: 2 | 250 val: 2 |
275 }); | 251 }); |
276 | 252 |
277 Object.observe(obj, observer.callback); | 253 Object.observe(obj, observer.callback); |
278 Object.getNotifier(obj).notify({ | 254 Object.getNotifier(obj).notify({ |
279 type: 'updated', | 255 type: 'foo', |
280 val: 3 | 256 val: 3 |
281 }); | 257 }); |
282 | 258 |
283 Object.unobserve(obj, observer.callback); | 259 Object.unobserve(obj, observer.callback); |
284 Object.getNotifier(obj).notify({ | 260 Object.getNotifier(obj).notify({ |
285 type: 'updated', | 261 type: 'foo', |
286 val: 4 | 262 val: 4 |
287 }); | 263 }); |
288 | 264 |
289 Object.observe(obj, observer.callback); | 265 Object.observe(obj, observer.callback); |
290 Object.getNotifier(obj).notify({ | 266 Object.getNotifier(obj).notify({ |
291 type: 'updated', | 267 type: 'foo', |
292 val: 5 | 268 val: 5 |
293 }); | 269 }); |
294 | 270 |
295 Object.unobserve(obj, observer.callback); | 271 Object.unobserve(obj, observer.callback); |
296 Object.deliverChangeRecords(observer.callback); | 272 Object.deliverChangeRecords(observer.callback); |
297 observer.assertCallbackRecords([ | 273 observer.assertCallbackRecords([ |
298 { object: obj, type: 'updated', val: 1 }, | 274 { object: obj, type: 'foo', val: 1 }, |
299 { object: obj, type: 'updated', val: 3 }, | 275 { object: obj, type: 'foo', val: 3 }, |
300 { object: obj, type: 'updated', val: 5 } | 276 { object: obj, type: 'foo', val: 5 } |
301 ]); | |
302 | |
303 // Accept | |
304 reset(); | |
305 Object.observe(obj, observer.callback, []); | |
306 Object.getNotifier(obj).notify({ | |
307 type: 'new' | |
308 }); | |
309 Object.getNotifier(obj).notify({ | |
310 type: 'updated' | |
311 }); | |
312 Object.getNotifier(obj).notify({ | |
313 type: 'deleted' | |
314 }); | |
315 Object.getNotifier(obj).notify({ | |
316 type: 'reconfigured' | |
317 }); | |
318 Object.getNotifier(obj).notify({ | |
319 type: 'prototype' | |
320 }); | |
321 Object.deliverChangeRecords(observer.callback); | |
322 observer.assertNotCalled(); | |
323 | |
324 reset(); | |
325 Object.observe(obj, observer.callback, ['new', 'deleted', 'prototype']); | |
326 Object.getNotifier(obj).notify({ | |
327 type: 'new' | |
328 }); | |
329 Object.getNotifier(obj).notify({ | |
330 type: 'updated' | |
331 }); | |
332 Object.getNotifier(obj).notify({ | |
333 type: 'deleted' | |
334 }); | |
335 Object.getNotifier(obj).notify({ | |
336 type: 'deleted' | |
337 }); | |
338 Object.getNotifier(obj).notify({ | |
339 type: 'reconfigured' | |
340 }); | |
341 Object.getNotifier(obj).notify({ | |
342 type: 'prototype' | |
343 }); | |
344 Object.deliverChangeRecords(observer.callback); | |
345 observer.assertCallbackRecords([ | |
346 { object: obj, type: 'new' }, | |
347 { object: obj, type: 'deleted' }, | |
348 { object: obj, type: 'deleted' }, | |
349 { object: obj, type: 'prototype' } | |
350 ]); | |
351 | |
352 reset(); | |
353 Object.observe(obj, observer.callback, ['updated', 'foo']); | |
354 Object.getNotifier(obj).notify({ | |
355 type: 'new' | |
356 }); | |
357 Object.getNotifier(obj).notify({ | |
358 type: 'updated' | |
359 }); | |
360 Object.getNotifier(obj).notify({ | |
361 type: 'deleted' | |
362 }); | |
363 Object.getNotifier(obj).notify({ | |
364 type: 'foo' | |
365 }); | |
366 Object.getNotifier(obj).notify({ | |
367 type: 'bar' | |
368 }); | |
369 Object.getNotifier(obj).notify({ | |
370 type: 'foo' | |
371 }); | |
372 Object.deliverChangeRecords(observer.callback); | |
373 observer.assertCallbackRecords([ | |
374 { object: obj, type: 'updated' }, | |
375 { object: obj, type: 'foo' }, | |
376 { object: obj, type: 'foo' } | |
377 ]); | |
378 | |
379 reset(); | |
380 function Thingy(a, b, c) { | |
381 this.a = a; | |
382 this.b = b; | |
383 } | |
384 | |
385 Thingy.MULTIPLY = 'multiply'; | |
386 Thingy.INCREMENT = 'increment'; | |
387 Thingy.INCREMENT_AND_MULTIPLY = 'incrementAndMultiply'; | |
388 | |
389 Thingy.prototype = { | |
390 increment: function(amount) { | |
391 var notifier = Object.getNotifier(this); | |
392 | |
393 notifier.performChange(Thingy.INCREMENT, function() { | |
394 this.a += amount; | |
395 this.b += amount; | |
396 }, this); | |
397 | |
398 notifier.notify({ | |
399 object: this, | |
400 type: Thingy.INCREMENT, | |
401 incremented: amount | |
402 }); | |
403 }, | |
404 | |
405 multiply: function(amount) { | |
406 var notifier = Object.getNotifier(this); | |
407 | |
408 notifier.performChange(Thingy.MULTIPLY, function() { | |
409 this.a *= amount; | |
410 this.b *= amount; | |
411 }, this); | |
412 | |
413 notifier.notify({ | |
414 object: this, | |
415 type: Thingy.MULTIPLY, | |
416 multiplied: amount | |
417 }); | |
418 }, | |
419 | |
420 incrementAndMultiply: function(incAmount, multAmount) { | |
421 var notifier = Object.getNotifier(this); | |
422 | |
423 notifier.performChange(Thingy.INCREMENT_AND_MULTIPLY, function() { | |
424 this.increment(incAmount); | |
425 this.multiply(multAmount); | |
426 }, this); | |
427 | |
428 notifier.notify({ | |
429 object: this, | |
430 type: Thingy.INCREMENT_AND_MULTIPLY, | |
431 incremented: incAmount, | |
432 multiplied: multAmount | |
433 }); | |
434 } | |
435 } | |
436 | |
437 Thingy.observe = function(thingy, callback) { | |
438 Object.observe(thingy, callback, [Thingy.INCREMENT, | |
439 Thingy.MULTIPLY, | |
440 Thingy.INCREMENT_AND_MULTIPLY, | |
441 'updated']); | |
442 } | |
443 | |
444 Thingy.unobserve = function(thingy, callback) { | |
445 Object.unobserve(thingy); | |
446 } | |
447 | |
448 var thingy = new Thingy(2, 4); | |
449 | |
450 Object.observe(thingy, observer.callback); | |
451 Thingy.observe(thingy, observer2.callback); | |
452 thingy.increment(3); // { a: 5, b: 7 } | |
453 thingy.b++; // { a: 5, b: 8 } | |
454 thingy.multiply(2); // { a: 10, b: 16 } | |
455 thingy.a++; // { a: 11, b: 16 } | |
456 thingy.incrementAndMultiply(2, 2); // { a: 26, b: 36 } | |
457 | |
458 Object.deliverChangeRecords(observer.callback); | |
459 Object.deliverChangeRecords(observer2.callback); | |
460 observer.assertCallbackRecords([ | |
461 { object: thingy, type: 'updated', name: 'a', oldValue: 2 }, | |
462 { object: thingy, type: 'updated', name: 'b', oldValue: 4 }, | |
463 { object: thingy, type: 'updated', name: 'b', oldValue: 7 }, | |
464 { object: thingy, type: 'updated', name: 'a', oldValue: 5 }, | |
465 { object: thingy, type: 'updated', name: 'b', oldValue: 8 }, | |
466 { object: thingy, type: 'updated', name: 'a', oldValue: 10 }, | |
467 { object: thingy, type: 'updated', name: 'a', oldValue: 11 }, | |
468 { object: thingy, type: 'updated', name: 'b', oldValue: 16 }, | |
469 { object: thingy, type: 'updated', name: 'a', oldValue: 13 }, | |
470 { object: thingy, type: 'updated', name: 'b', oldValue: 18 }, | |
471 ]); | |
472 observer2.assertCallbackRecords([ | |
473 { object: thingy, type: Thingy.INCREMENT, incremented: 3 }, | |
474 { object: thingy, type: 'updated', name: 'b', oldValue: 7 }, | |
475 { object: thingy, type: Thingy.MULTIPLY, multiplied: 2 }, | |
476 { object: thingy, type: 'updated', name: 'a', oldValue: 10 }, | |
477 { | |
478 object: thingy, | |
479 type: Thingy.INCREMENT_AND_MULTIPLY, | |
480 incremented: 2, | |
481 multiplied: 2 | |
482 } | |
483 ]); | 277 ]); |
484 | 278 |
485 | 279 |
486 reset(); | |
487 function RecursiveThingy() {} | |
488 | |
489 RecursiveThingy.MULTIPLY_FIRST_N = 'multiplyFirstN'; | |
490 | |
491 RecursiveThingy.prototype = { | |
492 __proto__: Array.prototype, | |
493 | |
494 multiplyFirstN: function(amount, n) { | |
495 if (!n) | |
496 return; | |
497 var notifier = Object.getNotifier(this); | |
498 notifier.performChange(RecursiveThingy.MULTIPLY_FIRST_N, function() { | |
499 this[n-1] = this[n-1]*amount; | |
500 this.multiplyFirstN(amount, n-1); | |
501 }, this); | |
502 | |
503 notifier.notify({ | |
504 object: this, | |
505 type: RecursiveThingy.MULTIPLY_FIRST_N, | |
506 multiplied: amount, | |
507 n: n | |
508 }); | |
509 }, | |
510 } | |
511 | |
512 RecursiveThingy.observe = function(thingy, callback) { | |
513 Object.observe(thingy, callback, [RecursiveThingy.MULTIPLY_FIRST_N]); | |
514 } | |
515 | |
516 RecursiveThingy.unobserve = function(thingy, callback) { | |
517 Object.unobserve(thingy); | |
518 } | |
519 | |
520 var thingy = new RecursiveThingy; | |
521 thingy.push(1, 2, 3, 4); | |
522 | |
523 Object.observe(thingy, observer.callback); | |
524 RecursiveThingy.observe(thingy, observer2.callback); | |
525 thingy.multiplyFirstN(2, 3); // [2, 4, 6, 4] | |
526 | |
527 Object.deliverChangeRecords(observer.callback); | |
528 Object.deliverChangeRecords(observer2.callback); | |
529 observer.assertCallbackRecords([ | |
530 { object: thingy, type: 'updated', name: '2', oldValue: 3 }, | |
531 { object: thingy, type: 'updated', name: '1', oldValue: 2 }, | |
532 { object: thingy, type: 'updated', name: '0', oldValue: 1 } | |
533 ]); | |
534 observer2.assertCallbackRecords([ | |
535 { object: thingy, type: RecursiveThingy.MULTIPLY_FIRST_N, multiplied: 2, n: 3
} | |
536 ]); | |
537 | |
538 reset(); | |
539 function DeckSuit() { | |
540 this.push('1', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'A', 'Q', 'K'); | |
541 } | |
542 | |
543 DeckSuit.SHUFFLE = 'shuffle'; | |
544 | |
545 DeckSuit.prototype = { | |
546 __proto__: Array.prototype, | |
547 | |
548 shuffle: function() { | |
549 var notifier = Object.getNotifier(this); | |
550 notifier.performChange(DeckSuit.SHUFFLE, function() { | |
551 this.reverse(); | |
552 this.sort(function() { return Math.random()* 2 - 1; }); | |
553 var cut = this.splice(0, 6); | |
554 Array.prototype.push.apply(this, cut); | |
555 this.reverse(); | |
556 this.sort(function() { return Math.random()* 2 - 1; }); | |
557 var cut = this.splice(0, 6); | |
558 Array.prototype.push.apply(this, cut); | |
559 this.reverse(); | |
560 this.sort(function() { return Math.random()* 2 - 1; }); | |
561 }, this); | |
562 | |
563 notifier.notify({ | |
564 object: this, | |
565 type: DeckSuit.SHUFFLE | |
566 }); | |
567 }, | |
568 } | |
569 | |
570 DeckSuit.observe = function(thingy, callback) { | |
571 Object.observe(thingy, callback, [DeckSuit.SHUFFLE]); | |
572 } | |
573 | |
574 DeckSuit.unobserve = function(thingy, callback) { | |
575 Object.unobserve(thingy); | |
576 } | |
577 | |
578 var deck = new DeckSuit; | |
579 | |
580 DeckSuit.observe(deck, observer2.callback); | |
581 deck.shuffle(); | |
582 | |
583 Object.deliverChangeRecords(observer2.callback); | |
584 observer2.assertCallbackRecords([ | |
585 { object: deck, type: DeckSuit.SHUFFLE } | |
586 ]); | |
587 | |
588 // Observing multiple objects; records appear in order. | 280 // Observing multiple objects; records appear in order. |
589 reset(); | 281 reset(); |
590 var obj2 = {}; | 282 var obj2 = {}; |
591 var obj3 = {} | 283 var obj3 = {} |
592 Object.observe(obj, observer.callback); | 284 Object.observe(obj, observer.callback); |
593 Object.observe(obj3, observer.callback); | 285 Object.observe(obj3, observer.callback); |
594 Object.observe(obj2, observer.callback); | 286 Object.observe(obj2, observer.callback); |
595 Object.getNotifier(obj).notify({ | 287 Object.getNotifier(obj).notify({ |
596 type: 'new', | 288 type: 'foo1', |
597 }); | 289 }); |
598 Object.getNotifier(obj2).notify({ | 290 Object.getNotifier(obj2).notify({ |
599 type: 'updated', | 291 type: 'foo2', |
600 }); | 292 }); |
601 Object.getNotifier(obj3).notify({ | 293 Object.getNotifier(obj3).notify({ |
602 type: 'deleted', | 294 type: 'foo3', |
603 }); | 295 }); |
604 Object.observe(obj3, observer.callback); | 296 Object.observe(obj3, observer.callback); |
605 Object.deliverChangeRecords(observer.callback); | 297 Object.deliverChangeRecords(observer.callback); |
606 observer.assertCallbackRecords([ | 298 observer.assertCallbackRecords([ |
607 { object: obj, type: 'new' }, | 299 { object: obj, type: 'foo1' }, |
608 { object: obj2, type: 'updated' }, | 300 { object: obj2, type: 'foo2' }, |
609 { object: obj3, type: 'deleted' } | 301 { object: obj3, type: 'foo3' } |
610 ]); | 302 ]); |
611 | 303 |
612 | 304 |
613 // Recursive observation. | 305 // Recursive observation. |
614 var obj = {a: 1}; | 306 var obj = {a: 1}; |
615 var callbackCount = 0; | 307 var callbackCount = 0; |
616 function recursiveObserver(r) { | 308 function recursiveObserver(r) { |
617 assertEquals(1, r.length); | 309 assertEquals(1, r.length); |
618 ++callbackCount; | 310 ++callbackCount; |
619 if (r[0].oldValue < 100) ++obj[r[0].name]; | 311 if (r[0].oldValue < 100) ++obj[r[0].name]; |
(...skipping 758 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1378 for (var n1 = 0; n1 < 3; ++n1) | 1070 for (var n1 = 0; n1 < 3; ++n1) |
1379 for (var n2 = 0; n2 < 3; ++n2) | 1071 for (var n2 = 0; n2 < 3; ++n2) |
1380 for (var i in mutation) | 1072 for (var i in mutation) |
1381 TestFastElementsLength(mutation[i], b1 != 0, b2 != 0, 20*n1, 20*n2); | 1073 TestFastElementsLength(mutation[i], b1 != 0, b2 != 0, 20*n1, 20*n2); |
1382 | 1074 |
1383 for (var b1 = 0; b1 < 2; ++b1) | 1075 for (var b1 = 0; b1 < 2; ++b1) |
1384 for (var b2 = 0; b2 < 2; ++b2) | 1076 for (var b2 = 0; b2 < 2; ++b2) |
1385 for (var n = 0; n < 3; ++n) | 1077 for (var n = 0; n < 3; ++n) |
1386 for (var i in mutationByIncr) | 1078 for (var i in mutationByIncr) |
1387 TestFastElementsLength(mutationByIncr[i], b1 != 0, b2 != 0, 7*n, 7*n+1); | 1079 TestFastElementsLength(mutationByIncr[i], b1 != 0, b2 != 0, 7*n, 7*n+1); |
OLD | NEW |