Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(46)

Side by Side Diff: test/mjsunit/harmony/object-observe.js

Issue 11593028: Object.observe: Change semantics of deliverChangeRecords to iterate. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/object-observe.js ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 assertCalled: function() { 58 assertCalled: function() {
59 assertEquals(1, this.callbackCount); 59 assertEquals(1, this.callbackCount);
60 }, 60 },
61 assertRecordCount: function(count) { 61 assertRecordCount: function(count) {
62 this.assertCalled(); 62 this.assertCalled();
63 assertEquals(count, this.records.length); 63 assertEquals(count, this.records.length);
64 }, 64 },
65 assertCallbackRecords: function(recs) { 65 assertCallbackRecords: function(recs) {
66 this.assertRecordCount(recs.length); 66 this.assertRecordCount(recs.length);
67 for (var i = 0; i < recs.length; i++) { 67 for (var i = 0; i < recs.length; i++) {
68 if ('name' in recs[i]) 68 if ('name' in recs[i]) recs[i].name = String(recs[i].name);
69 recs[i].name = String(recs[i].name);
70 print(i, stringifyNoThrow(this.records[i]), stringifyNoThrow(recs[i])); 69 print(i, stringifyNoThrow(this.records[i]), stringifyNoThrow(recs[i]));
71 assertSame(this.records[i].object, recs[i].object); 70 assertSame(this.records[i].object, recs[i].object);
72 assertEquals('string', typeof recs[i].type); 71 assertEquals('string', typeof recs[i].type);
73 assertPropertiesEqual(this.records[i], recs[i]); 72 assertPropertiesEqual(this.records[i], recs[i]);
74 } 73 }
75 } 74 }
76 }; 75 };
77 76
78 observer.callback = function(r) { 77 observer.callback = function(r) {
79 assertEquals(undefined, this); 78 assertEquals(undefined, this);
(...skipping 18 matching lines...) Expand all
98 var changeRecordWithAccessor = { type: 'foo' }; 97 var changeRecordWithAccessor = { type: 'foo' };
99 var recordCreated = false; 98 var recordCreated = false;
100 Object.defineProperty(changeRecordWithAccessor, 'name', { 99 Object.defineProperty(changeRecordWithAccessor, 'name', {
101 get: function() { 100 get: function() {
102 recordCreated = true; 101 recordCreated = true;
103 return "bar"; 102 return "bar";
104 }, 103 },
105 enumerable: true 104 enumerable: true
106 }) 105 })
107 106
107
108 // Object.observe 108 // Object.observe
109 assertThrows(function() { Object.observe("non-object", observer.callback); }, Ty peError); 109 assertThrows(function() { Object.observe("non-object", observer.callback); }, Ty peError);
110 assertThrows(function() { Object.observe(obj, nonFunction); }, TypeError); 110 assertThrows(function() { Object.observe(obj, nonFunction); }, TypeError);
111 assertThrows(function() { Object.observe(obj, frozenFunction); }, TypeError); 111 assertThrows(function() { Object.observe(obj, frozenFunction); }, TypeError);
112 assertEquals(obj, Object.observe(obj, observer.callback)); 112 assertEquals(obj, Object.observe(obj, observer.callback));
113 113
114
114 // Object.unobserve 115 // Object.unobserve
115 assertThrows(function() { Object.unobserve(4, observer.callback); }, TypeError); 116 assertThrows(function() { Object.unobserve(4, observer.callback); }, TypeError);
116 assertThrows(function() { Object.unobserve(obj, nonFunction); }, TypeError); 117 assertThrows(function() { Object.unobserve(obj, nonFunction); }, TypeError);
117 assertEquals(obj, Object.unobserve(obj, observer.callback)); 118 assertEquals(obj, Object.unobserve(obj, observer.callback));
118 119
120
119 // Object.getNotifier 121 // Object.getNotifier
120 var notifier = Object.getNotifier(obj); 122 var notifier = Object.getNotifier(obj);
121 assertSame(notifier, Object.getNotifier(obj)); 123 assertSame(notifier, Object.getNotifier(obj));
122 assertEquals(null, Object.getNotifier(Object.freeze({}))); 124 assertEquals(null, Object.getNotifier(Object.freeze({})));
123 assertFalse(notifier.hasOwnProperty('notify')); 125 assertFalse(notifier.hasOwnProperty('notify'));
124 assertEquals([], Object.keys(notifier)); 126 assertEquals([], Object.keys(notifier));
125 var notifyDesc = Object.getOwnPropertyDescriptor(notifier.__proto__, 'notify'); 127 var notifyDesc = Object.getOwnPropertyDescriptor(notifier.__proto__, 'notify');
126 assertTrue(notifyDesc.configurable); 128 assertTrue(notifyDesc.configurable);
127 assertTrue(notifyDesc.writable); 129 assertTrue(notifyDesc.writable);
128 assertFalse(notifyDesc.enumerable); 130 assertFalse(notifyDesc.enumerable);
129 assertThrows(function() { notifier.notify({}); }, TypeError); 131 assertThrows(function() { notifier.notify({}); }, TypeError);
130 assertThrows(function() { notifier.notify({ type: 4 }); }, TypeError); 132 assertThrows(function() { notifier.notify({ type: 4 }); }, TypeError);
131 var notify = notifier.notify; 133 var notify = notifier.notify;
132 assertThrows(function() { notify.call(undefined, { type: 'a' }); }, TypeError); 134 assertThrows(function() { notify.call(undefined, { type: 'a' }); }, TypeError);
133 assertThrows(function() { notify.call(null, { type: 'a' }); }, TypeError); 135 assertThrows(function() { notify.call(null, { type: 'a' }); }, TypeError);
134 assertThrows(function() { notify.call(5, { type: 'a' }); }, TypeError); 136 assertThrows(function() { notify.call(5, { type: 'a' }); }, TypeError);
135 assertThrows(function() { notify.call('hello', { type: 'a' }); }, TypeError); 137 assertThrows(function() { notify.call('hello', { type: 'a' }); }, TypeError);
136 assertThrows(function() { notify.call(false, { type: 'a' }); }, TypeError); 138 assertThrows(function() { notify.call(false, { type: 'a' }); }, TypeError);
137 assertThrows(function() { notify.call({}, { type: 'a' }); }, TypeError); 139 assertThrows(function() { notify.call({}, { type: 'a' }); }, TypeError);
138 assertFalse(recordCreated); 140 assertFalse(recordCreated);
139 notifier.notify(changeRecordWithAccessor); 141 notifier.notify(changeRecordWithAccessor);
140 assertFalse(recordCreated); // not observed yet 142 assertFalse(recordCreated); // not observed yet
141 143
144
142 // Object.deliverChangeRecords 145 // Object.deliverChangeRecords
143 assertThrows(function() { Object.deliverChangeRecords(nonFunction); }, TypeError ); 146 assertThrows(function() { Object.deliverChangeRecords(nonFunction); }, TypeError );
144 147
145 Object.observe(obj, observer.callback); 148 Object.observe(obj, observer.callback);
146 149
150
147 // notify uses to [[CreateOwnProperty]] to create changeRecord; 151 // notify uses to [[CreateOwnProperty]] to create changeRecord;
148 reset(); 152 reset();
149 var protoExpandoAccessed = false; 153 var protoExpandoAccessed = false;
150 Object.defineProperty(Object.prototype, 'protoExpando', 154 Object.defineProperty(Object.prototype, 'protoExpando',
151 { 155 {
152 configurable: true, 156 configurable: true,
153 set: function() { protoExpandoAccessed = true; } 157 set: function() { protoExpandoAccessed = true; }
154 } 158 }
155 ); 159 );
156 notifier.notify({ type: 'foo', protoExpando: 'val'}); 160 notifier.notify({ type: 'foo', protoExpando: 'val'});
157 assertFalse(protoExpandoAccessed); 161 assertFalse(protoExpandoAccessed);
158 delete Object.prototype.protoExpando; 162 delete Object.prototype.protoExpando;
159 Object.deliverChangeRecords(observer.callback); 163 Object.deliverChangeRecords(observer.callback);
160 164
165
161 // Multiple records are delivered. 166 // Multiple records are delivered.
162 reset(); 167 reset();
163 notifier.notify({ 168 notifier.notify({
164 type: 'updated', 169 type: 'updated',
165 name: 'foo', 170 name: 'foo',
166 expando: 1 171 expando: 1
167 }); 172 });
168 173
169 notifier.notify({ 174 notifier.notify({
170 object: notifier, // object property is ignored 175 object: notifier, // object property is ignored
171 type: 'deleted', 176 type: 'deleted',
172 name: 'bar', 177 name: 'bar',
173 expando2: 'str' 178 expando2: 'str'
174 }); 179 });
175 Object.deliverChangeRecords(observer.callback); 180 Object.deliverChangeRecords(observer.callback);
176 observer.assertCallbackRecords([ 181 observer.assertCallbackRecords([
177 { object: obj, name: 'foo', type: 'updated', expando: 1 }, 182 { object: obj, name: 'foo', type: 'updated', expando: 1 },
178 { object: obj, name: 'bar', type: 'deleted', expando2: 'str' } 183 { object: obj, name: 'bar', type: 'deleted', expando2: 'str' }
179 ]); 184 ]);
180 185
186
181 // No delivery takes place if no records are pending 187 // No delivery takes place if no records are pending
182 reset(); 188 reset();
183 Object.deliverChangeRecords(observer.callback); 189 Object.deliverChangeRecords(observer.callback);
184 observer.assertNotCalled(); 190 observer.assertNotCalled();
185 191
192
186 // Multiple observation has no effect. 193 // Multiple observation has no effect.
187 reset(); 194 reset();
188 Object.observe(obj, observer.callback); 195 Object.observe(obj, observer.callback);
189 Object.observe(obj, observer.callback); 196 Object.observe(obj, observer.callback);
190 Object.getNotifier(obj).notify({ 197 Object.getNotifier(obj).notify({
191 type: 'foo', 198 type: 'foo',
192 }); 199 });
193 Object.deliverChangeRecords(observer.callback); 200 Object.deliverChangeRecords(observer.callback);
194 observer.assertCalled(); 201 observer.assertCalled();
195 202
203
196 // Observation can be stopped. 204 // Observation can be stopped.
197 reset(); 205 reset();
198 Object.unobserve(obj, observer.callback); 206 Object.unobserve(obj, observer.callback);
199 Object.getNotifier(obj).notify({ 207 Object.getNotifier(obj).notify({
200 type: 'foo', 208 type: 'foo',
201 }); 209 });
202 Object.deliverChangeRecords(observer.callback); 210 Object.deliverChangeRecords(observer.callback);
203 observer.assertNotCalled(); 211 observer.assertNotCalled();
204 212
213
205 // Multiple unobservation has no effect 214 // Multiple unobservation has no effect
206 reset(); 215 reset();
207 Object.unobserve(obj, observer.callback); 216 Object.unobserve(obj, observer.callback);
208 Object.unobserve(obj, observer.callback); 217 Object.unobserve(obj, observer.callback);
209 Object.getNotifier(obj).notify({ 218 Object.getNotifier(obj).notify({
210 type: 'foo', 219 type: 'foo',
211 }); 220 });
212 Object.deliverChangeRecords(observer.callback); 221 Object.deliverChangeRecords(observer.callback);
213 observer.assertNotCalled(); 222 observer.assertNotCalled();
214 223
224
215 // Re-observation works and only includes changeRecords after of call. 225 // Re-observation works and only includes changeRecords after of call.
216 reset(); 226 reset();
217 Object.getNotifier(obj).notify({ 227 Object.getNotifier(obj).notify({
218 type: 'foo', 228 type: 'foo',
219 }); 229 });
220 Object.observe(obj, observer.callback); 230 Object.observe(obj, observer.callback);
221 Object.getNotifier(obj).notify({ 231 Object.getNotifier(obj).notify({
222 type: 'foo', 232 type: 'foo',
223 }); 233 });
224 records = undefined; 234 records = undefined;
225 Object.deliverChangeRecords(observer.callback); 235 Object.deliverChangeRecords(observer.callback);
226 observer.assertRecordCount(1); 236 observer.assertRecordCount(1);
227 237
238
228 // Observing a continuous stream of changes, while itermittantly unobserving. 239 // Observing a continuous stream of changes, while itermittantly unobserving.
229 reset(); 240 reset();
230 Object.observe(obj, observer.callback); 241 Object.observe(obj, observer.callback);
231 Object.getNotifier(obj).notify({ 242 Object.getNotifier(obj).notify({
232 type: 'foo', 243 type: 'foo',
233 val: 1 244 val: 1
234 }); 245 });
235 246
236 Object.unobserve(obj, observer.callback); 247 Object.unobserve(obj, observer.callback);
237 Object.getNotifier(obj).notify({ 248 Object.getNotifier(obj).notify({
(...skipping 20 matching lines...) Expand all
258 }); 269 });
259 270
260 Object.unobserve(obj, observer.callback); 271 Object.unobserve(obj, observer.callback);
261 Object.deliverChangeRecords(observer.callback); 272 Object.deliverChangeRecords(observer.callback);
262 observer.assertCallbackRecords([ 273 observer.assertCallbackRecords([
263 { object: obj, type: 'foo', val: 1 }, 274 { object: obj, type: 'foo', val: 1 },
264 { object: obj, type: 'foo', val: 3 }, 275 { object: obj, type: 'foo', val: 3 },
265 { object: obj, type: 'foo', val: 5 } 276 { object: obj, type: 'foo', val: 5 }
266 ]); 277 ]);
267 278
279
268 // Observing multiple objects; records appear in order. 280 // Observing multiple objects; records appear in order.
269 reset(); 281 reset();
270 var obj2 = {}; 282 var obj2 = {};
271 var obj3 = {} 283 var obj3 = {}
272 Object.observe(obj, observer.callback); 284 Object.observe(obj, observer.callback);
273 Object.observe(obj3, observer.callback); 285 Object.observe(obj3, observer.callback);
274 Object.observe(obj2, observer.callback); 286 Object.observe(obj2, observer.callback);
275 Object.getNotifier(obj).notify({ 287 Object.getNotifier(obj).notify({
276 type: 'foo1', 288 type: 'foo1',
277 }); 289 });
278 Object.getNotifier(obj2).notify({ 290 Object.getNotifier(obj2).notify({
279 type: 'foo2', 291 type: 'foo2',
280 }); 292 });
281 Object.getNotifier(obj3).notify({ 293 Object.getNotifier(obj3).notify({
282 type: 'foo3', 294 type: 'foo3',
283 }); 295 });
284 Object.observe(obj3, observer.callback); 296 Object.observe(obj3, observer.callback);
285 Object.deliverChangeRecords(observer.callback); 297 Object.deliverChangeRecords(observer.callback);
286 observer.assertCallbackRecords([ 298 observer.assertCallbackRecords([
287 { object: obj, type: 'foo1' }, 299 { object: obj, type: 'foo1' },
288 { object: obj2, type: 'foo2' }, 300 { object: obj2, type: 'foo2' },
289 { object: obj3, type: 'foo3' } 301 { object: obj3, type: 'foo3' }
290 ]); 302 ]);
291 303
304
305 // Recursive observation.
306 var obj = {a: 1};
307 var callbackCount = 0;
308 function recursiveObserver(r) {
309 assertEquals(1, r.length);
310 ++callbackCount;
311 if (r[0].oldValue < 100) ++obj[r[0].name];
312 }
313 Object.observe(obj, recursiveObserver);
314 ++obj.a;
315 Object.deliverChangeRecords(recursiveObserver);
316 assertEquals(100, callbackCount);
317
318 var obj1 = {a: 1};
319 var obj2 = {a: 1};
320 var recordCount = 0;
321 function recursiveObserver2(r) {
322 recordCount += r.length;
323 if (r[0].oldValue < 100) {
324 ++obj1.a;
325 ++obj2.a;
326 }
327 }
328 Object.observe(obj1, recursiveObserver2);
329 Object.observe(obj2, recursiveObserver2);
330 ++obj1.a;
331 Object.deliverChangeRecords(recursiveObserver2);
332 assertEquals(199, recordCount);
333
334
292 // Observing named properties. 335 // Observing named properties.
293 reset(); 336 reset();
294 var obj = {a: 1} 337 var obj = {a: 1}
295 Object.observe(obj, observer.callback); 338 Object.observe(obj, observer.callback);
296 obj.a = 2; 339 obj.a = 2;
297 obj["a"] = 3; 340 obj["a"] = 3;
298 delete obj.a; 341 delete obj.a;
299 obj.a = 4; 342 obj.a = 4;
300 obj.a = 4; // ignored 343 obj.a = 4; // ignored
301 obj.a = 5; 344 obj.a = 5;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 { object: obj, name: "a", type: "reconfigured" }, 376 { object: obj, name: "a", type: "reconfigured" },
334 { object: obj, name: "a", type: "reconfigured" }, 377 { object: obj, name: "a", type: "reconfigured" },
335 { object: obj, name: "a", type: "deleted" }, 378 { object: obj, name: "a", type: "deleted" },
336 { object: obj, name: "a", type: "new" }, 379 { object: obj, name: "a", type: "new" },
337 { object: obj, name: "a", type: "reconfigured" }, 380 { object: obj, name: "a", type: "reconfigured" },
338 { object: obj, name: "a", type: "updated", oldValue: 9 }, 381 { object: obj, name: "a", type: "updated", oldValue: 9 },
339 { object: obj, name: "a", type: "deleted", oldValue: 10 }, 382 { object: obj, name: "a", type: "deleted", oldValue: 10 },
340 { object: obj, name: "a", type: "new" }, 383 { object: obj, name: "a", type: "new" },
341 ]); 384 ]);
342 385
386
343 // Observing indexed properties. 387 // Observing indexed properties.
344 reset(); 388 reset();
345 var obj = {'1': 1} 389 var obj = {'1': 1}
346 Object.observe(obj, observer.callback); 390 Object.observe(obj, observer.callback);
347 obj[1] = 2; 391 obj[1] = 2;
348 obj[1] = 3; 392 obj[1] = 3;
349 delete obj[1]; 393 delete obj[1];
350 obj[1] = 4; 394 obj[1] = 4;
351 obj[1] = 4; // ignored 395 obj[1] = 4; // ignored
352 obj[1] = 5; 396 obj[1] = 5;
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 function TestObserveNonConfigurable(obj, prop, desc) { 503 function TestObserveNonConfigurable(obj, prop, desc) {
460 reset(); 504 reset();
461 obj[prop] = 1; 505 obj[prop] = 1;
462 Object.observe(obj, observer.callback); 506 Object.observe(obj, observer.callback);
463 obj[prop] = 4; 507 obj[prop] = 4;
464 obj[prop] = 4; // ignored 508 obj[prop] = 4; // ignored
465 obj[prop] = 5; 509 obj[prop] = 5;
466 Object.defineProperty(obj, prop, {value: 6}); 510 Object.defineProperty(obj, prop, {value: 6});
467 Object.defineProperty(obj, prop, {value: 6}); // ignored 511 Object.defineProperty(obj, prop, {value: 6}); // ignored
468 Object.defineProperty(obj, prop, {value: 7}); 512 Object.defineProperty(obj, prop, {value: 7});
469 Object.defineProperty(obj, prop, 513 Object.defineProperty(obj, prop, {enumerable: desc.enumerable}); // ignored
470 {enumerable: desc.enumerable}); // ignored
471 Object.defineProperty(obj, prop, {writable: false}); 514 Object.defineProperty(obj, prop, {writable: false});
472 obj[prop] = 7; // ignored 515 obj[prop] = 7; // ignored
473 Object.deliverChangeRecords(observer.callback); 516 Object.deliverChangeRecords(observer.callback);
474 observer.assertCallbackRecords([ 517 observer.assertCallbackRecords([
475 { object: obj, name: prop, type: "updated", oldValue: 1 }, 518 { object: obj, name: prop, type: "updated", oldValue: 1 },
476 { object: obj, name: prop, type: "updated", oldValue: 4 }, 519 { object: obj, name: prop, type: "updated", oldValue: 4 },
477 { object: obj, name: prop, type: "updated", oldValue: 5 }, 520 { object: obj, name: prop, type: "updated", oldValue: 5 },
478 { object: obj, name: prop, type: "updated", oldValue: 6 }, 521 { object: obj, name: prop, type: "updated", oldValue: 6 },
479 { object: obj, name: prop, type: "reconfigured", oldValue: 7 }, 522 { object: obj, name: prop, type: "reconfigured", oldValue: 7 },
480 ]); 523 ]);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
534 new Set, new Map, new WeakMap, 577 new Set, new Map, new WeakMap,
535 new ArrayBuffer(10), new Int32Array(5), 578 new ArrayBuffer(10), new Int32Array(5),
536 createProxy(Proxy.create, null), 579 createProxy(Proxy.create, null),
537 createProxy(Proxy.createFunction, function(){}), 580 createProxy(Proxy.createFunction, function(){}),
538 ]; 581 ];
539 var properties = ["a", "1", 1, "length", "prototype", "name", "caller"]; 582 var properties = ["a", "1", 1, "length", "prototype", "name", "caller"];
540 583
541 // Cases that yield non-standard results. 584 // Cases that yield non-standard results.
542 function blacklisted(obj, prop) { 585 function blacklisted(obj, prop) {
543 return (obj instanceof Int32Array && prop == 1) || 586 return (obj instanceof Int32Array && prop == 1) ||
544 (obj instanceof Int32Array && prop === "length") || 587 (obj instanceof Int32Array && prop === "length") ||
545 (obj instanceof ArrayBuffer && prop == 1) 588 (obj instanceof ArrayBuffer && prop == 1)
546 } 589 }
547 590
548 for (var i in objects) for (var j in properties) { 591 for (var i in objects) for (var j in properties) {
549 var obj = objects[i]; 592 var obj = objects[i];
550 var prop = properties[j]; 593 var prop = properties[j];
551 if (blacklisted(obj, prop)) continue; 594 if (blacklisted(obj, prop)) continue;
552 var desc = Object.getOwnPropertyDescriptor(obj, prop); 595 var desc = Object.getOwnPropertyDescriptor(obj, prop);
553 print("***", typeof obj, stringifyNoThrow(obj), prop); 596 print("***", typeof obj, stringifyNoThrow(obj), prop);
554 if (!desc || desc.configurable) 597 if (!desc || desc.configurable)
555 TestObserveConfigurable(obj, prop); 598 TestObserveConfigurable(obj, prop);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
597 { object: arr2, name: '1', type: 'deleted', oldValue: 'beta' }, 640 { object: arr2, name: '1', type: 'deleted', oldValue: 'beta' },
598 { object: arr2, name: 'length', type: 'updated', oldValue: 2 }, 641 { object: arr2, name: 'length', type: 'updated', oldValue: 2 },
599 { object: arr2, name: 'length', type: 'reconfigured', oldValue: 1 }, 642 { object: arr2, name: 'length', type: 'reconfigured', oldValue: 1 },
600 { object: arr3, name: '2', type: 'deleted', oldValue: 'goodbye' }, 643 { object: arr3, name: '2', type: 'deleted', oldValue: 'goodbye' },
601 { object: arr3, name: '0', type: 'deleted', oldValue: 'hello' }, 644 { object: arr3, name: '0', type: 'deleted', oldValue: 'hello' },
602 { object: arr3, name: 'length', type: 'updated', oldValue: 6 }, 645 { object: arr3, name: 'length', type: 'updated', oldValue: 6 },
603 { object: arr3, name: 'length', type: 'updated', oldValue: 0 }, 646 { object: arr3, name: 'length', type: 'updated', oldValue: 0 },
604 { object: arr3, name: 'length', type: 'reconfigured', oldValue: 5 }, 647 { object: arr3, name: 'length', type: 'reconfigured', oldValue: 5 },
605 ]); 648 ]);
606 649
650
607 // Assignments in loops (checking different IC states). 651 // Assignments in loops (checking different IC states).
608 reset(); 652 reset();
609 var obj = {}; 653 var obj = {};
610 Object.observe(obj, observer.callback); 654 Object.observe(obj, observer.callback);
611 for (var i = 0; i < 5; i++) { 655 for (var i = 0; i < 5; i++) {
612 obj["a" + i] = i; 656 obj["a" + i] = i;
613 } 657 }
614 Object.deliverChangeRecords(observer.callback); 658 Object.deliverChangeRecords(observer.callback);
615 observer.assertCallbackRecords([ 659 observer.assertCallbackRecords([
616 { object: obj, name: "a0", type: "new" }, 660 { object: obj, name: "a0", type: "new" },
(...skipping 11 matching lines...) Expand all
628 } 672 }
629 Object.deliverChangeRecords(observer.callback); 673 Object.deliverChangeRecords(observer.callback);
630 observer.assertCallbackRecords([ 674 observer.assertCallbackRecords([
631 { object: obj, name: "0", type: "new" }, 675 { object: obj, name: "0", type: "new" },
632 { object: obj, name: "1", type: "new" }, 676 { object: obj, name: "1", type: "new" },
633 { object: obj, name: "2", type: "new" }, 677 { object: obj, name: "2", type: "new" },
634 { object: obj, name: "3", type: "new" }, 678 { object: obj, name: "3", type: "new" },
635 { object: obj, name: "4", type: "new" }, 679 { object: obj, name: "4", type: "new" },
636 ]); 680 ]);
637 681
682
638 // Adding elements past the end of an array should notify on length 683 // Adding elements past the end of an array should notify on length
639 reset(); 684 reset();
640 var arr = [1, 2, 3]; 685 var arr = [1, 2, 3];
641 Object.observe(arr, observer.callback); 686 Object.observe(arr, observer.callback);
642 arr[3] = 10; 687 arr[3] = 10;
643 arr[100] = 20; 688 arr[100] = 20;
644 Object.defineProperty(arr, '200', {value: 7}); 689 Object.defineProperty(arr, '200', {value: 7});
645 Object.defineProperty(arr, '400', {get: function(){}}); 690 Object.defineProperty(arr, '400', {get: function(){}});
646 arr[50] = 30; // no length change expected 691 arr[50] = 30; // no length change expected
647 Object.deliverChangeRecords(observer.callback); 692 Object.deliverChangeRecords(observer.callback);
648 observer.assertCallbackRecords([ 693 observer.assertCallbackRecords([
649 { object: arr, name: '3', type: 'new' }, 694 { object: arr, name: '3', type: 'new' },
650 { object: arr, name: 'length', type: 'updated', oldValue: 3 }, 695 { object: arr, name: 'length', type: 'updated', oldValue: 3 },
651 { object: arr, name: '100', type: 'new' }, 696 { object: arr, name: '100', type: 'new' },
652 { object: arr, name: 'length', type: 'updated', oldValue: 4 }, 697 { object: arr, name: 'length', type: 'updated', oldValue: 4 },
653 { object: arr, name: '200', type: 'new' }, 698 { object: arr, name: '200', type: 'new' },
654 { object: arr, name: 'length', type: 'updated', oldValue: 101 }, 699 { object: arr, name: 'length', type: 'updated', oldValue: 101 },
655 { object: arr, name: '400', type: 'new' }, 700 { object: arr, name: '400', type: 'new' },
656 { object: arr, name: 'length', type: 'updated', oldValue: 201 }, 701 { object: arr, name: 'length', type: 'updated', oldValue: 201 },
657 { object: arr, name: '50', type: 'new' }, 702 { object: arr, name: '50', type: 'new' },
658 ]); 703 ]);
659 704
705
660 // Tests for array methods, first on arrays and then on plain objects 706 // Tests for array methods, first on arrays and then on plain objects
661 // 707 //
662 // === ARRAYS === 708 // === ARRAYS ===
663 // 709 //
664 // Push 710 // Push
665 reset(); 711 reset();
666 var array = [1, 2]; 712 var array = [1, 2];
667 Object.observe(array, observer.callback); 713 Object.observe(array, observer.callback);
668 array.push(3, 4); 714 array.push(3, 4);
669 Object.deliverChangeRecords(observer.callback); 715 Object.deliverChangeRecords(observer.callback);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
723 Object.observe(array, observer.callback); 769 Object.observe(array, observer.callback);
724 array.splice(1, 1, 4, 5); 770 array.splice(1, 1, 4, 5);
725 Object.deliverChangeRecords(observer.callback); 771 Object.deliverChangeRecords(observer.callback);
726 observer.assertCallbackRecords([ 772 observer.assertCallbackRecords([
727 { object: array, name: '3', type: 'new' }, 773 { object: array, name: '3', type: 'new' },
728 { object: array, name: 'length', type: 'updated', oldValue: 3 }, 774 { object: array, name: 'length', type: 'updated', oldValue: 3 },
729 { object: array, name: '1', type: 'updated', oldValue: 2 }, 775 { object: array, name: '1', type: 'updated', oldValue: 2 },
730 { object: array, name: '2', type: 'updated', oldValue: 3 }, 776 { object: array, name: '2', type: 'updated', oldValue: 3 },
731 ]); 777 ]);
732 778
779
733 // 780 //
734 // === PLAIN OBJECTS === 781 // === PLAIN OBJECTS ===
735 // 782 //
736 // Push 783 // Push
737 reset() 784 reset()
738 var array = {0: 1, 1: 2, length: 2} 785 var array = {0: 1, 1: 2, length: 2}
739 Object.observe(array, observer.callback); 786 Object.observe(array, observer.callback);
740 Array.prototype.push.call(array, 3, 4); 787 Array.prototype.push.call(array, 3, 4);
741 Object.deliverChangeRecords(observer.callback); 788 Object.deliverChangeRecords(observer.callback);
742 observer.assertCallbackRecords([ 789 observer.assertCallbackRecords([
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
829 // TODO(adamk): Add tests for objects with hidden prototypes 876 // TODO(adamk): Add tests for objects with hidden prototypes
830 // once we support observing the global object. 877 // once we support observing the global object.
831 Object.deliverChangeRecords(observer.callback); 878 Object.deliverChangeRecords(observer.callback);
832 observer.assertCallbackRecords([ 879 observer.assertCallbackRecords([
833 { object: obj, name: '__proto__', type: 'prototype', 880 { object: obj, name: '__proto__', type: 'prototype',
834 oldValue: Object.prototype }, 881 oldValue: Object.prototype },
835 { object: obj, name: '__proto__', type: 'prototype', oldValue: p }, 882 { object: obj, name: '__proto__', type: 'prototype', oldValue: p },
836 { object: obj, name: '__proto__', type: 'prototype', oldValue: null }, 883 { object: obj, name: '__proto__', type: 'prototype', oldValue: null },
837 ]); 884 ]);
838 885
886
839 // Function.prototype 887 // Function.prototype
840 reset(); 888 reset();
841 var fun = function(){}; 889 var fun = function(){};
842 Object.observe(fun, observer.callback); 890 Object.observe(fun, observer.callback);
843 var myproto = {foo: 'bar'}; 891 var myproto = {foo: 'bar'};
844 fun.prototype = myproto; 892 fun.prototype = myproto;
845 fun.prototype = 7; 893 fun.prototype = 7;
846 fun.prototype = 7; // ignored 894 fun.prototype = 7; // ignored
847 Object.defineProperty(fun, 'prototype', {value: 8}); 895 Object.defineProperty(fun, 'prototype', {value: 8});
848 Object.deliverChangeRecords(observer.callback); 896 Object.deliverChangeRecords(observer.callback);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
897 observer.assertCallbackRecords([ 945 observer.assertCallbackRecords([
898 { object: arr, name: '1', type: 'updated', oldValue: 212 } 946 { object: arr, name: '1', type: 'updated', oldValue: 212 }
899 ]); 947 ]);
900 } 948 }
901 949
902 for (var b1 = 0; b1 < 2; ++b1) 950 for (var b1 = 0; b1 < 2; ++b1)
903 for (var b2 = 0; b2 < 2; ++b2) 951 for (var b2 = 0; b2 < 2; ++b2)
904 for (var b3 = 0; b3 < 2; ++b3) 952 for (var b3 = 0; b3 < 2; ++b3)
905 TestFastElements(b1 != 0, b2 != 0, b3 != 0); 953 TestFastElements(b1 != 0, b2 != 0, b3 != 0);
906 954
907
908 function TestFastElementsLength(polymorphic, optimize, oldSize, newSize) { 955 function TestFastElementsLength(polymorphic, optimize, oldSize, newSize) {
909 var setLength = eval( 956 var setLength = eval(
910 "(function setLength(a, n) { a.length = n " + 957 "(function setLength(a, n) { a.length = n " +
911 "/* " + polymorphic + " " + optimize + " " + oldSize + " " + newSize + " */" 958 "/* " + polymorphic + " " + optimize + " " + oldSize + " " + newSize + " */"
912 + "})" 959 + "})"
913 ); 960 );
914 print("TestFastElementsLength:", setLength); 961 print("TestFastElementsLength:", setLength);
915 962
916 function array(n) { 963 function array(n) {
917 var arr = new Array(n); 964 var arr = new Array(n);
(...skipping 23 matching lines...) Expand all
941 assertEquals('updated', lengthRecord.type); 988 assertEquals('updated', lengthRecord.type);
942 assertSame(oldSize, lengthRecord.oldValue); 989 assertSame(oldSize, lengthRecord.oldValue);
943 } 990 }
944 } 991 }
945 992
946 for (var b1 = 0; b1 < 2; ++b1) 993 for (var b1 = 0; b1 < 2; ++b1)
947 for (var b2 = 0; b2 < 2; ++b2) 994 for (var b2 = 0; b2 < 2; ++b2)
948 for (var n1 = 0; n1 < 3; ++n1) 995 for (var n1 = 0; n1 < 3; ++n1)
949 for (var n2 = 0; n2 < 3; ++n2) 996 for (var n2 = 0; n2 < 3; ++n2)
950 TestFastElementsLength(b1 != 0, b2 != 0, 20*n1, 20*n2); 997 TestFastElementsLength(b1 != 0, b2 != 0, 20*n1, 20*n2);
OLDNEW
« no previous file with comments | « src/object-observe.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698