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

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

Issue 71163006: Merge bleeding_edge r17376:17693. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Fix all.gyp Created 7 years, 1 month 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 | « test/mjsunit/getters-on-elements.js ('k') | test/mjsunit/harmony/private.js » ('j') | 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 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 ); 180 );
181 notifier.notify({ type: 'foo', protoExpando: 'val'}); 181 notifier.notify({ type: 'foo', protoExpando: 'val'});
182 assertFalse(protoExpandoAccessed); 182 assertFalse(protoExpandoAccessed);
183 delete Object.prototype.protoExpando; 183 delete Object.prototype.protoExpando;
184 Object.deliverChangeRecords(observer.callback); 184 Object.deliverChangeRecords(observer.callback);
185 185
186 186
187 // Multiple records are delivered. 187 // Multiple records are delivered.
188 reset(); 188 reset();
189 notifier.notify({ 189 notifier.notify({
190 type: 'updated', 190 type: 'update',
191 name: 'foo', 191 name: 'foo',
192 expando: 1 192 expando: 1
193 }); 193 });
194 194
195 notifier.notify({ 195 notifier.notify({
196 object: notifier, // object property is ignored 196 object: notifier, // object property is ignored
197 type: 'deleted', 197 type: 'delete',
198 name: 'bar', 198 name: 'bar',
199 expando2: 'str' 199 expando2: 'str'
200 }); 200 });
201 Object.deliverChangeRecords(observer.callback); 201 Object.deliverChangeRecords(observer.callback);
202 observer.assertCallbackRecords([ 202 observer.assertCallbackRecords([
203 { object: obj, name: 'foo', type: 'updated', expando: 1 }, 203 { object: obj, name: 'foo', type: 'update', expando: 1 },
204 { object: obj, name: 'bar', type: 'deleted', expando2: 'str' } 204 { object: obj, name: 'bar', type: 'delete', expando2: 'str' }
205 ]); 205 ]);
206 206
207 // Non-string accept values are coerced to strings 207 // Non-string accept values are coerced to strings
208 reset(); 208 reset();
209 Object.observe(obj, observer.callback, [true, 1, null, undefined]); 209 Object.observe(obj, observer.callback, [true, 1, null, undefined]);
210 notifier = Object.getNotifier(obj); 210 notifier = Object.getNotifier(obj);
211 notifier.notify({ type: 'true' }); 211 notifier.notify({ type: 'true' });
212 notifier.notify({ type: 'false' }); 212 notifier.notify({ type: 'false' });
213 notifier.notify({ type: '1' }); 213 notifier.notify({ type: '1' });
214 notifier.notify({ type: '-1' }); 214 notifier.notify({ type: '-1' });
(...skipping 13 matching lines...) Expand all
228 reset(); 228 reset();
229 Object.deliverChangeRecords(observer.callback); 229 Object.deliverChangeRecords(observer.callback);
230 observer.assertNotCalled(); 230 observer.assertNotCalled();
231 231
232 232
233 // Multiple observation has no effect. 233 // Multiple observation has no effect.
234 reset(); 234 reset();
235 Object.observe(obj, observer.callback); 235 Object.observe(obj, observer.callback);
236 Object.observe(obj, observer.callback); 236 Object.observe(obj, observer.callback);
237 Object.getNotifier(obj).notify({ 237 Object.getNotifier(obj).notify({
238 type: 'updated', 238 type: 'update',
239 }); 239 });
240 Object.deliverChangeRecords(observer.callback); 240 Object.deliverChangeRecords(observer.callback);
241 observer.assertCalled(); 241 observer.assertCalled();
242 242
243 243
244 // Observation can be stopped. 244 // Observation can be stopped.
245 reset(); 245 reset();
246 Object.unobserve(obj, observer.callback); 246 Object.unobserve(obj, observer.callback);
247 Object.getNotifier(obj).notify({ 247 Object.getNotifier(obj).notify({
248 type: 'updated', 248 type: 'update',
249 }); 249 });
250 Object.deliverChangeRecords(observer.callback); 250 Object.deliverChangeRecords(observer.callback);
251 observer.assertNotCalled(); 251 observer.assertNotCalled();
252 252
253 253
254 // Multiple unobservation has no effect 254 // Multiple unobservation has no effect
255 reset(); 255 reset();
256 Object.unobserve(obj, observer.callback); 256 Object.unobserve(obj, observer.callback);
257 Object.unobserve(obj, observer.callback); 257 Object.unobserve(obj, observer.callback);
258 Object.getNotifier(obj).notify({ 258 Object.getNotifier(obj).notify({
259 type: 'updated', 259 type: 'update',
260 }); 260 });
261 Object.deliverChangeRecords(observer.callback); 261 Object.deliverChangeRecords(observer.callback);
262 observer.assertNotCalled(); 262 observer.assertNotCalled();
263 263
264 264
265 // Re-observation works and only includes changeRecords after of call. 265 // Re-observation works and only includes changeRecords after of call.
266 reset(); 266 reset();
267 Object.getNotifier(obj).notify({ 267 Object.getNotifier(obj).notify({
268 type: 'updated', 268 type: 'update',
269 }); 269 });
270 Object.observe(obj, observer.callback); 270 Object.observe(obj, observer.callback);
271 Object.getNotifier(obj).notify({ 271 Object.getNotifier(obj).notify({
272 type: 'updated', 272 type: 'update',
273 }); 273 });
274 records = undefined; 274 records = undefined;
275 Object.deliverChangeRecords(observer.callback); 275 Object.deliverChangeRecords(observer.callback);
276 observer.assertRecordCount(1); 276 observer.assertRecordCount(1);
277 277
278 // Get notifier prior to observing 278 // Get notifier prior to observing
279 reset(); 279 reset();
280 var obj = {}; 280 var obj = {};
281 Object.getNotifier(obj); 281 Object.getNotifier(obj);
282 Object.observe(obj, observer.callback); 282 Object.observe(obj, observer.callback);
283 obj.id = 1; 283 obj.id = 1;
284 Object.deliverChangeRecords(observer.callback); 284 Object.deliverChangeRecords(observer.callback);
285 observer.assertCallbackRecords([ 285 observer.assertCallbackRecords([
286 { object: obj, type: 'new', name: 'id' }, 286 { object: obj, type: 'add', name: 'id' },
287 ]); 287 ]);
288 288
289 // The empty-string property is observable 289 // The empty-string property is observable
290 reset(); 290 reset();
291 var obj = {}; 291 var obj = {};
292 Object.observe(obj, observer.callback); 292 Object.observe(obj, observer.callback);
293 obj[''] = ''; 293 obj[''] = '';
294 obj[''] = ' '; 294 obj[''] = ' ';
295 delete obj['']; 295 delete obj[''];
296 Object.deliverChangeRecords(observer.callback); 296 Object.deliverChangeRecords(observer.callback);
297 observer.assertCallbackRecords([ 297 observer.assertCallbackRecords([
298 { object: obj, type: 'new', name: '' }, 298 { object: obj, type: 'add', name: '' },
299 { object: obj, type: 'updated', name: '', oldValue: '' }, 299 { object: obj, type: 'update', name: '', oldValue: '' },
300 { object: obj, type: 'deleted', name: '', oldValue: ' ' }, 300 { object: obj, type: 'delete', name: '', oldValue: ' ' },
301 ]); 301 ]);
302
303 // Object.preventExtensions
304 reset();
305 var obj = { foo: 'bar'};
306 Object.observe(obj, observer.callback);
307 obj.baz = 'bat';
308 Object.preventExtensions(obj);
309
310 Object.deliverChangeRecords(observer.callback);
311 observer.assertCallbackRecords([
312 { object: obj, type: 'add', name: 'baz' },
313 { object: obj, type: 'preventExtensions' },
314 ]);
315
316 reset();
317 var obj = { foo: 'bar'};
318 Object.preventExtensions(obj);
319 Object.observe(obj, observer.callback);
320 Object.preventExtensions(obj);
321 Object.deliverChangeRecords(observer.callback);
322 observer.assertNotCalled();
323
324 // Object.freeze
325 reset();
326 var obj = { a: 'a' };
327 Object.defineProperty(obj, 'b', {
328 writable: false,
329 configurable: true,
330 value: 'b'
331 });
332 Object.defineProperty(obj, 'c', {
333 writable: true,
334 configurable: false,
335 value: 'c'
336 });
337 Object.defineProperty(obj, 'd', {
338 writable: false,
339 configurable: false,
340 value: 'd'
341 });
342 Object.observe(obj, observer.callback);
343 Object.freeze(obj);
344
345 Object.deliverChangeRecords(observer.callback);
346 observer.assertCallbackRecords([
347 { object: obj, type: 'reconfigure', name: 'a' },
348 { object: obj, type: 'reconfigure', name: 'b' },
349 { object: obj, type: 'reconfigure', name: 'c' },
350 { object: obj, type: 'preventExtensions' },
351 ]);
352
353 reset();
354 var obj = { foo: 'bar'};
355 Object.freeze(obj);
356 Object.observe(obj, observer.callback);
357 Object.freeze(obj);
358 Object.deliverChangeRecords(observer.callback);
359 observer.assertNotCalled();
360
361 // Object.seal
362 reset();
363 var obj = { a: 'a' };
364 Object.defineProperty(obj, 'b', {
365 writable: false,
366 configurable: true,
367 value: 'b'
368 });
369 Object.defineProperty(obj, 'c', {
370 writable: true,
371 configurable: false,
372 value: 'c'
373 });
374 Object.defineProperty(obj, 'd', {
375 writable: false,
376 configurable: false,
377 value: 'd'
378 });
379 Object.observe(obj, observer.callback);
380 Object.seal(obj);
381
382 Object.deliverChangeRecords(observer.callback);
383 observer.assertCallbackRecords([
384 { object: obj, type: 'reconfigure', name: 'a' },
385 { object: obj, type: 'reconfigure', name: 'b' },
386 { object: obj, type: 'preventExtensions' },
387 ]);
388
389 reset();
390 var obj = { foo: 'bar'};
391 Object.seal(obj);
392 Object.observe(obj, observer.callback);
393 Object.seal(obj);
394 Object.deliverChangeRecords(observer.callback);
395 observer.assertNotCalled();
302 396
303 // Observing a continuous stream of changes, while itermittantly unobserving. 397 // Observing a continuous stream of changes, while itermittantly unobserving.
304 reset(); 398 reset();
305 Object.observe(obj, observer.callback); 399 var obj = {};
306 Object.getNotifier(obj).notify({ 400 Object.observe(obj, observer.callback);
307 type: 'updated', 401 Object.getNotifier(obj).notify({
402 type: 'update',
308 val: 1 403 val: 1
309 }); 404 });
310 405
311 Object.unobserve(obj, observer.callback); 406 Object.unobserve(obj, observer.callback);
312 Object.getNotifier(obj).notify({ 407 Object.getNotifier(obj).notify({
313 type: 'updated', 408 type: 'update',
314 val: 2 409 val: 2
315 }); 410 });
316 411
317 Object.observe(obj, observer.callback); 412 Object.observe(obj, observer.callback);
318 Object.getNotifier(obj).notify({ 413 Object.getNotifier(obj).notify({
319 type: 'updated', 414 type: 'update',
320 val: 3 415 val: 3
321 }); 416 });
322 417
323 Object.unobserve(obj, observer.callback); 418 Object.unobserve(obj, observer.callback);
324 Object.getNotifier(obj).notify({ 419 Object.getNotifier(obj).notify({
325 type: 'updated', 420 type: 'update',
326 val: 4 421 val: 4
327 }); 422 });
328 423
329 Object.observe(obj, observer.callback); 424 Object.observe(obj, observer.callback);
330 Object.getNotifier(obj).notify({ 425 Object.getNotifier(obj).notify({
331 type: 'updated', 426 type: 'update',
332 val: 5 427 val: 5
333 }); 428 });
334 429
335 Object.unobserve(obj, observer.callback); 430 Object.unobserve(obj, observer.callback);
336 Object.deliverChangeRecords(observer.callback); 431 Object.deliverChangeRecords(observer.callback);
337 observer.assertCallbackRecords([ 432 observer.assertCallbackRecords([
338 { object: obj, type: 'updated', val: 1 }, 433 { object: obj, type: 'update', val: 1 },
339 { object: obj, type: 'updated', val: 3 }, 434 { object: obj, type: 'update', val: 3 },
340 { object: obj, type: 'updated', val: 5 } 435 { object: obj, type: 'update', val: 5 }
341 ]); 436 ]);
342 437
343 // Accept 438 // Accept
344 reset(); 439 reset();
345 Object.observe(obj, observer.callback, ['somethingElse']); 440 Object.observe(obj, observer.callback, ['somethingElse']);
346 Object.getNotifier(obj).notify({ 441 Object.getNotifier(obj).notify({
347 type: 'new' 442 type: 'add'
348 }); 443 });
349 Object.getNotifier(obj).notify({ 444 Object.getNotifier(obj).notify({
350 type: 'updated' 445 type: 'update'
351 }); 446 });
352 Object.getNotifier(obj).notify({ 447 Object.getNotifier(obj).notify({
353 type: 'deleted' 448 type: 'delete'
354 }); 449 });
355 Object.getNotifier(obj).notify({ 450 Object.getNotifier(obj).notify({
356 type: 'reconfigured' 451 type: 'reconfigure'
357 }); 452 });
358 Object.getNotifier(obj).notify({ 453 Object.getNotifier(obj).notify({
359 type: 'prototype' 454 type: 'setPrototype'
360 }); 455 });
361 Object.deliverChangeRecords(observer.callback); 456 Object.deliverChangeRecords(observer.callback);
362 observer.assertNotCalled(); 457 observer.assertNotCalled();
363 458
364 reset(); 459 reset();
365 Object.observe(obj, observer.callback, ['new', 'deleted', 'prototype']); 460 Object.observe(obj, observer.callback, ['add', 'delete', 'setPrototype']);
366 Object.getNotifier(obj).notify({ 461 Object.getNotifier(obj).notify({
367 type: 'new' 462 type: 'add'
368 }); 463 });
369 Object.getNotifier(obj).notify({ 464 Object.getNotifier(obj).notify({
370 type: 'updated' 465 type: 'update'
371 }); 466 });
372 Object.getNotifier(obj).notify({ 467 Object.getNotifier(obj).notify({
373 type: 'deleted' 468 type: 'delete'
374 }); 469 });
375 Object.getNotifier(obj).notify({ 470 Object.getNotifier(obj).notify({
376 type: 'deleted' 471 type: 'delete'
377 }); 472 });
378 Object.getNotifier(obj).notify({ 473 Object.getNotifier(obj).notify({
379 type: 'reconfigured' 474 type: 'reconfigure'
380 }); 475 });
381 Object.getNotifier(obj).notify({ 476 Object.getNotifier(obj).notify({
382 type: 'prototype' 477 type: 'setPrototype'
383 }); 478 });
384 Object.deliverChangeRecords(observer.callback); 479 Object.deliverChangeRecords(observer.callback);
385 observer.assertCallbackRecords([ 480 observer.assertCallbackRecords([
386 { object: obj, type: 'new' }, 481 { object: obj, type: 'add' },
387 { object: obj, type: 'deleted' }, 482 { object: obj, type: 'delete' },
388 { object: obj, type: 'deleted' }, 483 { object: obj, type: 'delete' },
389 { object: obj, type: 'prototype' } 484 { object: obj, type: 'setPrototype' }
390 ]); 485 ]);
391 486
392 reset(); 487 reset();
393 Object.observe(obj, observer.callback, ['updated', 'foo']); 488 Object.observe(obj, observer.callback, ['update', 'foo']);
394 Object.getNotifier(obj).notify({ 489 Object.getNotifier(obj).notify({
395 type: 'new' 490 type: 'add'
396 }); 491 });
397 Object.getNotifier(obj).notify({ 492 Object.getNotifier(obj).notify({
398 type: 'updated' 493 type: 'update'
399 }); 494 });
400 Object.getNotifier(obj).notify({ 495 Object.getNotifier(obj).notify({
401 type: 'deleted' 496 type: 'delete'
402 }); 497 });
403 Object.getNotifier(obj).notify({ 498 Object.getNotifier(obj).notify({
404 type: 'foo' 499 type: 'foo'
405 }); 500 });
406 Object.getNotifier(obj).notify({ 501 Object.getNotifier(obj).notify({
407 type: 'bar' 502 type: 'bar'
408 }); 503 });
409 Object.getNotifier(obj).notify({ 504 Object.getNotifier(obj).notify({
410 type: 'foo' 505 type: 'foo'
411 }); 506 });
412 Object.deliverChangeRecords(observer.callback); 507 Object.deliverChangeRecords(observer.callback);
413 observer.assertCallbackRecords([ 508 observer.assertCallbackRecords([
414 { object: obj, type: 'updated' }, 509 { object: obj, type: 'update' },
415 { object: obj, type: 'foo' }, 510 { object: obj, type: 'foo' },
416 { object: obj, type: 'foo' } 511 { object: obj, type: 'foo' }
417 ]); 512 ]);
418 513
419 reset(); 514 reset();
420 function Thingy(a, b, c) { 515 function Thingy(a, b, c) {
421 this.a = a; 516 this.a = a;
422 this.b = b; 517 this.b = b;
423 } 518 }
424 519
425 Thingy.MULTIPLY = 'multiply'; 520 Thingy.MULTIPLY = 'multiply';
426 Thingy.INCREMENT = 'increment'; 521 Thingy.INCREMENT = 'increment';
427 Thingy.INCREMENT_AND_MULTIPLY = 'incrementAndMultiply'; 522 Thingy.INCREMENT_AND_MULTIPLY = 'incrementAndMultiply';
428 523
429 Thingy.prototype = { 524 Thingy.prototype = {
430 increment: function(amount) { 525 increment: function(amount) {
431 var notifier = Object.getNotifier(this); 526 var notifier = Object.getNotifier(this);
432 527
433 var self = this; 528 var self = this;
434 notifier.performChange(Thingy.INCREMENT, function() { 529 notifier.performChange(Thingy.INCREMENT, function() {
435 self.a += amount; 530 self.a += amount;
436 self.b += amount; 531 self.b += amount;
437 });
438 532
439 notifier.notify({ 533 return {
440 object: this, 534 incremented: amount
441 type: Thingy.INCREMENT, 535 }; // implicit notify
442 incremented: amount
443 }); 536 });
444 }, 537 },
445 538
446 multiply: function(amount) { 539 multiply: function(amount) {
447 var notifier = Object.getNotifier(this); 540 var notifier = Object.getNotifier(this);
448 541
449 var self = this; 542 var self = this;
450 notifier.performChange(Thingy.MULTIPLY, function() { 543 notifier.performChange(Thingy.MULTIPLY, function() {
451 self.a *= amount; 544 self.a *= amount;
452 self.b *= amount; 545 self.b *= amount;
453 });
454 546
455 notifier.notify({ 547 return {
456 object: this, 548 multiplied: amount
457 type: Thingy.MULTIPLY, 549 }; // implicit notify
458 multiplied: amount
459 }); 550 });
460 }, 551 },
461 552
462 incrementAndMultiply: function(incAmount, multAmount) { 553 incrementAndMultiply: function(incAmount, multAmount) {
463 var notifier = Object.getNotifier(this); 554 var notifier = Object.getNotifier(this);
464 555
465 var self = this; 556 var self = this;
466 notifier.performChange(Thingy.INCREMENT_AND_MULTIPLY, function() { 557 notifier.performChange(Thingy.INCREMENT_AND_MULTIPLY, function() {
467 self.increment(incAmount); 558 self.increment(incAmount);
468 self.multiply(multAmount); 559 self.multiply(multAmount);
469 });
470 560
471 notifier.notify({ 561 return {
472 object: this, 562 incremented: incAmount,
473 type: Thingy.INCREMENT_AND_MULTIPLY, 563 multiplied: multAmount
474 incremented: incAmount, 564 }; // implicit notify
475 multiplied: multAmount
476 }); 565 });
477 } 566 }
478 } 567 }
479 568
480 Thingy.observe = function(thingy, callback) { 569 Thingy.observe = function(thingy, callback) {
481 Object.observe(thingy, callback, [Thingy.INCREMENT, 570 Object.observe(thingy, callback, [Thingy.INCREMENT,
482 Thingy.MULTIPLY, 571 Thingy.MULTIPLY,
483 Thingy.INCREMENT_AND_MULTIPLY, 572 Thingy.INCREMENT_AND_MULTIPLY,
484 'updated']); 573 'update']);
485 } 574 }
486 575
487 Thingy.unobserve = function(thingy, callback) { 576 Thingy.unobserve = function(thingy, callback) {
488 Object.unobserve(thingy); 577 Object.unobserve(thingy);
489 } 578 }
490 579
491 var thingy = new Thingy(2, 4); 580 var thingy = new Thingy(2, 4);
492 581
493 Object.observe(thingy, observer.callback); 582 Object.observe(thingy, observer.callback);
494 Thingy.observe(thingy, observer2.callback); 583 Thingy.observe(thingy, observer2.callback);
495 thingy.increment(3); // { a: 5, b: 7 } 584 thingy.increment(3); // { a: 5, b: 7 }
496 thingy.b++; // { a: 5, b: 8 } 585 thingy.b++; // { a: 5, b: 8 }
497 thingy.multiply(2); // { a: 10, b: 16 } 586 thingy.multiply(2); // { a: 10, b: 16 }
498 thingy.a++; // { a: 11, b: 16 } 587 thingy.a++; // { a: 11, b: 16 }
499 thingy.incrementAndMultiply(2, 2); // { a: 26, b: 36 } 588 thingy.incrementAndMultiply(2, 2); // { a: 26, b: 36 }
500 589
501 Object.deliverChangeRecords(observer.callback); 590 Object.deliverChangeRecords(observer.callback);
502 Object.deliverChangeRecords(observer2.callback); 591 Object.deliverChangeRecords(observer2.callback);
503 observer.assertCallbackRecords([ 592 observer.assertCallbackRecords([
504 { object: thingy, type: 'updated', name: 'a', oldValue: 2 }, 593 { object: thingy, type: 'update', name: 'a', oldValue: 2 },
505 { object: thingy, type: 'updated', name: 'b', oldValue: 4 }, 594 { object: thingy, type: 'update', name: 'b', oldValue: 4 },
506 { object: thingy, type: 'updated', name: 'b', oldValue: 7 }, 595 { object: thingy, type: 'update', name: 'b', oldValue: 7 },
507 { object: thingy, type: 'updated', name: 'a', oldValue: 5 }, 596 { object: thingy, type: 'update', name: 'a', oldValue: 5 },
508 { object: thingy, type: 'updated', name: 'b', oldValue: 8 }, 597 { object: thingy, type: 'update', name: 'b', oldValue: 8 },
509 { object: thingy, type: 'updated', name: 'a', oldValue: 10 }, 598 { object: thingy, type: 'update', name: 'a', oldValue: 10 },
510 { object: thingy, type: 'updated', name: 'a', oldValue: 11 }, 599 { object: thingy, type: 'update', name: 'a', oldValue: 11 },
511 { object: thingy, type: 'updated', name: 'b', oldValue: 16 }, 600 { object: thingy, type: 'update', name: 'b', oldValue: 16 },
512 { object: thingy, type: 'updated', name: 'a', oldValue: 13 }, 601 { object: thingy, type: 'update', name: 'a', oldValue: 13 },
513 { object: thingy, type: 'updated', name: 'b', oldValue: 18 }, 602 { object: thingy, type: 'update', name: 'b', oldValue: 18 },
514 ]); 603 ]);
515 observer2.assertCallbackRecords([ 604 observer2.assertCallbackRecords([
516 { object: thingy, type: Thingy.INCREMENT, incremented: 3 }, 605 { object: thingy, type: Thingy.INCREMENT, incremented: 3 },
517 { object: thingy, type: 'updated', name: 'b', oldValue: 7 }, 606 { object: thingy, type: 'update', name: 'b', oldValue: 7 },
518 { object: thingy, type: Thingy.MULTIPLY, multiplied: 2 }, 607 { object: thingy, type: Thingy.MULTIPLY, multiplied: 2 },
519 { object: thingy, type: 'updated', name: 'a', oldValue: 10 }, 608 { object: thingy, type: 'update', name: 'a', oldValue: 10 },
520 { 609 {
521 object: thingy, 610 object: thingy,
522 type: Thingy.INCREMENT_AND_MULTIPLY, 611 type: Thingy.INCREMENT_AND_MULTIPLY,
523 incremented: 2, 612 incremented: 2,
524 multiplied: 2 613 multiplied: 2
525 } 614 }
526 ]); 615 ]);
527 616
528 617
529 reset(); 618 reset();
530 function RecursiveThingy() {} 619 function RecursiveThingy() {}
531 620
532 RecursiveThingy.MULTIPLY_FIRST_N = 'multiplyFirstN'; 621 RecursiveThingy.MULTIPLY_FIRST_N = 'multiplyFirstN';
533 622
534 RecursiveThingy.prototype = { 623 RecursiveThingy.prototype = {
535 __proto__: Array.prototype, 624 __proto__: Array.prototype,
536 625
537 multiplyFirstN: function(amount, n) { 626 multiplyFirstN: function(amount, n) {
538 if (!n) 627 if (!n)
539 return; 628 return;
540 var notifier = Object.getNotifier(this); 629 var notifier = Object.getNotifier(this);
541 var self = this; 630 var self = this;
542 notifier.performChange(RecursiveThingy.MULTIPLY_FIRST_N, function() { 631 notifier.performChange(RecursiveThingy.MULTIPLY_FIRST_N, function() {
543 self[n-1] = self[n-1]*amount; 632 self[n-1] = self[n-1]*amount;
544 self.multiplyFirstN(amount, n-1); 633 self.multiplyFirstN(amount, n-1);
545 }); 634 });
546 635
547 notifier.notify({ 636 notifier.notify({
548 object: this,
549 type: RecursiveThingy.MULTIPLY_FIRST_N, 637 type: RecursiveThingy.MULTIPLY_FIRST_N,
550 multiplied: amount, 638 multiplied: amount,
551 n: n 639 n: n
552 }); 640 });
553 }, 641 },
554 } 642 }
555 643
556 RecursiveThingy.observe = function(thingy, callback) { 644 RecursiveThingy.observe = function(thingy, callback) {
557 Object.observe(thingy, callback, [RecursiveThingy.MULTIPLY_FIRST_N]); 645 Object.observe(thingy, callback, [RecursiveThingy.MULTIPLY_FIRST_N]);
558 } 646 }
559 647
560 RecursiveThingy.unobserve = function(thingy, callback) { 648 RecursiveThingy.unobserve = function(thingy, callback) {
561 Object.unobserve(thingy); 649 Object.unobserve(thingy);
562 } 650 }
563 651
564 var thingy = new RecursiveThingy; 652 var thingy = new RecursiveThingy;
565 thingy.push(1, 2, 3, 4); 653 thingy.push(1, 2, 3, 4);
566 654
567 Object.observe(thingy, observer.callback); 655 Object.observe(thingy, observer.callback);
568 RecursiveThingy.observe(thingy, observer2.callback); 656 RecursiveThingy.observe(thingy, observer2.callback);
569 thingy.multiplyFirstN(2, 3); // [2, 4, 6, 4] 657 thingy.multiplyFirstN(2, 3); // [2, 4, 6, 4]
570 658
571 Object.deliverChangeRecords(observer.callback); 659 Object.deliverChangeRecords(observer.callback);
572 Object.deliverChangeRecords(observer2.callback); 660 Object.deliverChangeRecords(observer2.callback);
573 observer.assertCallbackRecords([ 661 observer.assertCallbackRecords([
574 { object: thingy, type: 'updated', name: '2', oldValue: 3 }, 662 { object: thingy, type: 'update', name: '2', oldValue: 3 },
575 { object: thingy, type: 'updated', name: '1', oldValue: 2 }, 663 { object: thingy, type: 'update', name: '1', oldValue: 2 },
576 { object: thingy, type: 'updated', name: '0', oldValue: 1 } 664 { object: thingy, type: 'update', name: '0', oldValue: 1 }
577 ]); 665 ]);
578 observer2.assertCallbackRecords([ 666 observer2.assertCallbackRecords([
579 { object: thingy, type: RecursiveThingy.MULTIPLY_FIRST_N, multiplied: 2, n: 3 } 667 { object: thingy, type: RecursiveThingy.MULTIPLY_FIRST_N, multiplied: 2, n: 3 }
580 ]); 668 ]);
581 669
582 reset(); 670 reset();
583 function DeckSuit() { 671 function DeckSuit() {
584 this.push('1', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'A', 'Q', 'K'); 672 this.push('1', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'A', 'Q', 'K');
585 } 673 }
586 674
(...skipping 12 matching lines...) Expand all
599 Array.prototype.push.apply(self, cut); 687 Array.prototype.push.apply(self, cut);
600 self.reverse(); 688 self.reverse();
601 self.sort(function() { return Math.random()* 2 - 1; }); 689 self.sort(function() { return Math.random()* 2 - 1; });
602 var cut = self.splice(0, 6); 690 var cut = self.splice(0, 6);
603 Array.prototype.push.apply(self, cut); 691 Array.prototype.push.apply(self, cut);
604 self.reverse(); 692 self.reverse();
605 self.sort(function() { return Math.random()* 2 - 1; }); 693 self.sort(function() { return Math.random()* 2 - 1; });
606 }); 694 });
607 695
608 notifier.notify({ 696 notifier.notify({
609 object: this,
610 type: DeckSuit.SHUFFLE 697 type: DeckSuit.SHUFFLE
611 }); 698 });
612 }, 699 },
613 } 700 }
614 701
615 DeckSuit.observe = function(thingy, callback) { 702 DeckSuit.observe = function(thingy, callback) {
616 Object.observe(thingy, callback, [DeckSuit.SHUFFLE]); 703 Object.observe(thingy, callback, [DeckSuit.SHUFFLE]);
617 } 704 }
618 705
619 DeckSuit.unobserve = function(thingy, callback) { 706 DeckSuit.unobserve = function(thingy, callback) {
(...skipping 11 matching lines...) Expand all
631 ]); 718 ]);
632 719
633 // Observing multiple objects; records appear in order. 720 // Observing multiple objects; records appear in order.
634 reset(); 721 reset();
635 var obj2 = {}; 722 var obj2 = {};
636 var obj3 = {} 723 var obj3 = {}
637 Object.observe(obj, observer.callback); 724 Object.observe(obj, observer.callback);
638 Object.observe(obj3, observer.callback); 725 Object.observe(obj3, observer.callback);
639 Object.observe(obj2, observer.callback); 726 Object.observe(obj2, observer.callback);
640 Object.getNotifier(obj).notify({ 727 Object.getNotifier(obj).notify({
641 type: 'new', 728 type: 'add',
642 }); 729 });
643 Object.getNotifier(obj2).notify({ 730 Object.getNotifier(obj2).notify({
644 type: 'updated', 731 type: 'update',
645 }); 732 });
646 Object.getNotifier(obj3).notify({ 733 Object.getNotifier(obj3).notify({
647 type: 'deleted', 734 type: 'delete',
648 }); 735 });
649 Object.observe(obj3, observer.callback); 736 Object.observe(obj3, observer.callback);
650 Object.deliverChangeRecords(observer.callback); 737 Object.deliverChangeRecords(observer.callback);
651 observer.assertCallbackRecords([ 738 observer.assertCallbackRecords([
652 { object: obj, type: 'new' }, 739 { object: obj, type: 'add' },
653 { object: obj2, type: 'updated' }, 740 { object: obj2, type: 'update' },
654 { object: obj3, type: 'deleted' } 741 { object: obj3, type: 'delete' }
655 ]); 742 ]);
656 743
657 744
658 // Recursive observation. 745 // Recursive observation.
659 var obj = {a: 1}; 746 var obj = {a: 1};
660 var callbackCount = 0; 747 var callbackCount = 0;
661 function recursiveObserver(r) { 748 function recursiveObserver(r) {
662 assertEquals(1, r.length); 749 assertEquals(1, r.length);
663 ++callbackCount; 750 ++callbackCount;
664 if (r[0].oldValue < 100) ++obj[r[0].name]; 751 if (r[0].oldValue < 100) ++obj[r[0].name];
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
711 Object.defineProperty(obj, "a", {get: function() {}, configurable: true}); 798 Object.defineProperty(obj, "a", {get: function() {}, configurable: true});
712 Object.defineProperty(obj, "a", {value: 9, writable: true}); 799 Object.defineProperty(obj, "a", {value: 9, writable: true});
713 obj.a = 10; 800 obj.a = 10;
714 ++obj.a; 801 ++obj.a;
715 obj.a++; 802 obj.a++;
716 obj.a *= 3; 803 obj.a *= 3;
717 delete obj.a; 804 delete obj.a;
718 Object.defineProperty(obj, "a", {value: 11, configurable: true}); 805 Object.defineProperty(obj, "a", {value: 11, configurable: true});
719 Object.deliverChangeRecords(observer.callback); 806 Object.deliverChangeRecords(observer.callback);
720 observer.assertCallbackRecords([ 807 observer.assertCallbackRecords([
721 { object: obj, name: "a", type: "updated", oldValue: 1 }, 808 { object: obj, name: "a", type: "update", oldValue: 1 },
722 { object: obj, name: "a", type: "updated", oldValue: 2 }, 809 { object: obj, name: "a", type: "update", oldValue: 2 },
723 { object: obj, name: "a", type: "deleted", oldValue: 3 }, 810 { object: obj, name: "a", type: "delete", oldValue: 3 },
724 { object: obj, name: "a", type: "new" }, 811 { object: obj, name: "a", type: "add" },
725 { object: obj, name: "a", type: "updated", oldValue: 4 }, 812 { object: obj, name: "a", type: "update", oldValue: 4 },
726 { object: obj, name: "a", type: "updated", oldValue: 5 }, 813 { object: obj, name: "a", type: "update", oldValue: 5 },
727 { object: obj, name: "a", type: "reconfigured" }, 814 { object: obj, name: "a", type: "reconfigure" },
728 { object: obj, name: "a", type: "updated", oldValue: 6 }, 815 { object: obj, name: "a", type: "update", oldValue: 6 },
729 { object: obj, name: "a", type: "reconfigured", oldValue: 8 }, 816 { object: obj, name: "a", type: "reconfigure", oldValue: 8 },
730 { object: obj, name: "a", type: "reconfigured", oldValue: 7 }, 817 { object: obj, name: "a", type: "reconfigure", oldValue: 7 },
731 { object: obj, name: "a", type: "reconfigured" }, 818 { object: obj, name: "a", type: "reconfigure" },
732 { object: obj, name: "a", type: "reconfigured" }, 819 { object: obj, name: "a", type: "reconfigure" },
733 { object: obj, name: "a", type: "reconfigured" }, 820 { object: obj, name: "a", type: "reconfigure" },
734 { object: obj, name: "a", type: "deleted" }, 821 { object: obj, name: "a", type: "delete" },
735 { object: obj, name: "a", type: "new" }, 822 { object: obj, name: "a", type: "add" },
736 { object: obj, name: "a", type: "reconfigured" }, 823 { object: obj, name: "a", type: "reconfigure" },
737 { object: obj, name: "a", type: "updated", oldValue: 9 }, 824 { object: obj, name: "a", type: "update", oldValue: 9 },
738 { object: obj, name: "a", type: "updated", oldValue: 10 }, 825 { object: obj, name: "a", type: "update", oldValue: 10 },
739 { object: obj, name: "a", type: "updated", oldValue: 11 }, 826 { object: obj, name: "a", type: "update", oldValue: 11 },
740 { object: obj, name: "a", type: "updated", oldValue: 12 }, 827 { object: obj, name: "a", type: "update", oldValue: 12 },
741 { object: obj, name: "a", type: "deleted", oldValue: 36 }, 828 { object: obj, name: "a", type: "delete", oldValue: 36 },
742 { object: obj, name: "a", type: "new" }, 829 { object: obj, name: "a", type: "add" },
743 ]); 830 ]);
744 831
745 832
746 // Observing indexed properties. 833 // Observing indexed properties.
747 reset(); 834 reset();
748 var obj = {'1': 1} 835 var obj = {'1': 1}
749 Object.observe(obj, observer.callback); 836 Object.observe(obj, observer.callback);
750 obj[1] = 2; 837 obj[1] = 2;
751 obj[1] = 3; 838 obj[1] = 3;
752 delete obj[1]; 839 delete obj[1];
(...skipping 16 matching lines...) Expand all
769 Object.defineProperty(obj, "1", {get: function() {}, configurable: true}); 856 Object.defineProperty(obj, "1", {get: function() {}, configurable: true});
770 Object.defineProperty(obj, "1", {value: 9, writable: true}); 857 Object.defineProperty(obj, "1", {value: 9, writable: true});
771 obj[1] = 10; 858 obj[1] = 10;
772 ++obj[1]; 859 ++obj[1];
773 obj[1]++; 860 obj[1]++;
774 obj[1] *= 3; 861 obj[1] *= 3;
775 delete obj[1]; 862 delete obj[1];
776 Object.defineProperty(obj, "1", {value: 11, configurable: true}); 863 Object.defineProperty(obj, "1", {value: 11, configurable: true});
777 Object.deliverChangeRecords(observer.callback); 864 Object.deliverChangeRecords(observer.callback);
778 observer.assertCallbackRecords([ 865 observer.assertCallbackRecords([
779 { object: obj, name: "1", type: "updated", oldValue: 1 }, 866 { object: obj, name: "1", type: "update", oldValue: 1 },
780 { object: obj, name: "1", type: "updated", oldValue: 2 }, 867 { object: obj, name: "1", type: "update", oldValue: 2 },
781 { object: obj, name: "1", type: "deleted", oldValue: 3 }, 868 { object: obj, name: "1", type: "delete", oldValue: 3 },
782 { object: obj, name: "1", type: "new" }, 869 { object: obj, name: "1", type: "add" },
783 { object: obj, name: "1", type: "updated", oldValue: 4 }, 870 { object: obj, name: "1", type: "update", oldValue: 4 },
784 { object: obj, name: "1", type: "updated", oldValue: 5 }, 871 { object: obj, name: "1", type: "update", oldValue: 5 },
785 { object: obj, name: "1", type: "reconfigured" }, 872 { object: obj, name: "1", type: "reconfigure" },
786 { object: obj, name: "1", type: "updated", oldValue: 6 }, 873 { object: obj, name: "1", type: "update", oldValue: 6 },
787 { object: obj, name: "1", type: "reconfigured", oldValue: 8 }, 874 { object: obj, name: "1", type: "reconfigure", oldValue: 8 },
788 { object: obj, name: "1", type: "reconfigured", oldValue: 7 }, 875 { object: obj, name: "1", type: "reconfigure", oldValue: 7 },
789 { object: obj, name: "1", type: "reconfigured" }, 876 { object: obj, name: "1", type: "reconfigure" },
790 { object: obj, name: "1", type: "reconfigured" }, 877 { object: obj, name: "1", type: "reconfigure" },
791 { object: obj, name: "1", type: "reconfigured" }, 878 { object: obj, name: "1", type: "reconfigure" },
792 { object: obj, name: "1", type: "deleted" }, 879 { object: obj, name: "1", type: "delete" },
793 { object: obj, name: "1", type: "new" }, 880 { object: obj, name: "1", type: "add" },
794 { object: obj, name: "1", type: "reconfigured" }, 881 { object: obj, name: "1", type: "reconfigure" },
795 { object: obj, name: "1", type: "updated", oldValue: 9 }, 882 { object: obj, name: "1", type: "update", oldValue: 9 },
796 { object: obj, name: "1", type: "updated", oldValue: 10 }, 883 { object: obj, name: "1", type: "update", oldValue: 10 },
797 { object: obj, name: "1", type: "updated", oldValue: 11 }, 884 { object: obj, name: "1", type: "update", oldValue: 11 },
798 { object: obj, name: "1", type: "updated", oldValue: 12 }, 885 { object: obj, name: "1", type: "update", oldValue: 12 },
799 { object: obj, name: "1", type: "deleted", oldValue: 36 }, 886 { object: obj, name: "1", type: "delete", oldValue: 36 },
800 { object: obj, name: "1", type: "new" }, 887 { object: obj, name: "1", type: "add" },
801 ]); 888 ]);
802 889
803 890
804 // Observing symbol properties (not). 891 // Observing symbol properties (not).
805 print("*****") 892 print("*****")
806 reset(); 893 reset();
807 var obj = {} 894 var obj = {}
808 var symbol = Symbol("secret"); 895 var symbol = Symbol("secret");
809 Object.observe(obj, observer.callback); 896 Object.observe(obj, observer.callback);
810 obj[symbol] = 3; 897 obj[symbol] = 3;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
858 Object.defineProperty(obj, prop, {get: function() {}, configurable: true}); 945 Object.defineProperty(obj, prop, {get: function() {}, configurable: true});
859 Object.defineProperty(obj, prop, {value: 9, writable: true}); 946 Object.defineProperty(obj, prop, {value: 9, writable: true});
860 obj[prop] = 10; 947 obj[prop] = 10;
861 ++obj[prop]; 948 ++obj[prop];
862 obj[prop]++; 949 obj[prop]++;
863 obj[prop] *= 3; 950 obj[prop] *= 3;
864 delete obj[prop]; 951 delete obj[prop];
865 Object.defineProperty(obj, prop, {value: 11, configurable: true}); 952 Object.defineProperty(obj, prop, {value: 11, configurable: true});
866 Object.deliverChangeRecords(observer.callback); 953 Object.deliverChangeRecords(observer.callback);
867 observer.assertCallbackRecords([ 954 observer.assertCallbackRecords([
868 { object: obj, name: prop, type: "updated", oldValue: 1 }, 955 { object: obj, name: prop, type: "update", oldValue: 1 },
869 { object: obj, name: prop, type: "updated", oldValue: 2 }, 956 { object: obj, name: prop, type: "update", oldValue: 2 },
870 { object: obj, name: prop, type: "deleted", oldValue: 3 }, 957 { object: obj, name: prop, type: "delete", oldValue: 3 },
871 { object: obj, name: prop, type: "new" }, 958 { object: obj, name: prop, type: "add" },
872 { object: obj, name: prop, type: "updated", oldValue: 4 }, 959 { object: obj, name: prop, type: "update", oldValue: 4 },
873 { object: obj, name: prop, type: "updated", oldValue: 5 }, 960 { object: obj, name: prop, type: "update", oldValue: 5 },
874 { object: obj, name: prop, type: "reconfigured" }, 961 { object: obj, name: prop, type: "reconfigure" },
875 { object: obj, name: prop, type: "updated", oldValue: 6 }, 962 { object: obj, name: prop, type: "update", oldValue: 6 },
876 { object: obj, name: prop, type: "reconfigured", oldValue: 8 }, 963 { object: obj, name: prop, type: "reconfigure", oldValue: 8 },
877 { object: obj, name: prop, type: "reconfigured", oldValue: 7 }, 964 { object: obj, name: prop, type: "reconfigure", oldValue: 7 },
878 { object: obj, name: prop, type: "reconfigured" }, 965 { object: obj, name: prop, type: "reconfigure" },
879 { object: obj, name: prop, type: "reconfigured" }, 966 { object: obj, name: prop, type: "reconfigure" },
880 { object: obj, name: prop, type: "reconfigured" }, 967 { object: obj, name: prop, type: "reconfigure" },
881 { object: obj, name: prop, type: "reconfigured" }, 968 { object: obj, name: prop, type: "reconfigure" },
882 { object: obj, name: prop, type: "reconfigured" }, 969 { object: obj, name: prop, type: "reconfigure" },
883 { object: obj, name: prop, type: "deleted" }, 970 { object: obj, name: prop, type: "delete" },
884 { object: obj, name: prop, type: "new" }, 971 { object: obj, name: prop, type: "add" },
885 { object: obj, name: prop, type: "deleted" }, 972 { object: obj, name: prop, type: "delete" },
886 { object: obj, name: prop, type: "new" }, 973 { object: obj, name: prop, type: "add" },
887 { object: obj, name: prop, type: "reconfigured" }, 974 { object: obj, name: prop, type: "reconfigure" },
888 { object: obj, name: prop, type: "updated", oldValue: 9 }, 975 { object: obj, name: prop, type: "update", oldValue: 9 },
889 { object: obj, name: prop, type: "updated", oldValue: 10 }, 976 { object: obj, name: prop, type: "update", oldValue: 10 },
890 { object: obj, name: prop, type: "updated", oldValue: 11 }, 977 { object: obj, name: prop, type: "update", oldValue: 11 },
891 { object: obj, name: prop, type: "updated", oldValue: 12 }, 978 { object: obj, name: prop, type: "update", oldValue: 12 },
892 { object: obj, name: prop, type: "deleted", oldValue: 36 }, 979 { object: obj, name: prop, type: "delete", oldValue: 36 },
893 { object: obj, name: prop, type: "new" }, 980 { object: obj, name: prop, type: "add" },
894 ]); 981 ]);
895 Object.unobserve(obj, observer.callback); 982 Object.unobserve(obj, observer.callback);
896 delete obj[prop]; 983 delete obj[prop];
897 } 984 }
898 985
899 function TestObserveNonConfigurable(obj, prop, desc) { 986 function TestObserveNonConfigurable(obj, prop, desc) {
900 reset(); 987 reset();
901 Object.observe(obj, observer.callback); 988 Object.observe(obj, observer.callback);
902 Object.unobserve(obj, observer.callback); 989 Object.unobserve(obj, observer.callback);
903 obj[prop] = 1; 990 obj[prop] = 1;
904 Object.observe(obj, observer.callback); 991 Object.observe(obj, observer.callback);
905 obj[prop] = 4; 992 obj[prop] = 4;
906 obj[prop] = 4; // ignored 993 obj[prop] = 4; // ignored
907 obj[prop] = 5; 994 obj[prop] = 5;
908 Object.defineProperty(obj, prop, {value: 6}); 995 Object.defineProperty(obj, prop, {value: 6});
909 Object.defineProperty(obj, prop, {value: 6}); // ignored 996 Object.defineProperty(obj, prop, {value: 6}); // ignored
910 Object.defineProperty(obj, prop, {value: 7}); 997 Object.defineProperty(obj, prop, {value: 7});
911 Object.defineProperty(obj, prop, {enumerable: desc.enumerable}); // ignored 998 Object.defineProperty(obj, prop, {enumerable: desc.enumerable}); // ignored
912 Object.defineProperty(obj, prop, {writable: false}); 999 Object.defineProperty(obj, prop, {writable: false});
913 obj[prop] = 7; // ignored 1000 obj[prop] = 7; // ignored
914 Object.deliverChangeRecords(observer.callback); 1001 Object.deliverChangeRecords(observer.callback);
915 observer.assertCallbackRecords([ 1002 observer.assertCallbackRecords([
916 { object: obj, name: prop, type: "updated", oldValue: 1 }, 1003 { object: obj, name: prop, type: "update", oldValue: 1 },
917 { object: obj, name: prop, type: "updated", oldValue: 4 }, 1004 { object: obj, name: prop, type: "update", oldValue: 4 },
918 { object: obj, name: prop, type: "updated", oldValue: 5 }, 1005 { object: obj, name: prop, type: "update", oldValue: 5 },
919 { object: obj, name: prop, type: "updated", oldValue: 6 }, 1006 { object: obj, name: prop, type: "update", oldValue: 6 },
920 { object: obj, name: prop, type: "reconfigured" }, 1007 { object: obj, name: prop, type: "reconfigure" },
921 ]); 1008 ]);
922 Object.unobserve(obj, observer.callback); 1009 Object.unobserve(obj, observer.callback);
923 } 1010 }
924 1011
925 function createProxy(create, x) { 1012 function createProxy(create, x) {
926 var handler = { 1013 var handler = {
927 getPropertyDescriptor: function(k) { 1014 getPropertyDescriptor: function(k) {
928 for (var o = this.target; o; o = Object.getPrototypeOf(o)) { 1015 for (var o = this.target; o; o = Object.getPrototypeOf(o)) {
929 var desc = Object.getOwnPropertyDescriptor(o, k); 1016 var desc = Object.getOwnPropertyDescriptor(o, k);
930 if (desc) return desc; 1017 if (desc) return desc;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
970 (function(){ return arguments })(), 1057 (function(){ return arguments })(),
971 (function(){ "use strict"; return arguments })(), 1058 (function(){ "use strict"; return arguments })(),
972 Object(1), Object(true), Object("bla"), 1059 Object(1), Object(true), Object("bla"),
973 new Date(), 1060 new Date(),
974 Object, Function, Date, RegExp, 1061 Object, Function, Date, RegExp,
975 new Set, new Map, new WeakMap, 1062 new Set, new Map, new WeakMap,
976 new ArrayBuffer(10), new Int32Array(5), 1063 new ArrayBuffer(10), new Int32Array(5),
977 createProxy(Proxy.create, null), 1064 createProxy(Proxy.create, null),
978 createProxy(Proxy.createFunction, function(){}), 1065 createProxy(Proxy.createFunction, function(){}),
979 ]; 1066 ];
980 var properties = ["a", "1", 1, "length", "prototype", "name", "caller"]; 1067 var properties = ["a", "1", 1, "length", "setPrototype", "name", "caller"];
981 1068
982 // Cases that yield non-standard results. 1069 // Cases that yield non-standard results.
983 function blacklisted(obj, prop) { 1070 function blacklisted(obj, prop) {
984 return (obj instanceof Int32Array && prop == 1) || 1071 return (obj instanceof Int32Array && prop == 1) ||
985 (obj instanceof Int32Array && prop === "length") || 1072 (obj instanceof Int32Array && prop === "length") ||
986 (obj instanceof ArrayBuffer && prop == 1) 1073 (obj instanceof ArrayBuffer && prop == 1)
987 } 1074 }
988 1075
989 for (var i in objects) for (var j in properties) { 1076 for (var i in objects) for (var j in properties) {
990 var obj = objects[i]; 1077 var obj = objects[i];
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1024 Object.defineProperty(arr2, 'length', {value: 1, writable: false}); 1111 Object.defineProperty(arr2, 'length', {value: 1, writable: false});
1025 arr3.length = 0; 1112 arr3.length = 0;
1026 ++arr3.length; 1113 ++arr3.length;
1027 arr3.length++; 1114 arr3.length++;
1028 arr3.length /= 2; 1115 arr3.length /= 2;
1029 Object.defineProperty(arr3, 'length', {value: 5}); 1116 Object.defineProperty(arr3, 'length', {value: 5});
1030 arr3[4] = 5; 1117 arr3[4] = 5;
1031 Object.defineProperty(arr3, 'length', {value: 1, writable: false}); 1118 Object.defineProperty(arr3, 'length', {value: 1, writable: false});
1032 Object.deliverChangeRecords(observer.callback); 1119 Object.deliverChangeRecords(observer.callback);
1033 observer.assertCallbackRecords([ 1120 observer.assertCallbackRecords([
1034 { object: arr, name: '3', type: 'deleted', oldValue: 'd' }, 1121 { object: arr, name: '3', type: 'delete', oldValue: 'd' },
1035 { object: arr, name: '2', type: 'deleted' }, 1122 { object: arr, name: '2', type: 'delete' },
1036 { object: arr, name: 'length', type: 'updated', oldValue: 4 }, 1123 { object: arr, name: 'length', type: 'update', oldValue: 4 },
1037 { object: arr, name: '1', type: 'deleted', oldValue: 'b' }, 1124 { object: arr, name: '1', type: 'delete', oldValue: 'b' },
1038 { object: arr, name: 'length', type: 'updated', oldValue: 2 }, 1125 { object: arr, name: 'length', type: 'update', oldValue: 2 },
1039 { object: arr, name: 'length', type: 'updated', oldValue: 1 }, 1126 { object: arr, name: 'length', type: 'update', oldValue: 1 },
1040 { object: arr, name: 'length', type: 'reconfigured' }, 1127 { object: arr, name: 'length', type: 'reconfigure' },
1041 { object: arr2, name: '1', type: 'deleted', oldValue: 'beta' }, 1128 { object: arr2, name: '1', type: 'delete', oldValue: 'beta' },
1042 { object: arr2, name: 'length', type: 'updated', oldValue: 2 }, 1129 { object: arr2, name: 'length', type: 'update', oldValue: 2 },
1043 { object: arr2, name: 'length', type: 'reconfigured' }, 1130 { object: arr2, name: 'length', type: 'reconfigure' },
1044 { object: arr3, name: '2', type: 'deleted', oldValue: 'goodbye' }, 1131 { object: arr3, name: '2', type: 'delete', oldValue: 'goodbye' },
1045 { object: arr3, name: '0', type: 'deleted', oldValue: 'hello' }, 1132 { object: arr3, name: '0', type: 'delete', oldValue: 'hello' },
1046 { object: arr3, name: 'length', type: 'updated', oldValue: 6 }, 1133 { object: arr3, name: 'length', type: 'update', oldValue: 6 },
1047 { object: arr3, name: 'length', type: 'updated', oldValue: 0 }, 1134 { object: arr3, name: 'length', type: 'update', oldValue: 0 },
1048 { object: arr3, name: 'length', type: 'updated', oldValue: 1 }, 1135 { object: arr3, name: 'length', type: 'update', oldValue: 1 },
1049 { object: arr3, name: 'length', type: 'updated', oldValue: 2 }, 1136 { object: arr3, name: 'length', type: 'update', oldValue: 2 },
1050 { object: arr3, name: 'length', type: 'updated', oldValue: 1 }, 1137 { object: arr3, name: 'length', type: 'update', oldValue: 1 },
1051 { object: arr3, name: '4', type: 'new' }, 1138 { object: arr3, name: '4', type: 'add' },
1052 { object: arr3, name: '4', type: 'deleted', oldValue: 5 }, 1139 { object: arr3, name: '4', type: 'delete', oldValue: 5 },
1053 // TODO(rafaelw): It breaks spec compliance to get two records here. 1140 // TODO(rafaelw): It breaks spec compliance to get two records here.
1054 // When the TODO in v8natives.js::DefineArrayProperty is addressed 1141 // When the TODO in v8natives.js::DefineArrayProperty is addressed
1055 // which prevents DefineProperty from over-writing the magic length 1142 // which prevents DefineProperty from over-writing the magic length
1056 // property, these will collapse into a single record. 1143 // property, these will collapse into a single record.
1057 { object: arr3, name: 'length', type: 'updated', oldValue: 5 }, 1144 { object: arr3, name: 'length', type: 'update', oldValue: 5 },
1058 { object: arr3, name: 'length', type: 'reconfigured' } 1145 { object: arr3, name: 'length', type: 'reconfigure' }
1059 ]); 1146 ]);
1060 Object.deliverChangeRecords(observer2.callback); 1147 Object.deliverChangeRecords(observer2.callback);
1061 observer2.assertCallbackRecords([ 1148 observer2.assertCallbackRecords([
1062 { object: arr, type: 'splice', index: 2, removed: [, 'd'], addedCount: 0 }, 1149 { object: arr, type: 'splice', index: 2, removed: [, 'd'], addedCount: 0 },
1063 { object: arr, type: 'splice', index: 1, removed: ['b'], addedCount: 0 }, 1150 { object: arr, type: 'splice', index: 1, removed: ['b'], addedCount: 0 },
1064 { object: arr, type: 'splice', index: 1, removed: [], addedCount: 9 }, 1151 { object: arr, type: 'splice', index: 1, removed: [], addedCount: 9 },
1065 { object: arr2, type: 'splice', index: 1, removed: ['beta'], addedCount: 0 }, 1152 { object: arr2, type: 'splice', index: 1, removed: ['beta'], addedCount: 0 },
1066 { object: arr3, type: 'splice', index: 0, removed: ['hello',, 'goodbye',,,,], addedCount: 0 }, 1153 { object: arr3, type: 'splice', index: 0, removed: ['hello',, 'goodbye',,,,], addedCount: 0 },
1067 { object: arr3, type: 'splice', index: 0, removed: [], addedCount: 1 }, 1154 { object: arr3, type: 'splice', index: 0, removed: [], addedCount: 1 },
1068 { object: arr3, type: 'splice', index: 1, removed: [], addedCount: 1 }, 1155 { object: arr3, type: 'splice', index: 1, removed: [], addedCount: 1 },
1069 { object: arr3, type: 'splice', index: 1, removed: [,], addedCount: 0 }, 1156 { object: arr3, type: 'splice', index: 1, removed: [,], addedCount: 0 },
1070 { object: arr3, type: 'splice', index: 1, removed: [], addedCount: 4 }, 1157 { object: arr3, type: 'splice', index: 1, removed: [], addedCount: 4 },
1071 { object: arr3, name: '4', type: 'new' }, 1158 { object: arr3, name: '4', type: 'add' },
1072 { object: arr3, type: 'splice', index: 1, removed: [,,,5], addedCount: 0 } 1159 { object: arr3, type: 'splice', index: 1, removed: [,,,5], addedCount: 0 }
1073 ]); 1160 ]);
1074 1161
1075 1162
1076 // Updating length on large (slow) array 1163 // Updating length on large (slow) array
1077 reset(); 1164 reset();
1078 var slow_arr = new Array(1000000000); 1165 var slow_arr = new Array(1000000000);
1079 slow_arr[500000000] = 'hello'; 1166 slow_arr[500000000] = 'hello';
1080 Object.observe(slow_arr, observer.callback); 1167 Object.observe(slow_arr, observer.callback);
1081 var spliceRecords; 1168 var spliceRecords;
1082 function slowSpliceCallback(records) { 1169 function slowSpliceCallback(records) {
1083 spliceRecords = records; 1170 spliceRecords = records;
1084 } 1171 }
1085 Array.observe(slow_arr, slowSpliceCallback); 1172 Array.observe(slow_arr, slowSpliceCallback);
1086 slow_arr.length = 100; 1173 slow_arr.length = 100;
1087 Object.deliverChangeRecords(observer.callback); 1174 Object.deliverChangeRecords(observer.callback);
1088 observer.assertCallbackRecords([ 1175 observer.assertCallbackRecords([
1089 { object: slow_arr, name: '500000000', type: 'deleted', oldValue: 'hello' }, 1176 { object: slow_arr, name: '500000000', type: 'delete', oldValue: 'hello' },
1090 { object: slow_arr, name: 'length', type: 'updated', oldValue: 1000000000 }, 1177 { object: slow_arr, name: 'length', type: 'update', oldValue: 1000000000 },
1091 ]); 1178 ]);
1092 Object.deliverChangeRecords(slowSpliceCallback); 1179 Object.deliverChangeRecords(slowSpliceCallback);
1093 assertEquals(spliceRecords.length, 1); 1180 assertEquals(spliceRecords.length, 1);
1094 // Have to custom assert this splice record because the removed array is huge. 1181 // Have to custom assert this splice record because the removed array is huge.
1095 var splice = spliceRecords[0]; 1182 var splice = spliceRecords[0];
1096 assertSame(splice.object, slow_arr); 1183 assertSame(splice.object, slow_arr);
1097 assertEquals(splice.type, 'splice'); 1184 assertEquals(splice.type, 'splice');
1098 assertEquals(splice.index, 100); 1185 assertEquals(splice.index, 100);
1099 assertEquals(splice.addedCount, 0); 1186 assertEquals(splice.addedCount, 0);
1100 var array_keys = %GetArrayKeys(splice.removed, splice.removed.length); 1187 var array_keys = %GetArrayKeys(splice.removed, splice.removed.length);
1101 assertEquals(array_keys.length, 1); 1188 assertEquals(array_keys.length, 1);
1102 assertEquals(array_keys[0], 499999900); 1189 assertEquals(array_keys[0], 499999900);
1103 assertEquals(splice.removed[499999900], 'hello'); 1190 assertEquals(splice.removed[499999900], 'hello');
1104 assertEquals(splice.removed.length, 999999900); 1191 assertEquals(splice.removed.length, 999999900);
1105 1192
1106 1193
1107 // Assignments in loops (checking different IC states). 1194 // Assignments in loops (checking different IC states).
1108 reset(); 1195 reset();
1109 var obj = {}; 1196 var obj = {};
1110 Object.observe(obj, observer.callback); 1197 Object.observe(obj, observer.callback);
1111 for (var i = 0; i < 5; i++) { 1198 for (var i = 0; i < 5; i++) {
1112 obj["a" + i] = i; 1199 obj["a" + i] = i;
1113 } 1200 }
1114 Object.deliverChangeRecords(observer.callback); 1201 Object.deliverChangeRecords(observer.callback);
1115 observer.assertCallbackRecords([ 1202 observer.assertCallbackRecords([
1116 { object: obj, name: "a0", type: "new" }, 1203 { object: obj, name: "a0", type: "add" },
1117 { object: obj, name: "a1", type: "new" }, 1204 { object: obj, name: "a1", type: "add" },
1118 { object: obj, name: "a2", type: "new" }, 1205 { object: obj, name: "a2", type: "add" },
1119 { object: obj, name: "a3", type: "new" }, 1206 { object: obj, name: "a3", type: "add" },
1120 { object: obj, name: "a4", type: "new" }, 1207 { object: obj, name: "a4", type: "add" },
1121 ]); 1208 ]);
1122 1209
1123 reset(); 1210 reset();
1124 var obj = {}; 1211 var obj = {};
1125 Object.observe(obj, observer.callback); 1212 Object.observe(obj, observer.callback);
1126 for (var i = 0; i < 5; i++) { 1213 for (var i = 0; i < 5; i++) {
1127 obj[i] = i; 1214 obj[i] = i;
1128 } 1215 }
1129 Object.deliverChangeRecords(observer.callback); 1216 Object.deliverChangeRecords(observer.callback);
1130 observer.assertCallbackRecords([ 1217 observer.assertCallbackRecords([
1131 { object: obj, name: "0", type: "new" }, 1218 { object: obj, name: "0", type: "add" },
1132 { object: obj, name: "1", type: "new" }, 1219 { object: obj, name: "1", type: "add" },
1133 { object: obj, name: "2", type: "new" }, 1220 { object: obj, name: "2", type: "add" },
1134 { object: obj, name: "3", type: "new" }, 1221 { object: obj, name: "3", type: "add" },
1135 { object: obj, name: "4", type: "new" }, 1222 { object: obj, name: "4", type: "add" },
1136 ]); 1223 ]);
1137 1224
1138 1225
1139 // Adding elements past the end of an array should notify on length for 1226 // Adding elements past the end of an array should notify on length for
1140 // Object.observe and emit "splices" for Array.observe. 1227 // Object.observe and emit "splices" for Array.observe.
1141 reset(); 1228 reset();
1142 var arr = [1, 2, 3]; 1229 var arr = [1, 2, 3];
1143 Object.observe(arr, observer.callback); 1230 Object.observe(arr, observer.callback);
1144 Array.observe(arr, observer2.callback); 1231 Array.observe(arr, observer2.callback);
1145 arr[3] = 10; 1232 arr[3] = 10;
1146 arr[100] = 20; 1233 arr[100] = 20;
1147 Object.defineProperty(arr, '200', {value: 7}); 1234 Object.defineProperty(arr, '200', {value: 7});
1148 Object.defineProperty(arr, '400', {get: function(){}}); 1235 Object.defineProperty(arr, '400', {get: function(){}});
1149 arr[50] = 30; // no length change expected 1236 arr[50] = 30; // no length change expected
1150 Object.deliverChangeRecords(observer.callback); 1237 Object.deliverChangeRecords(observer.callback);
1151 observer.assertCallbackRecords([ 1238 observer.assertCallbackRecords([
1152 { object: arr, name: '3', type: 'new' }, 1239 { object: arr, name: '3', type: 'add' },
1153 { object: arr, name: 'length', type: 'updated', oldValue: 3 }, 1240 { object: arr, name: 'length', type: 'update', oldValue: 3 },
1154 { object: arr, name: '100', type: 'new' }, 1241 { object: arr, name: '100', type: 'add' },
1155 { object: arr, name: 'length', type: 'updated', oldValue: 4 }, 1242 { object: arr, name: 'length', type: 'update', oldValue: 4 },
1156 { object: arr, name: '200', type: 'new' }, 1243 { object: arr, name: '200', type: 'add' },
1157 { object: arr, name: 'length', type: 'updated', oldValue: 101 }, 1244 { object: arr, name: 'length', type: 'update', oldValue: 101 },
1158 { object: arr, name: '400', type: 'new' }, 1245 { object: arr, name: '400', type: 'add' },
1159 { object: arr, name: 'length', type: 'updated', oldValue: 201 }, 1246 { object: arr, name: 'length', type: 'update', oldValue: 201 },
1160 { object: arr, name: '50', type: 'new' }, 1247 { object: arr, name: '50', type: 'add' },
1161 ]); 1248 ]);
1162 Object.deliverChangeRecords(observer2.callback); 1249 Object.deliverChangeRecords(observer2.callback);
1163 observer2.assertCallbackRecords([ 1250 observer2.assertCallbackRecords([
1164 { object: arr, type: 'splice', index: 3, removed: [], addedCount: 1 }, 1251 { object: arr, type: 'splice', index: 3, removed: [], addedCount: 1 },
1165 { object: arr, type: 'splice', index: 4, removed: [], addedCount: 97 }, 1252 { object: arr, type: 'splice', index: 4, removed: [], addedCount: 97 },
1166 { object: arr, type: 'splice', index: 101, removed: [], addedCount: 100 }, 1253 { object: arr, type: 'splice', index: 101, removed: [], addedCount: 100 },
1167 { object: arr, type: 'splice', index: 201, removed: [], addedCount: 200 }, 1254 { object: arr, type: 'splice', index: 201, removed: [], addedCount: 200 },
1168 { object: arr, type: 'new', name: '50' }, 1255 { object: arr, type: 'add', name: '50' },
1169 ]); 1256 ]);
1170 1257
1171 1258
1172 // Tests for array methods, first on arrays and then on plain objects 1259 // Tests for array methods, first on arrays and then on plain objects
1173 // 1260 //
1174 // === ARRAYS === 1261 // === ARRAYS ===
1175 // 1262 //
1176 // Push 1263 // Push
1177 reset(); 1264 reset();
1178 var array = [1, 2]; 1265 var array = [1, 2];
1179 Object.observe(array, observer.callback); 1266 Object.observe(array, observer.callback);
1180 Array.observe(array, observer2.callback); 1267 Array.observe(array, observer2.callback);
1181 array.push(3, 4); 1268 array.push(3, 4);
1182 array.push(5); 1269 array.push(5);
1183 Object.deliverChangeRecords(observer.callback); 1270 Object.deliverChangeRecords(observer.callback);
1184 observer.assertCallbackRecords([ 1271 observer.assertCallbackRecords([
1185 { object: array, name: '2', type: 'new' }, 1272 { object: array, name: '2', type: 'add' },
1186 { object: array, name: 'length', type: 'updated', oldValue: 2 }, 1273 { object: array, name: 'length', type: 'update', oldValue: 2 },
1187 { object: array, name: '3', type: 'new' }, 1274 { object: array, name: '3', type: 'add' },
1188 { object: array, name: 'length', type: 'updated', oldValue: 3 }, 1275 { object: array, name: 'length', type: 'update', oldValue: 3 },
1189 { object: array, name: '4', type: 'new' }, 1276 { object: array, name: '4', type: 'add' },
1190 { object: array, name: 'length', type: 'updated', oldValue: 4 }, 1277 { object: array, name: 'length', type: 'update', oldValue: 4 },
1191 ]); 1278 ]);
1192 Object.deliverChangeRecords(observer2.callback); 1279 Object.deliverChangeRecords(observer2.callback);
1193 observer2.assertCallbackRecords([ 1280 observer2.assertCallbackRecords([
1194 { object: array, type: 'splice', index: 2, removed: [], addedCount: 2 }, 1281 { object: array, type: 'splice', index: 2, removed: [], addedCount: 2 },
1195 { object: array, type: 'splice', index: 4, removed: [], addedCount: 1 } 1282 { object: array, type: 'splice', index: 4, removed: [], addedCount: 1 }
1196 ]); 1283 ]);
1197 1284
1198 // Pop 1285 // Pop
1199 reset(); 1286 reset();
1200 var array = [1, 2]; 1287 var array = [1, 2];
1201 Object.observe(array, observer.callback); 1288 Object.observe(array, observer.callback);
1202 array.pop(); 1289 array.pop();
1203 array.pop(); 1290 array.pop();
1204 Object.deliverChangeRecords(observer.callback); 1291 Object.deliverChangeRecords(observer.callback);
1205 observer.assertCallbackRecords([ 1292 observer.assertCallbackRecords([
1206 { object: array, name: '1', type: 'deleted', oldValue: 2 }, 1293 { object: array, name: '1', type: 'delete', oldValue: 2 },
1207 { object: array, name: 'length', type: 'updated', oldValue: 2 }, 1294 { object: array, name: 'length', type: 'update', oldValue: 2 },
1208 { object: array, name: '0', type: 'deleted', oldValue: 1 }, 1295 { object: array, name: '0', type: 'delete', oldValue: 1 },
1209 { object: array, name: 'length', type: 'updated', oldValue: 1 }, 1296 { object: array, name: 'length', type: 'update', oldValue: 1 },
1210 ]); 1297 ]);
1211 1298
1212 // Shift 1299 // Shift
1213 reset(); 1300 reset();
1214 var array = [1, 2]; 1301 var array = [1, 2];
1215 Object.observe(array, observer.callback); 1302 Object.observe(array, observer.callback);
1216 array.shift(); 1303 array.shift();
1217 array.shift(); 1304 array.shift();
1218 Object.deliverChangeRecords(observer.callback); 1305 Object.deliverChangeRecords(observer.callback);
1219 observer.assertCallbackRecords([ 1306 observer.assertCallbackRecords([
1220 { object: array, name: '0', type: 'updated', oldValue: 1 }, 1307 { object: array, name: '0', type: 'update', oldValue: 1 },
1221 { object: array, name: '1', type: 'deleted', oldValue: 2 }, 1308 { object: array, name: '1', type: 'delete', oldValue: 2 },
1222 { object: array, name: 'length', type: 'updated', oldValue: 2 }, 1309 { object: array, name: 'length', type: 'update', oldValue: 2 },
1223 { object: array, name: '0', type: 'deleted', oldValue: 2 }, 1310 { object: array, name: '0', type: 'delete', oldValue: 2 },
1224 { object: array, name: 'length', type: 'updated', oldValue: 1 }, 1311 { object: array, name: 'length', type: 'update', oldValue: 1 },
1225 ]); 1312 ]);
1226 1313
1227 // Unshift 1314 // Unshift
1228 reset(); 1315 reset();
1229 var array = [1, 2]; 1316 var array = [1, 2];
1230 Object.observe(array, observer.callback); 1317 Object.observe(array, observer.callback);
1231 array.unshift(3, 4); 1318 array.unshift(3, 4);
1232 Object.deliverChangeRecords(observer.callback); 1319 Object.deliverChangeRecords(observer.callback);
1233 observer.assertCallbackRecords([ 1320 observer.assertCallbackRecords([
1234 { object: array, name: '3', type: 'new' }, 1321 { object: array, name: '3', type: 'add' },
1235 { object: array, name: 'length', type: 'updated', oldValue: 2 }, 1322 { object: array, name: 'length', type: 'update', oldValue: 2 },
1236 { object: array, name: '2', type: 'new' }, 1323 { object: array, name: '2', type: 'add' },
1237 { object: array, name: '0', type: 'updated', oldValue: 1 }, 1324 { object: array, name: '0', type: 'update', oldValue: 1 },
1238 { object: array, name: '1', type: 'updated', oldValue: 2 }, 1325 { object: array, name: '1', type: 'update', oldValue: 2 },
1239 ]); 1326 ]);
1240 1327
1241 // Splice 1328 // Splice
1242 reset(); 1329 reset();
1243 var array = [1, 2, 3]; 1330 var array = [1, 2, 3];
1244 Object.observe(array, observer.callback); 1331 Object.observe(array, observer.callback);
1245 array.splice(1, 1, 4, 5); 1332 array.splice(1, 1, 4, 5);
1246 Object.deliverChangeRecords(observer.callback); 1333 Object.deliverChangeRecords(observer.callback);
1247 observer.assertCallbackRecords([ 1334 observer.assertCallbackRecords([
1248 { object: array, name: '3', type: 'new' }, 1335 { object: array, name: '3', type: 'add' },
1249 { object: array, name: 'length', type: 'updated', oldValue: 3 }, 1336 { object: array, name: 'length', type: 'update', oldValue: 3 },
1250 { object: array, name: '1', type: 'updated', oldValue: 2 }, 1337 { object: array, name: '1', type: 'update', oldValue: 2 },
1251 { object: array, name: '2', type: 'updated', oldValue: 3 }, 1338 { object: array, name: '2', type: 'update', oldValue: 3 },
1252 ]); 1339 ]);
1253 1340
1254 // Sort 1341 // Sort
1255 reset(); 1342 reset();
1256 var array = [3, 2, 1]; 1343 var array = [3, 2, 1];
1257 Object.observe(array, observer.callback); 1344 Object.observe(array, observer.callback);
1258 array.sort(); 1345 array.sort();
1259 assertEquals(1, array[0]); 1346 assertEquals(1, array[0]);
1260 assertEquals(2, array[1]); 1347 assertEquals(2, array[1]);
1261 assertEquals(3, array[2]); 1348 assertEquals(3, array[2]);
1262 Object.deliverChangeRecords(observer.callback); 1349 Object.deliverChangeRecords(observer.callback);
1263 observer.assertCallbackRecords([ 1350 observer.assertCallbackRecords([
1264 { object: array, name: '1', type: 'updated', oldValue: 2 }, 1351 { object: array, name: '1', type: 'update', oldValue: 2 },
1265 { object: array, name: '0', type: 'updated', oldValue: 3 }, 1352 { object: array, name: '0', type: 'update', oldValue: 3 },
1266 { object: array, name: '2', type: 'updated', oldValue: 1 }, 1353 { object: array, name: '2', type: 'update', oldValue: 1 },
1267 { object: array, name: '1', type: 'updated', oldValue: 3 }, 1354 { object: array, name: '1', type: 'update', oldValue: 3 },
1268 { object: array, name: '0', type: 'updated', oldValue: 2 }, 1355 { object: array, name: '0', type: 'update', oldValue: 2 },
1269 ]); 1356 ]);
1270 1357
1271 // Splice emitted after Array mutation methods 1358 // Splice emitted after Array mutation methods
1272 function MockArray(initial, observer) { 1359 function MockArray(initial, observer) {
1273 for (var i = 0; i < initial.length; i++) 1360 for (var i = 0; i < initial.length; i++)
1274 this[i] = initial[i]; 1361 this[i] = initial[i];
1275 1362
1276 this.length_ = initial.length; 1363 this.length_ = initial.length;
1277 this.observer = observer; 1364 this.observer = observer;
1278 } 1365 }
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1340 // 1427 //
1341 // === PLAIN OBJECTS === 1428 // === PLAIN OBJECTS ===
1342 // 1429 //
1343 // Push 1430 // Push
1344 reset() 1431 reset()
1345 var array = {0: 1, 1: 2, length: 2} 1432 var array = {0: 1, 1: 2, length: 2}
1346 Object.observe(array, observer.callback); 1433 Object.observe(array, observer.callback);
1347 Array.prototype.push.call(array, 3, 4); 1434 Array.prototype.push.call(array, 3, 4);
1348 Object.deliverChangeRecords(observer.callback); 1435 Object.deliverChangeRecords(observer.callback);
1349 observer.assertCallbackRecords([ 1436 observer.assertCallbackRecords([
1350 { object: array, name: '2', type: 'new' }, 1437 { object: array, name: '2', type: 'add' },
1351 { object: array, name: '3', type: 'new' }, 1438 { object: array, name: '3', type: 'add' },
1352 { object: array, name: 'length', type: 'updated', oldValue: 2 }, 1439 { object: array, name: 'length', type: 'update', oldValue: 2 },
1353 ]); 1440 ]);
1354 1441
1355 // Pop 1442 // Pop
1356 reset(); 1443 reset();
1357 var array = [1, 2]; 1444 var array = [1, 2];
1358 Object.observe(array, observer.callback); 1445 Object.observe(array, observer.callback);
1359 Array.observe(array, observer2.callback); 1446 Array.observe(array, observer2.callback);
1360 array.pop(); 1447 array.pop();
1361 array.pop(); 1448 array.pop();
1362 array.pop(); 1449 array.pop();
1363 Object.deliverChangeRecords(observer.callback); 1450 Object.deliverChangeRecords(observer.callback);
1364 observer.assertCallbackRecords([ 1451 observer.assertCallbackRecords([
1365 { object: array, name: '1', type: 'deleted', oldValue: 2 }, 1452 { object: array, name: '1', type: 'delete', oldValue: 2 },
1366 { object: array, name: 'length', type: 'updated', oldValue: 2 }, 1453 { object: array, name: 'length', type: 'update', oldValue: 2 },
1367 { object: array, name: '0', type: 'deleted', oldValue: 1 }, 1454 { object: array, name: '0', type: 'delete', oldValue: 1 },
1368 { object: array, name: 'length', type: 'updated', oldValue: 1 }, 1455 { object: array, name: 'length', type: 'update', oldValue: 1 },
1369 ]); 1456 ]);
1370 Object.deliverChangeRecords(observer2.callback); 1457 Object.deliverChangeRecords(observer2.callback);
1371 observer2.assertCallbackRecords([ 1458 observer2.assertCallbackRecords([
1372 { object: array, type: 'splice', index: 1, removed: [2], addedCount: 0 }, 1459 { object: array, type: 'splice', index: 1, removed: [2], addedCount: 0 },
1373 { object: array, type: 'splice', index: 0, removed: [1], addedCount: 0 } 1460 { object: array, type: 'splice', index: 0, removed: [1], addedCount: 0 }
1374 ]); 1461 ]);
1375 1462
1376 // Shift 1463 // Shift
1377 reset(); 1464 reset();
1378 var array = [1, 2]; 1465 var array = [1, 2];
1379 Object.observe(array, observer.callback); 1466 Object.observe(array, observer.callback);
1380 Array.observe(array, observer2.callback); 1467 Array.observe(array, observer2.callback);
1381 array.shift(); 1468 array.shift();
1382 array.shift(); 1469 array.shift();
1383 array.shift(); 1470 array.shift();
1384 Object.deliverChangeRecords(observer.callback); 1471 Object.deliverChangeRecords(observer.callback);
1385 observer.assertCallbackRecords([ 1472 observer.assertCallbackRecords([
1386 { object: array, name: '0', type: 'updated', oldValue: 1 }, 1473 { object: array, name: '0', type: 'update', oldValue: 1 },
1387 { object: array, name: '1', type: 'deleted', oldValue: 2 }, 1474 { object: array, name: '1', type: 'delete', oldValue: 2 },
1388 { object: array, name: 'length', type: 'updated', oldValue: 2 }, 1475 { object: array, name: 'length', type: 'update', oldValue: 2 },
1389 { object: array, name: '0', type: 'deleted', oldValue: 2 }, 1476 { object: array, name: '0', type: 'delete', oldValue: 2 },
1390 { object: array, name: 'length', type: 'updated', oldValue: 1 }, 1477 { object: array, name: 'length', type: 'update', oldValue: 1 },
1391 ]); 1478 ]);
1392 Object.deliverChangeRecords(observer2.callback); 1479 Object.deliverChangeRecords(observer2.callback);
1393 observer2.assertCallbackRecords([ 1480 observer2.assertCallbackRecords([
1394 { object: array, type: 'splice', index: 0, removed: [1], addedCount: 0 }, 1481 { object: array, type: 'splice', index: 0, removed: [1], addedCount: 0 },
1395 { object: array, type: 'splice', index: 0, removed: [2], addedCount: 0 } 1482 { object: array, type: 'splice', index: 0, removed: [2], addedCount: 0 }
1396 ]); 1483 ]);
1397 1484
1398 // Unshift 1485 // Unshift
1399 reset(); 1486 reset();
1400 var array = [1, 2]; 1487 var array = [1, 2];
1401 Object.observe(array, observer.callback); 1488 Object.observe(array, observer.callback);
1402 Array.observe(array, observer2.callback); 1489 Array.observe(array, observer2.callback);
1403 array.unshift(3, 4); 1490 array.unshift(3, 4);
1404 array.unshift(5); 1491 array.unshift(5);
1405 Object.deliverChangeRecords(observer.callback); 1492 Object.deliverChangeRecords(observer.callback);
1406 observer.assertCallbackRecords([ 1493 observer.assertCallbackRecords([
1407 { object: array, name: '3', type: 'new' }, 1494 { object: array, name: '3', type: 'add' },
1408 { object: array, name: 'length', type: 'updated', oldValue: 2 }, 1495 { object: array, name: 'length', type: 'update', oldValue: 2 },
1409 { object: array, name: '2', type: 'new' }, 1496 { object: array, name: '2', type: 'add' },
1410 { object: array, name: '0', type: 'updated', oldValue: 1 }, 1497 { object: array, name: '0', type: 'update', oldValue: 1 },
1411 { object: array, name: '1', type: 'updated', oldValue: 2 }, 1498 { object: array, name: '1', type: 'update', oldValue: 2 },
1412 { object: array, name: '4', type: 'new' }, 1499 { object: array, name: '4', type: 'add' },
1413 { object: array, name: 'length', type: 'updated', oldValue: 4 }, 1500 { object: array, name: 'length', type: 'update', oldValue: 4 },
1414 { object: array, name: '3', type: 'updated', oldValue: 2 }, 1501 { object: array, name: '3', type: 'update', oldValue: 2 },
1415 { object: array, name: '2', type: 'updated', oldValue: 1 }, 1502 { object: array, name: '2', type: 'update', oldValue: 1 },
1416 { object: array, name: '1', type: 'updated', oldValue: 4 }, 1503 { object: array, name: '1', type: 'update', oldValue: 4 },
1417 { object: array, name: '0', type: 'updated', oldValue: 3 }, 1504 { object: array, name: '0', type: 'update', oldValue: 3 },
1418 ]); 1505 ]);
1419 Object.deliverChangeRecords(observer2.callback); 1506 Object.deliverChangeRecords(observer2.callback);
1420 observer2.assertCallbackRecords([ 1507 observer2.assertCallbackRecords([
1421 { object: array, type: 'splice', index: 0, removed: [], addedCount: 2 }, 1508 { object: array, type: 'splice', index: 0, removed: [], addedCount: 2 },
1422 { object: array, type: 'splice', index: 0, removed: [], addedCount: 1 } 1509 { object: array, type: 'splice', index: 0, removed: [], addedCount: 1 }
1423 ]); 1510 ]);
1424 1511
1425 // Splice 1512 // Splice
1426 reset(); 1513 reset();
1427 var array = [1, 2, 3]; 1514 var array = [1, 2, 3];
1428 Object.observe(array, observer.callback); 1515 Object.observe(array, observer.callback);
1429 Array.observe(array, observer2.callback); 1516 Array.observe(array, observer2.callback);
1430 array.splice(1, 0, 4, 5); // 1 4 5 2 3 1517 array.splice(1, 0, 4, 5); // 1 4 5 2 3
1431 array.splice(0, 2); // 5 2 3 1518 array.splice(0, 2); // 5 2 3
1432 array.splice(1, 2, 6, 7); // 5 6 7 1519 array.splice(1, 2, 6, 7); // 5 6 7
1433 array.splice(2, 0); 1520 array.splice(2, 0);
1434 Object.deliverChangeRecords(observer.callback); 1521 Object.deliverChangeRecords(observer.callback);
1435 observer.assertCallbackRecords([ 1522 observer.assertCallbackRecords([
1436 { object: array, name: '4', type: 'new' }, 1523 { object: array, name: '4', type: 'add' },
1437 { object: array, name: 'length', type: 'updated', oldValue: 3 }, 1524 { object: array, name: 'length', type: 'update', oldValue: 3 },
1438 { object: array, name: '3', type: 'new' }, 1525 { object: array, name: '3', type: 'add' },
1439 { object: array, name: '1', type: 'updated', oldValue: 2 }, 1526 { object: array, name: '1', type: 'update', oldValue: 2 },
1440 { object: array, name: '2', type: 'updated', oldValue: 3 }, 1527 { object: array, name: '2', type: 'update', oldValue: 3 },
1441 1528
1442 { object: array, name: '0', type: 'updated', oldValue: 1 }, 1529 { object: array, name: '0', type: 'update', oldValue: 1 },
1443 { object: array, name: '1', type: 'updated', oldValue: 4 }, 1530 { object: array, name: '1', type: 'update', oldValue: 4 },
1444 { object: array, name: '2', type: 'updated', oldValue: 5 }, 1531 { object: array, name: '2', type: 'update', oldValue: 5 },
1445 { object: array, name: '4', type: 'deleted', oldValue: 3 }, 1532 { object: array, name: '4', type: 'delete', oldValue: 3 },
1446 { object: array, name: '3', type: 'deleted', oldValue: 2 }, 1533 { object: array, name: '3', type: 'delete', oldValue: 2 },
1447 { object: array, name: 'length', type: 'updated', oldValue: 5 }, 1534 { object: array, name: 'length', type: 'update', oldValue: 5 },
1448 1535
1449 { object: array, name: '1', type: 'updated', oldValue: 2 }, 1536 { object: array, name: '1', type: 'update', oldValue: 2 },
1450 { object: array, name: '2', type: 'updated', oldValue: 3 }, 1537 { object: array, name: '2', type: 'update', oldValue: 3 },
1451 ]); 1538 ]);
1452 Object.deliverChangeRecords(observer2.callback); 1539 Object.deliverChangeRecords(observer2.callback);
1453 observer2.assertCallbackRecords([ 1540 observer2.assertCallbackRecords([
1454 { object: array, type: 'splice', index: 1, removed: [], addedCount: 2 }, 1541 { object: array, type: 'splice', index: 1, removed: [], addedCount: 2 },
1455 { object: array, type: 'splice', index: 0, removed: [1, 4], addedCount: 0 }, 1542 { object: array, type: 'splice', index: 0, removed: [1, 4], addedCount: 0 },
1456 { object: array, type: 'splice', index: 1, removed: [2, 3], addedCount: 2 }, 1543 { object: array, type: 'splice', index: 1, removed: [2, 3], addedCount: 2 },
1457 ]); 1544 ]);
1458 1545
1459 // Exercise StoreIC_ArrayLength 1546 // Exercise StoreIC_ArrayLength
1460 reset(); 1547 reset();
1461 var dummy = {}; 1548 var dummy = {};
1462 Object.observe(dummy, observer.callback); 1549 Object.observe(dummy, observer.callback);
1463 Object.unobserve(dummy, observer.callback); 1550 Object.unobserve(dummy, observer.callback);
1464 var array = [0]; 1551 var array = [0];
1465 Object.observe(array, observer.callback); 1552 Object.observe(array, observer.callback);
1466 array.splice(0, 1); 1553 array.splice(0, 1);
1467 Object.deliverChangeRecords(observer.callback); 1554 Object.deliverChangeRecords(observer.callback);
1468 observer.assertCallbackRecords([ 1555 observer.assertCallbackRecords([
1469 { object: array, name: '0', type: 'deleted', oldValue: 0 }, 1556 { object: array, name: '0', type: 'delete', oldValue: 0 },
1470 { object: array, name: 'length', type: 'updated', oldValue: 1}, 1557 { object: array, name: 'length', type: 'update', oldValue: 1},
1471 ]); 1558 ]);
1472 1559
1473 1560
1474 // __proto__ 1561 // __proto__
1475 reset(); 1562 reset();
1476 var obj = {}; 1563 var obj = {};
1477 Object.observe(obj, observer.callback); 1564 Object.observe(obj, observer.callback);
1478 var p = {foo: 'yes'}; 1565 var p = {foo: 'yes'};
1479 var q = {bar: 'no'}; 1566 var q = {bar: 'no'};
1480 obj.__proto__ = p; 1567 obj.__proto__ = p;
1481 obj.__proto__ = p; // ignored 1568 obj.__proto__ = p; // ignored
1482 obj.__proto__ = null; 1569 obj.__proto__ = null;
1483 obj.__proto__ = q; // the __proto__ accessor is gone 1570 obj.__proto__ = q; // the __proto__ accessor is gone
1484 // TODO(adamk): Add tests for objects with hidden prototypes 1571 // TODO(adamk): Add tests for objects with hidden prototypes
1485 // once we support observing the global object. 1572 // once we support observing the global object.
1486 Object.deliverChangeRecords(observer.callback); 1573 Object.deliverChangeRecords(observer.callback);
1487 observer.assertCallbackRecords([ 1574 observer.assertCallbackRecords([
1488 { object: obj, name: '__proto__', type: 'prototype', 1575 { object: obj, name: '__proto__', type: 'setPrototype',
1489 oldValue: Object.prototype }, 1576 oldValue: Object.prototype },
1490 { object: obj, name: '__proto__', type: 'prototype', oldValue: p }, 1577 { object: obj, name: '__proto__', type: 'setPrototype', oldValue: p },
1491 { object: obj, name: '__proto__', type: 'new' }, 1578 { object: obj, name: '__proto__', type: 'add' },
1492 ]); 1579 ]);
1493 1580
1494 1581
1495 // Function.prototype 1582 // Function.prototype
1496 reset(); 1583 reset();
1497 var fun = function(){}; 1584 var fun = function(){};
1498 Object.observe(fun, observer.callback); 1585 Object.observe(fun, observer.callback);
1499 var myproto = {foo: 'bar'}; 1586 var myproto = {foo: 'bar'};
1500 fun.prototype = myproto; 1587 fun.prototype = myproto;
1501 fun.prototype = 7; 1588 fun.prototype = 7;
1502 fun.prototype = 7; // ignored 1589 fun.prototype = 7; // ignored
1503 Object.defineProperty(fun, 'prototype', {value: 8}); 1590 Object.defineProperty(fun, 'prototype', {value: 8});
1504 Object.deliverChangeRecords(observer.callback); 1591 Object.deliverChangeRecords(observer.callback);
1505 observer.assertRecordCount(3); 1592 observer.assertRecordCount(3);
1506 // Manually examine the first record in order to test 1593 // Manually examine the first record in order to test
1507 // lazy creation of oldValue 1594 // lazy creation of oldValue
1508 assertSame(fun, observer.records[0].object); 1595 assertSame(fun, observer.records[0].object);
1509 assertEquals('prototype', observer.records[0].name); 1596 assertEquals('prototype', observer.records[0].name);
1510 assertEquals('updated', observer.records[0].type); 1597 assertEquals('update', observer.records[0].type);
1511 // The only existing reference to the oldValue object is in this 1598 // The only existing reference to the oldValue object is in this
1512 // record, so to test that lazy creation happened correctly 1599 // record, so to test that lazy creation happened correctly
1513 // we compare its constructor to our function (one of the invariants 1600 // we compare its constructor to our function (one of the invariants
1514 // ensured when creating an object via AllocateFunctionPrototype). 1601 // ensured when creating an object via AllocateFunctionPrototype).
1515 assertSame(fun, observer.records[0].oldValue.constructor); 1602 assertSame(fun, observer.records[0].oldValue.constructor);
1516 observer.records.splice(0, 1); 1603 observer.records.splice(0, 1);
1517 observer.assertCallbackRecords([ 1604 observer.assertCallbackRecords([
1518 { object: fun, name: 'prototype', type: 'updated', oldValue: myproto }, 1605 { object: fun, name: 'prototype', type: 'update', oldValue: myproto },
1519 { object: fun, name: 'prototype', type: 'updated', oldValue: 7 }, 1606 { object: fun, name: 'prototype', type: 'update', oldValue: 7 },
1520 ]); 1607 ]);
1521 1608
1522 // Function.prototype should not be observable except on the object itself 1609 // Function.prototype should not be observable except on the object itself
1523 reset(); 1610 reset();
1524 var fun = function(){}; 1611 var fun = function(){};
1525 var obj = { __proto__: fun }; 1612 var obj = { __proto__: fun };
1526 Object.observe(obj, observer.callback); 1613 Object.observe(obj, observer.callback);
1527 obj.prototype = 7; 1614 obj.prototype = 7;
1528 Object.deliverChangeRecords(observer.callback); 1615 Object.deliverChangeRecords(observer.callback);
1529 observer.assertNotCalled(); 1616 observer.assertNotCalled();
(...skipping 25 matching lines...) Expand all
1555 setElement(arr, prop, 4); 1642 setElement(arr, prop, 4);
1556 if (polymorphic) setElement(["M", "i", "l", "n", "e", "r"], 0, "m"); 1643 if (polymorphic) setElement(["M", "i", "l", "n", "e", "r"], 0, "m");
1557 if (optimize) %OptimizeFunctionOnNextCall(setElement); 1644 if (optimize) %OptimizeFunctionOnNextCall(setElement);
1558 setElement(arr, prop, 5); 1645 setElement(arr, prop, 5);
1559 1646
1560 reset(); 1647 reset();
1561 Object.observe(arr, observer.callback); 1648 Object.observe(arr, observer.callback);
1562 setElement(arr, prop, 989898); 1649 setElement(arr, prop, 989898);
1563 Object.deliverChangeRecords(observer.callback); 1650 Object.deliverChangeRecords(observer.callback);
1564 observer.assertCallbackRecords([ 1651 observer.assertCallbackRecords([
1565 { object: arr, name: "" + prop, type: 'updated', oldValue: 5 } 1652 { object: arr, name: "" + prop, type: 'update', oldValue: 5 }
1566 ]); 1653 ]);
1567 } 1654 }
1568 1655
1569 for (var b1 = 0; b1 < 2; ++b1) 1656 for (var b1 = 0; b1 < 2; ++b1)
1570 for (var b2 = 0; b2 < 2; ++b2) 1657 for (var b2 = 0; b2 < 2; ++b2)
1571 for (var b3 = 0; b3 < 2; ++b3) 1658 for (var b3 = 0; b3 < 2; ++b3)
1572 for (var i in props) 1659 for (var i in props)
1573 for (var j in mutation) 1660 for (var j in mutation)
1574 TestFastElements(props[i], mutation[j], b1 != 0, b2 != 0, b3 != 0); 1661 TestFastElements(props[i], mutation[j], b1 != 0, b2 != 0, b3 != 0);
1575 1662
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1612 setLength(arr, newSize); 1699 setLength(arr, newSize);
1613 Object.deliverChangeRecords(observer.callback); 1700 Object.deliverChangeRecords(observer.callback);
1614 if (oldSize === newSize) { 1701 if (oldSize === newSize) {
1615 observer.assertNotCalled(); 1702 observer.assertNotCalled();
1616 } else { 1703 } else {
1617 var count = oldSize > newSize ? oldSize - newSize : 0; 1704 var count = oldSize > newSize ? oldSize - newSize : 0;
1618 observer.assertRecordCount(count + 1); 1705 observer.assertRecordCount(count + 1);
1619 var lengthRecord = observer.records[count]; 1706 var lengthRecord = observer.records[count];
1620 assertSame(arr, lengthRecord.object); 1707 assertSame(arr, lengthRecord.object);
1621 assertEquals('length', lengthRecord.name); 1708 assertEquals('length', lengthRecord.name);
1622 assertEquals('updated', lengthRecord.type); 1709 assertEquals('update', lengthRecord.type);
1623 assertSame(oldSize, lengthRecord.oldValue); 1710 assertSame(oldSize, lengthRecord.oldValue);
1624 } 1711 }
1625 } 1712 }
1626 1713
1627 for (var b1 = 0; b1 < 2; ++b1) 1714 for (var b1 = 0; b1 < 2; ++b1)
1628 for (var b2 = 0; b2 < 2; ++b2) 1715 for (var b2 = 0; b2 < 2; ++b2)
1629 for (var n1 = 0; n1 < 3; ++n1) 1716 for (var n1 = 0; n1 < 3; ++n1)
1630 for (var n2 = 0; n2 < 3; ++n2) 1717 for (var n2 = 0; n2 < 3; ++n2)
1631 for (var i in mutation) 1718 for (var i in mutation)
1632 TestFastElementsLength(mutation[i], b1 != 0, b2 != 0, 20*n1, 20*n2); 1719 TestFastElementsLength(mutation[i], b1 != 0, b2 != 0, 20*n1, 20*n2);
1633 1720
1634 for (var b1 = 0; b1 < 2; ++b1) 1721 for (var b1 = 0; b1 < 2; ++b1)
1635 for (var b2 = 0; b2 < 2; ++b2) 1722 for (var b2 = 0; b2 < 2; ++b2)
1636 for (var n = 0; n < 3; ++n) 1723 for (var n = 0; n < 3; ++n)
1637 for (var i in mutationByIncr) 1724 for (var i in mutationByIncr)
1638 TestFastElementsLength(mutationByIncr[i], b1 != 0, b2 != 0, 7*n, 7*n+1); 1725 TestFastElementsLength(mutationByIncr[i], b1 != 0, b2 != 0, 7*n, 7*n+1);
OLDNEW
« no previous file with comments | « test/mjsunit/getters-on-elements.js ('k') | test/mjsunit/harmony/private.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698