| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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); |
| OLD | NEW |