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