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 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 var changeRecordWithAccessor = { type: 'foo' }; | 98 var changeRecordWithAccessor = { type: 'foo' }; |
99 var recordCreated = false; | 99 var recordCreated = false; |
100 Object.defineProperty(changeRecordWithAccessor, 'name', { | 100 Object.defineProperty(changeRecordWithAccessor, 'name', { |
101 get: function() { | 101 get: function() { |
102 recordCreated = true; | 102 recordCreated = true; |
103 return "bar"; | 103 return "bar"; |
104 }, | 104 }, |
105 enumerable: true | 105 enumerable: true |
106 }) | 106 }) |
107 | 107 |
| 108 |
108 // Object.observe | 109 // Object.observe |
109 assertThrows(function() { Object.observe("non-object", observer.callback); }, Ty
peError); | 110 assertThrows(function() { Object.observe("non-object", observer.callback); }, Ty
peError); |
110 assertThrows(function() { Object.observe(obj, nonFunction); }, TypeError); | 111 assertThrows(function() { Object.observe(obj, nonFunction); }, TypeError); |
111 assertThrows(function() { Object.observe(obj, frozenFunction); }, TypeError); | 112 assertThrows(function() { Object.observe(obj, frozenFunction); }, TypeError); |
112 assertEquals(obj, Object.observe(obj, observer.callback)); | 113 assertEquals(obj, Object.observe(obj, observer.callback)); |
113 | 114 |
| 115 |
114 // Object.unobserve | 116 // Object.unobserve |
115 assertThrows(function() { Object.unobserve(4, observer.callback); }, TypeError); | 117 assertThrows(function() { Object.unobserve(4, observer.callback); }, TypeError); |
116 assertThrows(function() { Object.unobserve(obj, nonFunction); }, TypeError); | 118 assertThrows(function() { Object.unobserve(obj, nonFunction); }, TypeError); |
117 assertEquals(obj, Object.unobserve(obj, observer.callback)); | 119 assertEquals(obj, Object.unobserve(obj, observer.callback)); |
118 | 120 |
| 121 |
119 // Object.getNotifier | 122 // Object.getNotifier |
120 var notifier = Object.getNotifier(obj); | 123 var notifier = Object.getNotifier(obj); |
121 assertSame(notifier, Object.getNotifier(obj)); | 124 assertSame(notifier, Object.getNotifier(obj)); |
122 assertEquals(null, Object.getNotifier(Object.freeze({}))); | 125 assertEquals(null, Object.getNotifier(Object.freeze({}))); |
123 assertFalse(notifier.hasOwnProperty('notify')); | 126 assertFalse(notifier.hasOwnProperty('notify')); |
124 assertEquals([], Object.keys(notifier)); | 127 assertEquals([], Object.keys(notifier)); |
125 var notifyDesc = Object.getOwnPropertyDescriptor(notifier.__proto__, 'notify'); | 128 var notifyDesc = Object.getOwnPropertyDescriptor(notifier.__proto__, 'notify'); |
126 assertTrue(notifyDesc.configurable); | 129 assertTrue(notifyDesc.configurable); |
127 assertTrue(notifyDesc.writable); | 130 assertTrue(notifyDesc.writable); |
128 assertFalse(notifyDesc.enumerable); | 131 assertFalse(notifyDesc.enumerable); |
129 assertThrows(function() { notifier.notify({}); }, TypeError); | 132 assertThrows(function() { notifier.notify({}); }, TypeError); |
130 assertThrows(function() { notifier.notify({ type: 4 }); }, TypeError); | 133 assertThrows(function() { notifier.notify({ type: 4 }); }, TypeError); |
131 var notify = notifier.notify; | 134 var notify = notifier.notify; |
132 assertThrows(function() { notify.call(undefined, { type: 'a' }); }, TypeError); | 135 assertThrows(function() { notify.call(undefined, { type: 'a' }); }, TypeError); |
133 assertThrows(function() { notify.call(null, { type: 'a' }); }, TypeError); | 136 assertThrows(function() { notify.call(null, { type: 'a' }); }, TypeError); |
134 assertThrows(function() { notify.call(5, { type: 'a' }); }, TypeError); | 137 assertThrows(function() { notify.call(5, { type: 'a' }); }, TypeError); |
135 assertThrows(function() { notify.call('hello', { type: 'a' }); }, TypeError); | 138 assertThrows(function() { notify.call('hello', { type: 'a' }); }, TypeError); |
136 assertThrows(function() { notify.call(false, { type: 'a' }); }, TypeError); | 139 assertThrows(function() { notify.call(false, { type: 'a' }); }, TypeError); |
137 assertThrows(function() { notify.call({}, { type: 'a' }); }, TypeError); | 140 assertThrows(function() { notify.call({}, { type: 'a' }); }, TypeError); |
138 assertFalse(recordCreated); | 141 assertFalse(recordCreated); |
139 notifier.notify(changeRecordWithAccessor); | 142 notifier.notify(changeRecordWithAccessor); |
140 assertFalse(recordCreated); // not observed yet | 143 assertFalse(recordCreated); // not observed yet |
141 | 144 |
| 145 |
142 // Object.deliverChangeRecords | 146 // Object.deliverChangeRecords |
143 assertThrows(function() { Object.deliverChangeRecords(nonFunction); }, TypeError
); | 147 assertThrows(function() { Object.deliverChangeRecords(nonFunction); }, TypeError
); |
144 | 148 |
145 Object.observe(obj, observer.callback); | 149 Object.observe(obj, observer.callback); |
146 | 150 |
| 151 |
147 // notify uses to [[CreateOwnProperty]] to create changeRecord; | 152 // notify uses to [[CreateOwnProperty]] to create changeRecord; |
148 reset(); | 153 reset(); |
149 var protoExpandoAccessed = false; | 154 var protoExpandoAccessed = false; |
150 Object.defineProperty(Object.prototype, 'protoExpando', | 155 Object.defineProperty(Object.prototype, 'protoExpando', |
151 { | 156 { |
152 configurable: true, | 157 configurable: true, |
153 set: function() { protoExpandoAccessed = true; } | 158 set: function() { protoExpandoAccessed = true; } |
154 } | 159 } |
155 ); | 160 ); |
156 notifier.notify({ type: 'foo', protoExpando: 'val'}); | 161 notifier.notify({ type: 'foo', protoExpando: 'val'}); |
157 assertFalse(protoExpandoAccessed); | 162 assertFalse(protoExpandoAccessed); |
158 delete Object.prototype.protoExpando; | 163 delete Object.prototype.protoExpando; |
159 Object.deliverChangeRecords(observer.callback); | 164 Object.deliverChangeRecords(observer.callback); |
160 | 165 |
| 166 |
161 // Multiple records are delivered. | 167 // Multiple records are delivered. |
162 reset(); | 168 reset(); |
163 notifier.notify({ | 169 notifier.notify({ |
164 type: 'updated', | 170 type: 'updated', |
165 name: 'foo', | 171 name: 'foo', |
166 expando: 1 | 172 expando: 1 |
167 }); | 173 }); |
168 | 174 |
169 notifier.notify({ | 175 notifier.notify({ |
170 object: notifier, // object property is ignored | 176 object: notifier, // object property is ignored |
171 type: 'deleted', | 177 type: 'deleted', |
172 name: 'bar', | 178 name: 'bar', |
173 expando2: 'str' | 179 expando2: 'str' |
174 }); | 180 }); |
175 Object.deliverChangeRecords(observer.callback); | 181 Object.deliverChangeRecords(observer.callback); |
176 observer.assertCallbackRecords([ | 182 observer.assertCallbackRecords([ |
177 { object: obj, name: 'foo', type: 'updated', expando: 1 }, | 183 { object: obj, name: 'foo', type: 'updated', expando: 1 }, |
178 { object: obj, name: 'bar', type: 'deleted', expando2: 'str' } | 184 { object: obj, name: 'bar', type: 'deleted', expando2: 'str' } |
179 ]); | 185 ]); |
180 | 186 |
| 187 |
181 // No delivery takes place if no records are pending | 188 // No delivery takes place if no records are pending |
182 reset(); | 189 reset(); |
183 Object.deliverChangeRecords(observer.callback); | 190 Object.deliverChangeRecords(observer.callback); |
184 observer.assertNotCalled(); | 191 observer.assertNotCalled(); |
185 | 192 |
| 193 |
186 // Multiple observation has no effect. | 194 // Multiple observation has no effect. |
187 reset(); | 195 reset(); |
188 Object.observe(obj, observer.callback); | 196 Object.observe(obj, observer.callback); |
189 Object.observe(obj, observer.callback); | 197 Object.observe(obj, observer.callback); |
190 Object.getNotifier(obj).notify({ | 198 Object.getNotifier(obj).notify({ |
191 type: 'foo', | 199 type: 'foo', |
192 }); | 200 }); |
193 Object.deliverChangeRecords(observer.callback); | 201 Object.deliverChangeRecords(observer.callback); |
194 observer.assertCalled(); | 202 observer.assertCalled(); |
195 | 203 |
| 204 |
196 // Observation can be stopped. | 205 // Observation can be stopped. |
197 reset(); | 206 reset(); |
198 Object.unobserve(obj, observer.callback); | 207 Object.unobserve(obj, observer.callback); |
199 Object.getNotifier(obj).notify({ | 208 Object.getNotifier(obj).notify({ |
200 type: 'foo', | 209 type: 'foo', |
201 }); | 210 }); |
202 Object.deliverChangeRecords(observer.callback); | 211 Object.deliverChangeRecords(observer.callback); |
203 observer.assertNotCalled(); | 212 observer.assertNotCalled(); |
204 | 213 |
| 214 |
205 // Multiple unobservation has no effect | 215 // Multiple unobservation has no effect |
206 reset(); | 216 reset(); |
207 Object.unobserve(obj, observer.callback); | 217 Object.unobserve(obj, observer.callback); |
208 Object.unobserve(obj, observer.callback); | 218 Object.unobserve(obj, observer.callback); |
209 Object.getNotifier(obj).notify({ | 219 Object.getNotifier(obj).notify({ |
210 type: 'foo', | 220 type: 'foo', |
211 }); | 221 }); |
212 Object.deliverChangeRecords(observer.callback); | 222 Object.deliverChangeRecords(observer.callback); |
213 observer.assertNotCalled(); | 223 observer.assertNotCalled(); |
214 | 224 |
| 225 |
215 // Re-observation works and only includes changeRecords after of call. | 226 // Re-observation works and only includes changeRecords after of call. |
216 reset(); | 227 reset(); |
217 Object.getNotifier(obj).notify({ | 228 Object.getNotifier(obj).notify({ |
218 type: 'foo', | 229 type: 'foo', |
219 }); | 230 }); |
220 Object.observe(obj, observer.callback); | 231 Object.observe(obj, observer.callback); |
221 Object.getNotifier(obj).notify({ | 232 Object.getNotifier(obj).notify({ |
222 type: 'foo', | 233 type: 'foo', |
223 }); | 234 }); |
224 records = undefined; | 235 records = undefined; |
225 Object.deliverChangeRecords(observer.callback); | 236 Object.deliverChangeRecords(observer.callback); |
226 observer.assertRecordCount(1); | 237 observer.assertRecordCount(1); |
227 | 238 |
| 239 |
228 // Observing a continuous stream of changes, while itermittantly unobserving. | 240 // Observing a continuous stream of changes, while itermittantly unobserving. |
229 reset(); | 241 reset(); |
230 Object.observe(obj, observer.callback); | 242 Object.observe(obj, observer.callback); |
231 Object.getNotifier(obj).notify({ | 243 Object.getNotifier(obj).notify({ |
232 type: 'foo', | 244 type: 'foo', |
233 val: 1 | 245 val: 1 |
234 }); | 246 }); |
235 | 247 |
236 Object.unobserve(obj, observer.callback); | 248 Object.unobserve(obj, observer.callback); |
237 Object.getNotifier(obj).notify({ | 249 Object.getNotifier(obj).notify({ |
(...skipping 20 matching lines...) Expand all Loading... |
258 }); | 270 }); |
259 | 271 |
260 Object.unobserve(obj, observer.callback); | 272 Object.unobserve(obj, observer.callback); |
261 Object.deliverChangeRecords(observer.callback); | 273 Object.deliverChangeRecords(observer.callback); |
262 observer.assertCallbackRecords([ | 274 observer.assertCallbackRecords([ |
263 { object: obj, type: 'foo', val: 1 }, | 275 { object: obj, type: 'foo', val: 1 }, |
264 { object: obj, type: 'foo', val: 3 }, | 276 { object: obj, type: 'foo', val: 3 }, |
265 { object: obj, type: 'foo', val: 5 } | 277 { object: obj, type: 'foo', val: 5 } |
266 ]); | 278 ]); |
267 | 279 |
| 280 |
268 // Observing multiple objects; records appear in order. | 281 // Observing multiple objects; records appear in order. |
269 reset(); | 282 reset(); |
270 var obj2 = {}; | 283 var obj2 = {}; |
271 var obj3 = {} | 284 var obj3 = {} |
272 Object.observe(obj, observer.callback); | 285 Object.observe(obj, observer.callback); |
273 Object.observe(obj3, observer.callback); | 286 Object.observe(obj3, observer.callback); |
274 Object.observe(obj2, observer.callback); | 287 Object.observe(obj2, observer.callback); |
275 Object.getNotifier(obj).notify({ | 288 Object.getNotifier(obj).notify({ |
276 type: 'foo1', | 289 type: 'foo1', |
277 }); | 290 }); |
278 Object.getNotifier(obj2).notify({ | 291 Object.getNotifier(obj2).notify({ |
279 type: 'foo2', | 292 type: 'foo2', |
280 }); | 293 }); |
281 Object.getNotifier(obj3).notify({ | 294 Object.getNotifier(obj3).notify({ |
282 type: 'foo3', | 295 type: 'foo3', |
283 }); | 296 }); |
284 Object.observe(obj3, observer.callback); | 297 Object.observe(obj3, observer.callback); |
285 Object.deliverChangeRecords(observer.callback); | 298 Object.deliverChangeRecords(observer.callback); |
286 observer.assertCallbackRecords([ | 299 observer.assertCallbackRecords([ |
287 { object: obj, type: 'foo1' }, | 300 { object: obj, type: 'foo1' }, |
288 { object: obj2, type: 'foo2' }, | 301 { object: obj2, type: 'foo2' }, |
289 { object: obj3, type: 'foo3' } | 302 { object: obj3, type: 'foo3' } |
290 ]); | 303 ]); |
291 | 304 |
| 305 |
| 306 // Recursive observation. |
| 307 var obj = {a: 1}; |
| 308 var callbackCount = 0; |
| 309 function recursiveObserver(r) { |
| 310 assertEquals(1, r.length); |
| 311 ++callbackCount; |
| 312 if (r[0].oldValue < 100) ++obj[r[0].name]; |
| 313 } |
| 314 Object.observe(obj, recursiveObserver); |
| 315 ++obj.a; |
| 316 Object.deliverChangeRecords(recursiveObserver); |
| 317 assertEquals(100, callbackCount); |
| 318 |
| 319 var obj1 = {a: 1}; |
| 320 var obj2 = {a: 1}; |
| 321 var recordCount = 0; |
| 322 function recursiveObserver2(r) { |
| 323 recordCount += r.length; |
| 324 if (r[0].oldValue < 100) { |
| 325 ++obj1.a; |
| 326 ++obj2.a; |
| 327 } |
| 328 } |
| 329 Object.observe(obj1, recursiveObserver2); |
| 330 Object.observe(obj2, recursiveObserver2); |
| 331 ++obj1.a; |
| 332 Object.deliverChangeRecords(recursiveObserver2); |
| 333 assertEquals(199, recordCount); |
| 334 |
| 335 |
292 // Observing named properties. | 336 // Observing named properties. |
293 reset(); | 337 reset(); |
294 var obj = {a: 1} | 338 var obj = {a: 1} |
295 Object.observe(obj, observer.callback); | 339 Object.observe(obj, observer.callback); |
296 obj.a = 2; | 340 obj.a = 2; |
297 obj["a"] = 3; | 341 obj["a"] = 3; |
298 delete obj.a; | 342 delete obj.a; |
299 obj.a = 4; | 343 obj.a = 4; |
300 obj.a = 4; // ignored | 344 obj.a = 4; // ignored |
301 obj.a = 5; | 345 obj.a = 5; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 { object: obj, name: "a", type: "reconfigured" }, | 377 { object: obj, name: "a", type: "reconfigured" }, |
334 { object: obj, name: "a", type: "reconfigured" }, | 378 { object: obj, name: "a", type: "reconfigured" }, |
335 { object: obj, name: "a", type: "deleted" }, | 379 { object: obj, name: "a", type: "deleted" }, |
336 { object: obj, name: "a", type: "new" }, | 380 { object: obj, name: "a", type: "new" }, |
337 { object: obj, name: "a", type: "reconfigured" }, | 381 { object: obj, name: "a", type: "reconfigured" }, |
338 { object: obj, name: "a", type: "updated", oldValue: 9 }, | 382 { object: obj, name: "a", type: "updated", oldValue: 9 }, |
339 { object: obj, name: "a", type: "deleted", oldValue: 10 }, | 383 { object: obj, name: "a", type: "deleted", oldValue: 10 }, |
340 { object: obj, name: "a", type: "new" }, | 384 { object: obj, name: "a", type: "new" }, |
341 ]); | 385 ]); |
342 | 386 |
| 387 |
343 // Observing indexed properties. | 388 // Observing indexed properties. |
344 reset(); | 389 reset(); |
345 var obj = {'1': 1} | 390 var obj = {'1': 1} |
346 Object.observe(obj, observer.callback); | 391 Object.observe(obj, observer.callback); |
347 obj[1] = 2; | 392 obj[1] = 2; |
348 obj[1] = 3; | 393 obj[1] = 3; |
349 delete obj[1]; | 394 delete obj[1]; |
350 obj[1] = 4; | 395 obj[1] = 4; |
351 obj[1] = 4; // ignored | 396 obj[1] = 4; // ignored |
352 obj[1] = 5; | 397 obj[1] = 5; |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
597 { object: arr2, name: '1', type: 'deleted', oldValue: 'beta' }, | 642 { object: arr2, name: '1', type: 'deleted', oldValue: 'beta' }, |
598 { object: arr2, name: 'length', type: 'updated', oldValue: 2 }, | 643 { object: arr2, name: 'length', type: 'updated', oldValue: 2 }, |
599 { object: arr2, name: 'length', type: 'reconfigured', oldValue: 1 }, | 644 { object: arr2, name: 'length', type: 'reconfigured', oldValue: 1 }, |
600 { object: arr3, name: '2', type: 'deleted', oldValue: 'goodbye' }, | 645 { object: arr3, name: '2', type: 'deleted', oldValue: 'goodbye' }, |
601 { object: arr3, name: '0', type: 'deleted', oldValue: 'hello' }, | 646 { object: arr3, name: '0', type: 'deleted', oldValue: 'hello' }, |
602 { object: arr3, name: 'length', type: 'updated', oldValue: 6 }, | 647 { object: arr3, name: 'length', type: 'updated', oldValue: 6 }, |
603 { object: arr3, name: 'length', type: 'updated', oldValue: 0 }, | 648 { object: arr3, name: 'length', type: 'updated', oldValue: 0 }, |
604 { object: arr3, name: 'length', type: 'reconfigured', oldValue: 5 }, | 649 { object: arr3, name: 'length', type: 'reconfigured', oldValue: 5 }, |
605 ]); | 650 ]); |
606 | 651 |
| 652 |
607 // Assignments in loops (checking different IC states). | 653 // Assignments in loops (checking different IC states). |
608 reset(); | 654 reset(); |
609 var obj = {}; | 655 var obj = {}; |
610 Object.observe(obj, observer.callback); | 656 Object.observe(obj, observer.callback); |
611 for (var i = 0; i < 5; i++) { | 657 for (var i = 0; i < 5; i++) { |
612 obj["a" + i] = i; | 658 obj["a" + i] = i; |
613 } | 659 } |
614 Object.deliverChangeRecords(observer.callback); | 660 Object.deliverChangeRecords(observer.callback); |
615 observer.assertCallbackRecords([ | 661 observer.assertCallbackRecords([ |
616 { object: obj, name: "a0", type: "new" }, | 662 { object: obj, name: "a0", type: "new" }, |
(...skipping 11 matching lines...) Expand all Loading... |
628 } | 674 } |
629 Object.deliverChangeRecords(observer.callback); | 675 Object.deliverChangeRecords(observer.callback); |
630 observer.assertCallbackRecords([ | 676 observer.assertCallbackRecords([ |
631 { object: obj, name: "0", type: "new" }, | 677 { object: obj, name: "0", type: "new" }, |
632 { object: obj, name: "1", type: "new" }, | 678 { object: obj, name: "1", type: "new" }, |
633 { object: obj, name: "2", type: "new" }, | 679 { object: obj, name: "2", type: "new" }, |
634 { object: obj, name: "3", type: "new" }, | 680 { object: obj, name: "3", type: "new" }, |
635 { object: obj, name: "4", type: "new" }, | 681 { object: obj, name: "4", type: "new" }, |
636 ]); | 682 ]); |
637 | 683 |
| 684 |
638 // Adding elements past the end of an array should notify on length | 685 // Adding elements past the end of an array should notify on length |
639 reset(); | 686 reset(); |
640 var arr = [1, 2, 3]; | 687 var arr = [1, 2, 3]; |
641 Object.observe(arr, observer.callback); | 688 Object.observe(arr, observer.callback); |
642 arr[3] = 10; | 689 arr[3] = 10; |
643 arr[100] = 20; | 690 arr[100] = 20; |
644 Object.defineProperty(arr, '200', {value: 7}); | 691 Object.defineProperty(arr, '200', {value: 7}); |
645 Object.defineProperty(arr, '400', {get: function(){}}); | 692 Object.defineProperty(arr, '400', {get: function(){}}); |
646 arr[50] = 30; // no length change expected | 693 arr[50] = 30; // no length change expected |
647 Object.deliverChangeRecords(observer.callback); | 694 Object.deliverChangeRecords(observer.callback); |
648 observer.assertCallbackRecords([ | 695 observer.assertCallbackRecords([ |
649 { object: arr, name: '3', type: 'new' }, | 696 { object: arr, name: '3', type: 'new' }, |
650 { object: arr, name: 'length', type: 'updated', oldValue: 3 }, | 697 { object: arr, name: 'length', type: 'updated', oldValue: 3 }, |
651 { object: arr, name: '100', type: 'new' }, | 698 { object: arr, name: '100', type: 'new' }, |
652 { object: arr, name: 'length', type: 'updated', oldValue: 4 }, | 699 { object: arr, name: 'length', type: 'updated', oldValue: 4 }, |
653 { object: arr, name: '200', type: 'new' }, | 700 { object: arr, name: '200', type: 'new' }, |
654 { object: arr, name: 'length', type: 'updated', oldValue: 101 }, | 701 { object: arr, name: 'length', type: 'updated', oldValue: 101 }, |
655 { object: arr, name: '400', type: 'new' }, | 702 { object: arr, name: '400', type: 'new' }, |
656 { object: arr, name: 'length', type: 'updated', oldValue: 201 }, | 703 { object: arr, name: 'length', type: 'updated', oldValue: 201 }, |
657 { object: arr, name: '50', type: 'new' }, | 704 { object: arr, name: '50', type: 'new' }, |
658 ]); | 705 ]); |
659 | 706 |
| 707 |
660 // Tests for array methods, first on arrays and then on plain objects | 708 // Tests for array methods, first on arrays and then on plain objects |
661 // | 709 // |
662 // === ARRAYS === | 710 // === ARRAYS === |
663 // | 711 // |
664 // Push | 712 // Push |
665 reset(); | 713 reset(); |
666 var array = [1, 2]; | 714 var array = [1, 2]; |
667 Object.observe(array, observer.callback); | 715 Object.observe(array, observer.callback); |
668 array.push(3, 4); | 716 array.push(3, 4); |
669 Object.deliverChangeRecords(observer.callback); | 717 Object.deliverChangeRecords(observer.callback); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
723 Object.observe(array, observer.callback); | 771 Object.observe(array, observer.callback); |
724 array.splice(1, 1, 4, 5); | 772 array.splice(1, 1, 4, 5); |
725 Object.deliverChangeRecords(observer.callback); | 773 Object.deliverChangeRecords(observer.callback); |
726 observer.assertCallbackRecords([ | 774 observer.assertCallbackRecords([ |
727 { object: array, name: '3', type: 'new' }, | 775 { object: array, name: '3', type: 'new' }, |
728 { object: array, name: 'length', type: 'updated', oldValue: 3 }, | 776 { object: array, name: 'length', type: 'updated', oldValue: 3 }, |
729 { object: array, name: '1', type: 'updated', oldValue: 2 }, | 777 { object: array, name: '1', type: 'updated', oldValue: 2 }, |
730 { object: array, name: '2', type: 'updated', oldValue: 3 }, | 778 { object: array, name: '2', type: 'updated', oldValue: 3 }, |
731 ]); | 779 ]); |
732 | 780 |
| 781 |
733 // | 782 // |
734 // === PLAIN OBJECTS === | 783 // === PLAIN OBJECTS === |
735 // | 784 // |
736 // Push | 785 // Push |
737 reset() | 786 reset() |
738 var array = {0: 1, 1: 2, length: 2} | 787 var array = {0: 1, 1: 2, length: 2} |
739 Object.observe(array, observer.callback); | 788 Object.observe(array, observer.callback); |
740 Array.prototype.push.call(array, 3, 4); | 789 Array.prototype.push.call(array, 3, 4); |
741 Object.deliverChangeRecords(observer.callback); | 790 Object.deliverChangeRecords(observer.callback); |
742 observer.assertCallbackRecords([ | 791 observer.assertCallbackRecords([ |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
829 // TODO(adamk): Add tests for objects with hidden prototypes | 878 // TODO(adamk): Add tests for objects with hidden prototypes |
830 // once we support observing the global object. | 879 // once we support observing the global object. |
831 Object.deliverChangeRecords(observer.callback); | 880 Object.deliverChangeRecords(observer.callback); |
832 observer.assertCallbackRecords([ | 881 observer.assertCallbackRecords([ |
833 { object: obj, name: '__proto__', type: 'prototype', | 882 { object: obj, name: '__proto__', type: 'prototype', |
834 oldValue: Object.prototype }, | 883 oldValue: Object.prototype }, |
835 { object: obj, name: '__proto__', type: 'prototype', oldValue: p }, | 884 { object: obj, name: '__proto__', type: 'prototype', oldValue: p }, |
836 { object: obj, name: '__proto__', type: 'prototype', oldValue: null }, | 885 { object: obj, name: '__proto__', type: 'prototype', oldValue: null }, |
837 ]); | 886 ]); |
838 | 887 |
| 888 |
839 // Function.prototype | 889 // Function.prototype |
840 reset(); | 890 reset(); |
841 var fun = function(){}; | 891 var fun = function(){}; |
842 Object.observe(fun, observer.callback); | 892 Object.observe(fun, observer.callback); |
843 var myproto = {foo: 'bar'}; | 893 var myproto = {foo: 'bar'}; |
844 fun.prototype = myproto; | 894 fun.prototype = myproto; |
845 fun.prototype = 7; | 895 fun.prototype = 7; |
846 fun.prototype = 7; // ignored | 896 fun.prototype = 7; // ignored |
847 Object.defineProperty(fun, 'prototype', {value: 8}); | 897 Object.defineProperty(fun, 'prototype', {value: 8}); |
848 Object.deliverChangeRecords(observer.callback); | 898 Object.deliverChangeRecords(observer.callback); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
897 observer.assertCallbackRecords([ | 947 observer.assertCallbackRecords([ |
898 { object: arr, name: '1', type: 'updated', oldValue: 212 } | 948 { object: arr, name: '1', type: 'updated', oldValue: 212 } |
899 ]); | 949 ]); |
900 } | 950 } |
901 | 951 |
902 for (var b1 = 0; b1 < 2; ++b1) | 952 for (var b1 = 0; b1 < 2; ++b1) |
903 for (var b2 = 0; b2 < 2; ++b2) | 953 for (var b2 = 0; b2 < 2; ++b2) |
904 for (var b3 = 0; b3 < 2; ++b3) | 954 for (var b3 = 0; b3 < 2; ++b3) |
905 TestFastElements(b1 != 0, b2 != 0, b3 != 0); | 955 TestFastElements(b1 != 0, b2 != 0, b3 != 0); |
906 | 956 |
907 | |
908 function TestFastElementsLength(polymorphic, optimize, oldSize, newSize) { | 957 function TestFastElementsLength(polymorphic, optimize, oldSize, newSize) { |
909 var setLength = eval( | 958 var setLength = eval( |
910 "(function setLength(a, n) { a.length = n " + | 959 "(function setLength(a, n) { a.length = n " + |
911 "/* " + polymorphic + " " + optimize + " " + oldSize + " " + newSize + " */" | 960 "/* " + polymorphic + " " + optimize + " " + oldSize + " " + newSize + " */" |
912 + "})" | 961 + "})" |
913 ); | 962 ); |
914 print("TestFastElementsLength:", setLength); | 963 print("TestFastElementsLength:", setLength); |
915 | 964 |
916 function array(n) { | 965 function array(n) { |
917 var arr = new Array(n); | 966 var arr = new Array(n); |
(...skipping 23 matching lines...) Expand all Loading... |
941 assertEquals('updated', lengthRecord.type); | 990 assertEquals('updated', lengthRecord.type); |
942 assertSame(oldSize, lengthRecord.oldValue); | 991 assertSame(oldSize, lengthRecord.oldValue); |
943 } | 992 } |
944 } | 993 } |
945 | 994 |
946 for (var b1 = 0; b1 < 2; ++b1) | 995 for (var b1 = 0; b1 < 2; ++b1) |
947 for (var b2 = 0; b2 < 2; ++b2) | 996 for (var b2 = 0; b2 < 2; ++b2) |
948 for (var n1 = 0; n1 < 3; ++n1) | 997 for (var n1 = 0; n1 < 3; ++n1) |
949 for (var n2 = 0; n2 < 3; ++n2) | 998 for (var n2 = 0; n2 < 3; ++n2) |
950 TestFastElementsLength(b1 != 0, b2 != 0, 20*n1, 20*n2); | 999 TestFastElementsLength(b1 != 0, b2 != 0, 20*n1, 20*n2); |
OLD | NEW |