summaryrefslogtreecommitdiff
path: root/src/3rdparty/v8/test/mjsunit/harmony/object-observe.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/v8/test/mjsunit/harmony/object-observe.js')
-rw-r--r--src/3rdparty/v8/test/mjsunit/harmony/object-observe.js1056
1 files changed, 0 insertions, 1056 deletions
diff --git a/src/3rdparty/v8/test/mjsunit/harmony/object-observe.js b/src/3rdparty/v8/test/mjsunit/harmony/object-observe.js
deleted file mode 100644
index 584d9e8..0000000
--- a/src/3rdparty/v8/test/mjsunit/harmony/object-observe.js
+++ /dev/null
@@ -1,1056 +0,0 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Flags: --harmony-observation --harmony-proxies --harmony-collections
-// Flags: --allow-natives-syntax
-
-var allObservers = [];
-function reset() {
- allObservers.forEach(function(observer) { observer.reset(); });
-}
-
-function stringifyNoThrow(arg) {
- try {
- return JSON.stringify(arg);
- } catch (e) {
- return '{<circular reference>}';
- }
-}
-
-function createObserver() {
- "use strict"; // So that |this| in callback can be undefined.
-
- var observer = {
- records: undefined,
- callbackCount: 0,
- reset: function() {
- this.records = undefined;
- this.callbackCount = 0;
- },
- assertNotCalled: function() {
- assertEquals(undefined, this.records);
- assertEquals(0, this.callbackCount);
- },
- assertCalled: function() {
- assertEquals(1, this.callbackCount);
- },
- assertRecordCount: function(count) {
- this.assertCalled();
- assertEquals(count, this.records.length);
- },
- assertCallbackRecords: function(recs) {
- this.assertRecordCount(recs.length);
- for (var i = 0; i < recs.length; i++) {
- if ('name' in recs[i]) recs[i].name = String(recs[i].name);
- print(i, stringifyNoThrow(this.records[i]), stringifyNoThrow(recs[i]));
- assertSame(this.records[i].object, recs[i].object);
- assertEquals('string', typeof recs[i].type);
- assertPropertiesEqual(this.records[i], recs[i]);
- }
- }
- };
-
- observer.callback = function(r) {
- assertEquals(undefined, this);
- assertEquals('object', typeof r);
- assertTrue(r instanceof Array)
- observer.records = r;
- observer.callbackCount++;
- };
-
- observer.reset();
- allObservers.push(observer);
- return observer;
-}
-
-var observer = createObserver();
-assertEquals("function", typeof observer.callback);
-var obj = {};
-
-function frozenFunction() {}
-Object.freeze(frozenFunction);
-var nonFunction = {};
-var changeRecordWithAccessor = { type: 'foo' };
-var recordCreated = false;
-Object.defineProperty(changeRecordWithAccessor, 'name', {
- get: function() {
- recordCreated = true;
- return "bar";
- },
- enumerable: true
-})
-
-
-// Object.observe
-assertThrows(function() { Object.observe("non-object", observer.callback); }, TypeError);
-assertThrows(function() { Object.observe(obj, nonFunction); }, TypeError);
-assertThrows(function() { Object.observe(obj, frozenFunction); }, TypeError);
-assertEquals(obj, Object.observe(obj, observer.callback));
-
-
-// Object.unobserve
-assertThrows(function() { Object.unobserve(4, observer.callback); }, TypeError);
-assertThrows(function() { Object.unobserve(obj, nonFunction); }, TypeError);
-assertEquals(obj, Object.unobserve(obj, observer.callback));
-
-
-// Object.getNotifier
-var notifier = Object.getNotifier(obj);
-assertSame(notifier, Object.getNotifier(obj));
-assertEquals(null, Object.getNotifier(Object.freeze({})));
-assertFalse(notifier.hasOwnProperty('notify'));
-assertEquals([], Object.keys(notifier));
-var notifyDesc = Object.getOwnPropertyDescriptor(notifier.__proto__, 'notify');
-assertTrue(notifyDesc.configurable);
-assertTrue(notifyDesc.writable);
-assertFalse(notifyDesc.enumerable);
-assertThrows(function() { notifier.notify({}); }, TypeError);
-assertThrows(function() { notifier.notify({ type: 4 }); }, TypeError);
-var notify = notifier.notify;
-assertThrows(function() { notify.call(undefined, { type: 'a' }); }, TypeError);
-assertThrows(function() { notify.call(null, { type: 'a' }); }, TypeError);
-assertThrows(function() { notify.call(5, { type: 'a' }); }, TypeError);
-assertThrows(function() { notify.call('hello', { type: 'a' }); }, TypeError);
-assertThrows(function() { notify.call(false, { type: 'a' }); }, TypeError);
-assertThrows(function() { notify.call({}, { type: 'a' }); }, TypeError);
-assertFalse(recordCreated);
-notifier.notify(changeRecordWithAccessor);
-assertFalse(recordCreated); // not observed yet
-
-
-// Object.deliverChangeRecords
-assertThrows(function() { Object.deliverChangeRecords(nonFunction); }, TypeError);
-
-Object.observe(obj, observer.callback);
-
-
-// notify uses to [[CreateOwnProperty]] to create changeRecord;
-reset();
-var protoExpandoAccessed = false;
-Object.defineProperty(Object.prototype, 'protoExpando',
- {
- configurable: true,
- set: function() { protoExpandoAccessed = true; }
- }
-);
-notifier.notify({ type: 'foo', protoExpando: 'val'});
-assertFalse(protoExpandoAccessed);
-delete Object.prototype.protoExpando;
-Object.deliverChangeRecords(observer.callback);
-
-
-// Multiple records are delivered.
-reset();
-notifier.notify({
- type: 'updated',
- name: 'foo',
- expando: 1
-});
-
-notifier.notify({
- object: notifier, // object property is ignored
- type: 'deleted',
- name: 'bar',
- expando2: 'str'
-});
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
- { object: obj, name: 'foo', type: 'updated', expando: 1 },
- { object: obj, name: 'bar', type: 'deleted', expando2: 'str' }
-]);
-
-
-// No delivery takes place if no records are pending
-reset();
-Object.deliverChangeRecords(observer.callback);
-observer.assertNotCalled();
-
-
-// Multiple observation has no effect.
-reset();
-Object.observe(obj, observer.callback);
-Object.observe(obj, observer.callback);
-Object.getNotifier(obj).notify({
- type: 'foo',
-});
-Object.deliverChangeRecords(observer.callback);
-observer.assertCalled();
-
-
-// Observation can be stopped.
-reset();
-Object.unobserve(obj, observer.callback);
-Object.getNotifier(obj).notify({
- type: 'foo',
-});
-Object.deliverChangeRecords(observer.callback);
-observer.assertNotCalled();
-
-
-// Multiple unobservation has no effect
-reset();
-Object.unobserve(obj, observer.callback);
-Object.unobserve(obj, observer.callback);
-Object.getNotifier(obj).notify({
- type: 'foo',
-});
-Object.deliverChangeRecords(observer.callback);
-observer.assertNotCalled();
-
-
-// Re-observation works and only includes changeRecords after of call.
-reset();
-Object.getNotifier(obj).notify({
- type: 'foo',
-});
-Object.observe(obj, observer.callback);
-Object.getNotifier(obj).notify({
- type: 'foo',
-});
-records = undefined;
-Object.deliverChangeRecords(observer.callback);
-observer.assertRecordCount(1);
-
-
-// Observing a continuous stream of changes, while itermittantly unobserving.
-reset();
-Object.observe(obj, observer.callback);
-Object.getNotifier(obj).notify({
- type: 'foo',
- val: 1
-});
-
-Object.unobserve(obj, observer.callback);
-Object.getNotifier(obj).notify({
- type: 'foo',
- val: 2
-});
-
-Object.observe(obj, observer.callback);
-Object.getNotifier(obj).notify({
- type: 'foo',
- val: 3
-});
-
-Object.unobserve(obj, observer.callback);
-Object.getNotifier(obj).notify({
- type: 'foo',
- val: 4
-});
-
-Object.observe(obj, observer.callback);
-Object.getNotifier(obj).notify({
- type: 'foo',
- val: 5
-});
-
-Object.unobserve(obj, observer.callback);
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
- { object: obj, type: 'foo', val: 1 },
- { object: obj, type: 'foo', val: 3 },
- { object: obj, type: 'foo', val: 5 }
-]);
-
-
-// Observing multiple objects; records appear in order.
-reset();
-var obj2 = {};
-var obj3 = {}
-Object.observe(obj, observer.callback);
-Object.observe(obj3, observer.callback);
-Object.observe(obj2, observer.callback);
-Object.getNotifier(obj).notify({
- type: 'foo1',
-});
-Object.getNotifier(obj2).notify({
- type: 'foo2',
-});
-Object.getNotifier(obj3).notify({
- type: 'foo3',
-});
-Object.observe(obj3, observer.callback);
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
- { object: obj, type: 'foo1' },
- { object: obj2, type: 'foo2' },
- { object: obj3, type: 'foo3' }
-]);
-
-
-// Recursive observation.
-var obj = {a: 1};
-var callbackCount = 0;
-function recursiveObserver(r) {
- assertEquals(1, r.length);
- ++callbackCount;
- if (r[0].oldValue < 100) ++obj[r[0].name];
-}
-Object.observe(obj, recursiveObserver);
-++obj.a;
-Object.deliverChangeRecords(recursiveObserver);
-assertEquals(100, callbackCount);
-
-var obj1 = {a: 1};
-var obj2 = {a: 1};
-var recordCount = 0;
-function recursiveObserver2(r) {
- recordCount += r.length;
- if (r[0].oldValue < 100) {
- ++obj1.a;
- ++obj2.a;
- }
-}
-Object.observe(obj1, recursiveObserver2);
-Object.observe(obj2, recursiveObserver2);
-++obj1.a;
-Object.deliverChangeRecords(recursiveObserver2);
-assertEquals(199, recordCount);
-
-
-// Observing named properties.
-reset();
-var obj = {a: 1}
-Object.observe(obj, observer.callback);
-obj.a = 2;
-obj["a"] = 3;
-delete obj.a;
-obj.a = 4;
-obj.a = 4; // ignored
-obj.a = 5;
-Object.defineProperty(obj, "a", {value: 6});
-Object.defineProperty(obj, "a", {writable: false});
-obj.a = 7; // ignored
-Object.defineProperty(obj, "a", {value: 8});
-Object.defineProperty(obj, "a", {value: 7, writable: true});
-Object.defineProperty(obj, "a", {get: function() {}});
-Object.defineProperty(obj, "a", {get: frozenFunction});
-Object.defineProperty(obj, "a", {get: frozenFunction}); // ignored
-Object.defineProperty(obj, "a", {get: frozenFunction, set: frozenFunction});
-Object.defineProperty(obj, "a", {set: frozenFunction}); // ignored
-Object.defineProperty(obj, "a", {get: undefined, set: frozenFunction});
-delete obj.a;
-delete obj.a;
-Object.defineProperty(obj, "a", {get: function() {}, configurable: true});
-Object.defineProperty(obj, "a", {value: 9, writable: true});
-obj.a = 10;
-++obj.a;
-obj.a++;
-obj.a *= 3;
-delete obj.a;
-Object.defineProperty(obj, "a", {value: 11, configurable: true});
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
- { object: obj, name: "a", type: "updated", oldValue: 1 },
- { object: obj, name: "a", type: "updated", oldValue: 2 },
- { object: obj, name: "a", type: "deleted", oldValue: 3 },
- { object: obj, name: "a", type: "new" },
- { object: obj, name: "a", type: "updated", oldValue: 4 },
- { object: obj, name: "a", type: "updated", oldValue: 5 },
- { object: obj, name: "a", type: "reconfigured" },
- { object: obj, name: "a", type: "updated", oldValue: 6 },
- { object: obj, name: "a", type: "reconfigured", oldValue: 8 },
- { object: obj, name: "a", type: "reconfigured", oldValue: 7 },
- { object: obj, name: "a", type: "reconfigured" },
- { object: obj, name: "a", type: "reconfigured" },
- { object: obj, name: "a", type: "reconfigured" },
- { object: obj, name: "a", type: "deleted" },
- { object: obj, name: "a", type: "new" },
- { object: obj, name: "a", type: "reconfigured" },
- { object: obj, name: "a", type: "updated", oldValue: 9 },
- { object: obj, name: "a", type: "updated", oldValue: 10 },
- { object: obj, name: "a", type: "updated", oldValue: 11 },
- { object: obj, name: "a", type: "updated", oldValue: 12 },
- { object: obj, name: "a", type: "deleted", oldValue: 36 },
- { object: obj, name: "a", type: "new" },
-]);
-
-
-// Observing indexed properties.
-reset();
-var obj = {'1': 1}
-Object.observe(obj, observer.callback);
-obj[1] = 2;
-obj[1] = 3;
-delete obj[1];
-obj[1] = 4;
-obj[1] = 4; // ignored
-obj[1] = 5;
-Object.defineProperty(obj, "1", {value: 6});
-Object.defineProperty(obj, "1", {writable: false});
-obj[1] = 7; // ignored
-Object.defineProperty(obj, "1", {value: 8});
-Object.defineProperty(obj, "1", {value: 7, writable: true});
-Object.defineProperty(obj, "1", {get: function() {}});
-Object.defineProperty(obj, "1", {get: frozenFunction});
-Object.defineProperty(obj, "1", {get: frozenFunction}); // ignored
-Object.defineProperty(obj, "1", {get: frozenFunction, set: frozenFunction});
-Object.defineProperty(obj, "1", {set: frozenFunction}); // ignored
-Object.defineProperty(obj, "1", {get: undefined, set: frozenFunction});
-delete obj[1];
-delete obj[1];
-Object.defineProperty(obj, "1", {get: function() {}, configurable: true});
-Object.defineProperty(obj, "1", {value: 9, writable: true});
-obj[1] = 10;
-++obj[1];
-obj[1]++;
-obj[1] *= 3;
-delete obj[1];
-Object.defineProperty(obj, "1", {value: 11, configurable: true});
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
- { object: obj, name: "1", type: "updated", oldValue: 1 },
- { object: obj, name: "1", type: "updated", oldValue: 2 },
- { object: obj, name: "1", type: "deleted", oldValue: 3 },
- { object: obj, name: "1", type: "new" },
- { object: obj, name: "1", type: "updated", oldValue: 4 },
- { object: obj, name: "1", type: "updated", oldValue: 5 },
- { object: obj, name: "1", type: "reconfigured" },
- { object: obj, name: "1", type: "updated", oldValue: 6 },
- { object: obj, name: "1", type: "reconfigured", oldValue: 8 },
- { object: obj, name: "1", type: "reconfigured", oldValue: 7 },
- { object: obj, name: "1", type: "reconfigured" },
- { object: obj, name: "1", type: "reconfigured" },
- { object: obj, name: "1", type: "reconfigured" },
- { object: obj, name: "1", type: "deleted" },
- { object: obj, name: "1", type: "new" },
- { object: obj, name: "1", type: "reconfigured" },
- { object: obj, name: "1", type: "updated", oldValue: 9 },
- { object: obj, name: "1", type: "updated", oldValue: 10 },
- { object: obj, name: "1", type: "updated", oldValue: 11 },
- { object: obj, name: "1", type: "updated", oldValue: 12 },
- { object: obj, name: "1", type: "deleted", oldValue: 36 },
- { object: obj, name: "1", type: "new" },
-]);
-
-
-// Test all kinds of objects generically.
-function TestObserveConfigurable(obj, prop) {
- reset();
- obj[prop] = 1;
- Object.observe(obj, observer.callback);
- obj[prop] = 2;
- obj[prop] = 3;
- delete obj[prop];
- obj[prop] = 4;
- obj[prop] = 4; // ignored
- obj[prop] = 5;
- Object.defineProperty(obj, prop, {value: 6});
- Object.defineProperty(obj, prop, {writable: false});
- obj[prop] = 7; // ignored
- Object.defineProperty(obj, prop, {value: 8});
- Object.defineProperty(obj, prop, {value: 7, writable: true});
- Object.defineProperty(obj, prop, {get: function() {}});
- Object.defineProperty(obj, prop, {get: frozenFunction});
- Object.defineProperty(obj, prop, {get: frozenFunction}); // ignored
- Object.defineProperty(obj, prop, {get: frozenFunction, set: frozenFunction});
- Object.defineProperty(obj, prop, {set: frozenFunction}); // ignored
- Object.defineProperty(obj, prop, {get: undefined, set: frozenFunction});
- obj.__defineSetter__(prop, frozenFunction); // ignored
- obj.__defineSetter__(prop, function() {});
- obj.__defineGetter__(prop, function() {});
- delete obj[prop];
- delete obj[prop]; // ignored
- obj.__defineGetter__(prop, function() {});
- delete obj[prop];
- Object.defineProperty(obj, prop, {get: function() {}, configurable: true});
- Object.defineProperty(obj, prop, {value: 9, writable: true});
- obj[prop] = 10;
- ++obj[prop];
- obj[prop]++;
- obj[prop] *= 3;
- delete obj[prop];
- Object.defineProperty(obj, prop, {value: 11, configurable: true});
- Object.deliverChangeRecords(observer.callback);
- observer.assertCallbackRecords([
- { object: obj, name: prop, type: "updated", oldValue: 1 },
- { object: obj, name: prop, type: "updated", oldValue: 2 },
- { object: obj, name: prop, type: "deleted", oldValue: 3 },
- { object: obj, name: prop, type: "new" },
- { object: obj, name: prop, type: "updated", oldValue: 4 },
- { object: obj, name: prop, type: "updated", oldValue: 5 },
- { object: obj, name: prop, type: "reconfigured" },
- { object: obj, name: prop, type: "updated", oldValue: 6 },
- { object: obj, name: prop, type: "reconfigured", oldValue: 8 },
- { object: obj, name: prop, type: "reconfigured", oldValue: 7 },
- { object: obj, name: prop, type: "reconfigured" },
- { object: obj, name: prop, type: "reconfigured" },
- { object: obj, name: prop, type: "reconfigured" },
- { object: obj, name: prop, type: "reconfigured" },
- { object: obj, name: prop, type: "reconfigured" },
- { object: obj, name: prop, type: "deleted" },
- { object: obj, name: prop, type: "new" },
- { object: obj, name: prop, type: "deleted" },
- { object: obj, name: prop, type: "new" },
- { object: obj, name: prop, type: "reconfigured" },
- { object: obj, name: prop, type: "updated", oldValue: 9 },
- { object: obj, name: prop, type: "updated", oldValue: 10 },
- { object: obj, name: prop, type: "updated", oldValue: 11 },
- { object: obj, name: prop, type: "updated", oldValue: 12 },
- { object: obj, name: prop, type: "deleted", oldValue: 36 },
- { object: obj, name: prop, type: "new" },
- ]);
- Object.unobserve(obj, observer.callback);
- delete obj[prop];
-}
-
-function TestObserveNonConfigurable(obj, prop, desc) {
- reset();
- obj[prop] = 1;
- Object.observe(obj, observer.callback);
- obj[prop] = 4;
- obj[prop] = 4; // ignored
- obj[prop] = 5;
- Object.defineProperty(obj, prop, {value: 6});
- Object.defineProperty(obj, prop, {value: 6}); // ignored
- Object.defineProperty(obj, prop, {value: 7});
- Object.defineProperty(obj, prop, {enumerable: desc.enumerable}); // ignored
- Object.defineProperty(obj, prop, {writable: false});
- obj[prop] = 7; // ignored
- Object.deliverChangeRecords(observer.callback);
- observer.assertCallbackRecords([
- { object: obj, name: prop, type: "updated", oldValue: 1 },
- { object: obj, name: prop, type: "updated", oldValue: 4 },
- { object: obj, name: prop, type: "updated", oldValue: 5 },
- { object: obj, name: prop, type: "updated", oldValue: 6 },
- { object: obj, name: prop, type: "reconfigured" },
- ]);
- Object.unobserve(obj, observer.callback);
-}
-
-function createProxy(create, x) {
- var handler = {
- getPropertyDescriptor: function(k) {
- for (var o = this.target; o; o = Object.getPrototypeOf(o)) {
- var desc = Object.getOwnPropertyDescriptor(o, k);
- if (desc) return desc;
- }
- return undefined;
- },
- getOwnPropertyDescriptor: function(k) {
- return Object.getOwnPropertyDescriptor(this.target, k);
- },
- defineProperty: function(k, desc) {
- var x = Object.defineProperty(this.target, k, desc);
- Object.deliverChangeRecords(this.callback);
- return x;
- },
- delete: function(k) {
- var x = delete this.target[k];
- Object.deliverChangeRecords(this.callback);
- return x;
- },
- getPropertyNames: function() {
- return Object.getOwnPropertyNames(this.target);
- },
- target: {isProxy: true},
- callback: function(changeRecords) {
- print("callback", stringifyNoThrow(handler.proxy), stringifyNoThrow(got));
- for (var i in changeRecords) {
- var got = changeRecords[i];
- var change = {object: handler.proxy, name: got.name, type: got.type};
- if ("oldValue" in got) change.oldValue = got.oldValue;
- Object.getNotifier(handler.proxy).notify(change);
- }
- },
- };
- Object.observe(handler.target, handler.callback);
- return handler.proxy = create(handler, x);
-}
-
-var objects = [
- {},
- [],
- this, // global object
- function(){},
- (function(){ return arguments })(),
- (function(){ "use strict"; return arguments })(),
- Object(1), Object(true), Object("bla"),
- new Date(),
- Object, Function, Date, RegExp,
- new Set, new Map, new WeakMap,
- new ArrayBuffer(10), new Int32Array(5),
- createProxy(Proxy.create, null),
- createProxy(Proxy.createFunction, function(){}),
-];
-var properties = ["a", "1", 1, "length", "prototype", "name", "caller"];
-
-// Cases that yield non-standard results.
-function blacklisted(obj, prop) {
- return (obj instanceof Int32Array && prop == 1) ||
- (obj instanceof Int32Array && prop === "length") ||
- (obj instanceof ArrayBuffer && prop == 1)
-}
-
-for (var i in objects) for (var j in properties) {
- var obj = objects[i];
- var prop = properties[j];
- if (blacklisted(obj, prop)) continue;
- var desc = Object.getOwnPropertyDescriptor(obj, prop);
- print("***", typeof obj, stringifyNoThrow(obj), prop);
- if (!desc || desc.configurable)
- TestObserveConfigurable(obj, prop);
- else if (desc.writable)
- TestObserveNonConfigurable(obj, prop, desc);
-}
-
-
-// Observing array length (including truncation)
-reset();
-var arr = ['a', 'b', 'c', 'd'];
-var arr2 = ['alpha', 'beta'];
-var arr3 = ['hello'];
-arr3[2] = 'goodbye';
-arr3.length = 6;
-var slow_arr = new Array(1000000000);
-slow_arr[500000000] = 'hello';
-Object.defineProperty(arr, '0', {configurable: false});
-Object.defineProperty(arr, '2', {get: function(){}});
-Object.defineProperty(arr2, '0', {get: function(){}, configurable: false});
-Object.observe(arr, observer.callback);
-Object.observe(arr2, observer.callback);
-Object.observe(arr3, observer.callback);
-Object.observe(slow_arr, observer.callback);
-arr.length = 2;
-arr.length = 0;
-arr.length = 10;
-Object.defineProperty(arr, 'length', {writable: false});
-arr2.length = 0;
-arr2.length = 1; // no change expected
-Object.defineProperty(arr2, 'length', {value: 1, writable: false});
-arr3.length = 0;
-++arr3.length;
-arr3.length++;
-arr3.length /= 2;
-Object.defineProperty(arr3, 'length', {value: 5});
-Object.defineProperty(arr3, 'length', {value: 10, writable: false});
-slow_arr.length = 100;
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
- { object: arr, name: '3', type: 'deleted', oldValue: 'd' },
- { object: arr, name: '2', type: 'deleted' },
- { object: arr, name: 'length', type: 'updated', oldValue: 4 },
- { object: arr, name: '1', type: 'deleted', oldValue: 'b' },
- { object: arr, name: 'length', type: 'updated', oldValue: 2 },
- { object: arr, name: 'length', type: 'updated', oldValue: 1 },
- { object: arr, name: 'length', type: 'reconfigured' },
- { object: arr2, name: '1', type: 'deleted', oldValue: 'beta' },
- { object: arr2, name: 'length', type: 'updated', oldValue: 2 },
- { object: arr2, name: 'length', type: 'reconfigured', oldValue: 1 },
- { object: arr3, name: '2', type: 'deleted', oldValue: 'goodbye' },
- { object: arr3, name: '0', type: 'deleted', oldValue: 'hello' },
- { object: arr3, name: 'length', type: 'updated', oldValue: 6 },
- { object: arr3, name: 'length', type: 'updated', oldValue: 0 },
- { object: arr3, name: 'length', type: 'updated', oldValue: 1 },
- { object: arr3, name: 'length', type: 'updated', oldValue: 2 },
- { object: arr3, name: 'length', type: 'updated', oldValue: 1 },
- { object: arr3, name: 'length', type: 'reconfigured', oldValue: 5 },
- { object: slow_arr, name: '500000000', type: 'deleted', oldValue: 'hello' },
- { object: slow_arr, name: 'length', type: 'updated', oldValue: 1000000000 },
-]);
-
-
-// Assignments in loops (checking different IC states).
-reset();
-var obj = {};
-Object.observe(obj, observer.callback);
-for (var i = 0; i < 5; i++) {
- obj["a" + i] = i;
-}
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
- { object: obj, name: "a0", type: "new" },
- { object: obj, name: "a1", type: "new" },
- { object: obj, name: "a2", type: "new" },
- { object: obj, name: "a3", type: "new" },
- { object: obj, name: "a4", type: "new" },
-]);
-
-reset();
-var obj = {};
-Object.observe(obj, observer.callback);
-for (var i = 0; i < 5; i++) {
- obj[i] = i;
-}
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
- { object: obj, name: "0", type: "new" },
- { object: obj, name: "1", type: "new" },
- { object: obj, name: "2", type: "new" },
- { object: obj, name: "3", type: "new" },
- { object: obj, name: "4", type: "new" },
-]);
-
-
-// Adding elements past the end of an array should notify on length
-reset();
-var arr = [1, 2, 3];
-Object.observe(arr, observer.callback);
-arr[3] = 10;
-arr[100] = 20;
-Object.defineProperty(arr, '200', {value: 7});
-Object.defineProperty(arr, '400', {get: function(){}});
-arr[50] = 30; // no length change expected
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
- { object: arr, name: '3', type: 'new' },
- { object: arr, name: 'length', type: 'updated', oldValue: 3 },
- { object: arr, name: '100', type: 'new' },
- { object: arr, name: 'length', type: 'updated', oldValue: 4 },
- { object: arr, name: '200', type: 'new' },
- { object: arr, name: 'length', type: 'updated', oldValue: 101 },
- { object: arr, name: '400', type: 'new' },
- { object: arr, name: 'length', type: 'updated', oldValue: 201 },
- { object: arr, name: '50', type: 'new' },
-]);
-
-
-// Tests for array methods, first on arrays and then on plain objects
-//
-// === ARRAYS ===
-//
-// Push
-reset();
-var array = [1, 2];
-Object.observe(array, observer.callback);
-array.push(3, 4);
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
- { object: array, name: '2', type: 'new' },
- { object: array, name: 'length', type: 'updated', oldValue: 2 },
- { object: array, name: '3', type: 'new' },
- { object: array, name: 'length', type: 'updated', oldValue: 3 },
-]);
-
-// Pop
-reset();
-var array = [1, 2];
-Object.observe(array, observer.callback);
-array.pop();
-array.pop();
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
- { object: array, name: '1', type: 'deleted', oldValue: 2 },
- { object: array, name: 'length', type: 'updated', oldValue: 2 },
- { object: array, name: '0', type: 'deleted', oldValue: 1 },
- { object: array, name: 'length', type: 'updated', oldValue: 1 },
-]);
-
-// Shift
-reset();
-var array = [1, 2];
-Object.observe(array, observer.callback);
-array.shift();
-array.shift();
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
- { object: array, name: '0', type: 'updated', oldValue: 1 },
- { object: array, name: '1', type: 'deleted', oldValue: 2 },
- { object: array, name: 'length', type: 'updated', oldValue: 2 },
- { object: array, name: '0', type: 'deleted', oldValue: 2 },
- { object: array, name: 'length', type: 'updated', oldValue: 1 },
-]);
-
-// Unshift
-reset();
-var array = [1, 2];
-Object.observe(array, observer.callback);
-array.unshift(3, 4);
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
- { object: array, name: '3', type: 'new' },
- { object: array, name: 'length', type: 'updated', oldValue: 2 },
- { object: array, name: '2', type: 'new' },
- { object: array, name: '0', type: 'updated', oldValue: 1 },
- { object: array, name: '1', type: 'updated', oldValue: 2 },
-]);
-
-// Splice
-reset();
-var array = [1, 2, 3];
-Object.observe(array, observer.callback);
-array.splice(1, 1, 4, 5);
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
- { object: array, name: '3', type: 'new' },
- { object: array, name: 'length', type: 'updated', oldValue: 3 },
- { object: array, name: '1', type: 'updated', oldValue: 2 },
- { object: array, name: '2', type: 'updated', oldValue: 3 },
-]);
-
-
-//
-// === PLAIN OBJECTS ===
-//
-// Push
-reset()
-var array = {0: 1, 1: 2, length: 2}
-Object.observe(array, observer.callback);
-Array.prototype.push.call(array, 3, 4);
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
- { object: array, name: '2', type: 'new' },
- { object: array, name: '3', type: 'new' },
- { object: array, name: 'length', type: 'updated', oldValue: 2 },
-]);
-
-// Pop
-reset()
-var array = {0: 1, 1: 2, length: 2};
-Object.observe(array, observer.callback);
-Array.prototype.pop.call(array);
-Array.prototype.pop.call(array);
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
- { object: array, name: '1', type: 'deleted', oldValue: 2 },
- { object: array, name: 'length', type: 'updated', oldValue: 2 },
- { object: array, name: '0', type: 'deleted', oldValue: 1 },
- { object: array, name: 'length', type: 'updated', oldValue: 1 },
-]);
-
-// Shift
-reset()
-var array = {0: 1, 1: 2, length: 2};
-Object.observe(array, observer.callback);
-Array.prototype.shift.call(array);
-Array.prototype.shift.call(array);
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
- { object: array, name: '0', type: 'updated', oldValue: 1 },
- { object: array, name: '1', type: 'deleted', oldValue: 2 },
- { object: array, name: 'length', type: 'updated', oldValue: 2 },
- { object: array, name: '0', type: 'deleted', oldValue: 2 },
- { object: array, name: 'length', type: 'updated', oldValue: 1 },
-]);
-
-// Unshift
-reset()
-var array = {0: 1, 1: 2, length: 2};
-Object.observe(array, observer.callback);
-Array.prototype.unshift.call(array, 3, 4);
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
- { object: array, name: '3', type: 'new' },
- { object: array, name: '2', type: 'new' },
- { object: array, name: '0', type: 'updated', oldValue: 1 },
- { object: array, name: '1', type: 'updated', oldValue: 2 },
- { object: array, name: 'length', type: 'updated', oldValue: 2 },
-]);
-
-// Splice
-reset()
-var array = {0: 1, 1: 2, 2: 3, length: 3};
-Object.observe(array, observer.callback);
-Array.prototype.splice.call(array, 1, 1, 4, 5);
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
- { object: array, name: '3', type: 'new' },
- { object: array, name: '1', type: 'updated', oldValue: 2 },
- { object: array, name: '2', type: 'updated', oldValue: 3 },
- { object: array, name: 'length', type: 'updated', oldValue: 3 },
-]);
-
-// Exercise StoreIC_ArrayLength
-reset();
-var dummy = {};
-Object.observe(dummy, observer.callback);
-Object.unobserve(dummy, observer.callback);
-var array = [0];
-Object.observe(array, observer.callback);
-array.splice(0, 1);
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
- { object: array, name: '0', type: 'deleted', oldValue: 0 },
- { object: array, name: 'length', type: 'updated', oldValue: 1},
-]);
-
-
-// __proto__
-reset();
-var obj = {};
-Object.observe(obj, observer.callback);
-var p = {foo: 'yes'};
-var q = {bar: 'no'};
-obj.__proto__ = p;
-obj.__proto__ = p; // ignored
-obj.__proto__ = null;
-obj.__proto__ = q; // the __proto__ accessor is gone
-// TODO(adamk): Add tests for objects with hidden prototypes
-// once we support observing the global object.
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
- { object: obj, name: '__proto__', type: 'prototype',
- oldValue: Object.prototype },
- { object: obj, name: '__proto__', type: 'prototype', oldValue: p },
- { object: obj, name: '__proto__', type: 'new' },
-]);
-
-
-// Function.prototype
-reset();
-var fun = function(){};
-Object.observe(fun, observer.callback);
-var myproto = {foo: 'bar'};
-fun.prototype = myproto;
-fun.prototype = 7;
-fun.prototype = 7; // ignored
-Object.defineProperty(fun, 'prototype', {value: 8});
-Object.deliverChangeRecords(observer.callback);
-observer.assertRecordCount(3);
-// Manually examine the first record in order to test
-// lazy creation of oldValue
-assertSame(fun, observer.records[0].object);
-assertEquals('prototype', observer.records[0].name);
-assertEquals('updated', observer.records[0].type);
-// The only existing reference to the oldValue object is in this
-// record, so to test that lazy creation happened correctly
-// we compare its constructor to our function (one of the invariants
-// ensured when creating an object via AllocateFunctionPrototype).
-assertSame(fun, observer.records[0].oldValue.constructor);
-observer.records.splice(0, 1);
-observer.assertCallbackRecords([
- { object: fun, name: 'prototype', type: 'updated', oldValue: myproto },
- { object: fun, name: 'prototype', type: 'updated', oldValue: 7 },
-]);
-
-// Function.prototype should not be observable except on the object itself
-reset();
-var fun = function(){};
-var obj = { __proto__: fun };
-Object.observe(obj, observer.callback);
-obj.prototype = 7;
-Object.deliverChangeRecords(observer.callback);
-observer.assertNotCalled();
-
-
-// Check that changes in observation status are detected in all IC states and
-// in optimized code, especially in cases usually using fast elements.
-var mutation = [
- "a[i] = v",
- "a[i] ? ++a[i] : a[i] = v",
- "a[i] ? a[i]++ : a[i] = v",
- "a[i] ? a[i] += 1 : a[i] = v",
- "a[i] ? a[i] -= -1 : a[i] = v",
-];
-
-var props = [1, "1", "a"];
-
-function TestFastElements(prop, mutation, prepopulate, polymorphic, optimize) {
- var setElement = eval(
- "(function setElement(a, i, v) { " + mutation + "; " +
- "/* " + [].join.call(arguments, " ") + " */" +
- "})"
- );
- print("TestFastElements:", setElement);
-
- var arr = prepopulate ? [1, 2, 3, 4, 5] : [0];
- if (prepopulate) arr[prop] = 2; // for non-element case
- setElement(arr, prop, 3);
- setElement(arr, prop, 4);
- if (polymorphic) setElement(["M", "i", "l", "n", "e", "r"], 0, "m");
- if (optimize) %OptimizeFunctionOnNextCall(setElement);
- setElement(arr, prop, 5);
-
- reset();
- Object.observe(arr, observer.callback);
- setElement(arr, prop, 989898);
- Object.deliverChangeRecords(observer.callback);
- observer.assertCallbackRecords([
- { object: arr, name: "" + prop, type: 'updated', oldValue: 5 }
- ]);
-}
-
-for (var b1 = 0; b1 < 2; ++b1)
- for (var b2 = 0; b2 < 2; ++b2)
- for (var b3 = 0; b3 < 2; ++b3)
- for (var i in props)
- for (var j in mutation)
- TestFastElements(props[i], mutation[j], b1 != 0, b2 != 0, b3 != 0);
-
-
-var mutation = [
- "a.length = v",
- "a.length += newSize - oldSize",
- "a.length -= oldSize - newSize",
-];
-
-var mutationByIncr = [
- "++a.length",
- "a.length++",
-];
-
-function TestFastElementsLength(
- mutation, polymorphic, optimize, oldSize, newSize) {
- var setLength = eval(
- "(function setLength(a, v) { " + mutation + "; " +
- "/* " + [].join.call(arguments, " ") + " */"
- + "})"
- );
- print("TestFastElementsLength:", setLength);
-
- function array(n) {
- var arr = new Array(n);
- for (var i = 0; i < n; ++i) arr[i] = i;
- return arr;
- }
-
- setLength(array(oldSize), newSize);
- setLength(array(oldSize), newSize);
- if (polymorphic) setLength(array(oldSize).map(isNaN), newSize);
- if (optimize) %OptimizeFunctionOnNextCall(setLength);
- setLength(array(oldSize), newSize);
-
- reset();
- var arr = array(oldSize);
- Object.observe(arr, observer.callback);
- setLength(arr, newSize);
- Object.deliverChangeRecords(observer.callback);
- if (oldSize === newSize) {
- observer.assertNotCalled();
- } else {
- var count = oldSize > newSize ? oldSize - newSize : 0;
- observer.assertRecordCount(count + 1);
- var lengthRecord = observer.records[count];
- assertSame(arr, lengthRecord.object);
- assertEquals('length', lengthRecord.name);
- assertEquals('updated', lengthRecord.type);
- assertSame(oldSize, lengthRecord.oldValue);
- }
-}
-
-for (var b1 = 0; b1 < 2; ++b1)
- for (var b2 = 0; b2 < 2; ++b2)
- for (var n1 = 0; n1 < 3; ++n1)
- for (var n2 = 0; n2 < 3; ++n2)
- for (var i in mutation)
- TestFastElementsLength(mutation[i], b1 != 0, b2 != 0, 20*n1, 20*n2);
-
-for (var b1 = 0; b1 < 2; ++b1)
- for (var b2 = 0; b2 < 2; ++b2)
- for (var n = 0; n < 3; ++n)
- for (var i in mutationByIncr)
- TestFastElementsLength(mutationByIncr[i], b1 != 0, b2 != 0, 7*n, 7*n+1);