зеркало из https://github.com/mozilla/gecko-dev.git
Bug 978279 - Refactor proxy jit-tests and add tests to account for revocation. (r=jorendorff)
--HG-- rename : js/src/tests/ecma_6/Proxy/proxy-isExtensible.js => js/src/jit-test/tests/proxy/testDirectProxyIsExtensible1.js
This commit is contained in:
Родитель
9db4e68792
Коммит
b80dee55dd
|
@ -2,4 +2,5 @@
|
|||
var target = function (x, y) {
|
||||
return x + y;
|
||||
}
|
||||
assertEq(Proxy(target, {})(2, 3), 5);
|
||||
for (let p of [new Proxy(target, {}), Proxy.revocable(target, {}).proxy])
|
||||
assertEq(p(2, 3), 5);
|
||||
|
|
|
@ -15,4 +15,5 @@ var handler = {
|
|||
assertEq(args[1], 3);
|
||||
}
|
||||
}
|
||||
new Proxy(target, handler).call(receiver, 2, 3);
|
||||
for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy])
|
||||
p.call(receiver, 2, 3);
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
// Return the trap result
|
||||
assertEq(new Proxy(function (x, y) {
|
||||
// Man, wouldn't haskell's "uninfix" be cleaner? (+)
|
||||
function justAdd(x, y) {
|
||||
return x + y;
|
||||
}, {
|
||||
apply: function (target, receiver, args) {
|
||||
return args[0] * args[1];
|
||||
}
|
||||
})(2, 3), 6);
|
||||
}
|
||||
|
||||
var handler = { apply : function (target, receiver, args) { return args[0] * args[1]; } };
|
||||
|
||||
for (let p of [new Proxy(justAdd, handler), Proxy.revocable(justAdd, handler).proxy])
|
||||
assertEq(p(2,3), 6);
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
load(libdir + "asserts.js");
|
||||
// Revoked proxies should throw before calling the handler
|
||||
|
||||
var called = false;
|
||||
var target = function () { };
|
||||
var handler = { apply: () => called = true };
|
||||
var holder = Proxy.revocable(target, handler);
|
||||
|
||||
holder.revoke();
|
||||
|
||||
assertThrowsInstanceOf(() => holder.proxy(), TypeError);
|
||||
assertEq(called, false);
|
|
@ -2,6 +2,9 @@
|
|||
var target = function (x, y) {
|
||||
this.foo = x + y;
|
||||
}
|
||||
var obj = new (Proxy(target, {}))(2, 3);
|
||||
assertEq(obj.foo, 5);
|
||||
assertEq(Object.getPrototypeOf(obj), target.prototype);
|
||||
|
||||
for (let p of [new Proxy(target, {}), Proxy.revocable(target, {}).proxy]) {
|
||||
var obj = new p(2, 3);
|
||||
assertEq(obj.foo, 5);
|
||||
assertEq(Object.getPrototypeOf(obj), target.prototype);
|
||||
}
|
||||
|
|
|
@ -15,4 +15,5 @@ var handler = {
|
|||
assertEq(args[1], 3);
|
||||
}
|
||||
}
|
||||
assertThrowsInstanceOf(function () {new (new Proxy(target, handler))(2, 3)}, TypeError);
|
||||
for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy])
|
||||
assertThrowsInstanceOf(function () {new p(2, 3)}, TypeError);
|
||||
|
|
|
@ -1,15 +1,11 @@
|
|||
// Return the trap result
|
||||
var proxy = (new Proxy(function (x, y) {
|
||||
this.foo = x + y;
|
||||
}, {
|
||||
construct: function (target, args) {
|
||||
return {
|
||||
foo: args[0] * args[1]
|
||||
};
|
||||
}
|
||||
}));
|
||||
var obj1 = new proxy(2, 3);
|
||||
assertEq(obj1.foo, 6);
|
||||
obj1.bar = proxy;
|
||||
var obj2 = new obj1.bar(2, 3);
|
||||
assertEq(obj2.foo, 6);
|
||||
function setFoo(x,y) { this.foo = x + y; }
|
||||
var handler = { construct: function (target, args) { return { foo : args[0] * args[1]}; } }
|
||||
|
||||
for (let proxy of [new Proxy(setFoo, handler), Proxy.revocable(setFoo, handler).proxy]) {
|
||||
var obj1 = new proxy(2, 3);
|
||||
assertEq(obj1.foo, 6);
|
||||
obj1.bar = proxy;
|
||||
var obj2 = new obj1.bar(2, 3);
|
||||
assertEq(obj2.foo, 6);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
load(libdir + "asserts.js");
|
||||
// Revoked proxies should throw before calling the handler
|
||||
|
||||
var called = false;
|
||||
var target = function () { };
|
||||
var handler = { construct: () => called = true };
|
||||
var holder = Proxy.revocable(target, handler);
|
||||
|
||||
holder.revoke();
|
||||
|
||||
assertThrowsInstanceOf(() => new holder.proxy(), TypeError);
|
||||
assertEq(called, false);
|
|
@ -1,7 +1,8 @@
|
|||
// Forward to the target if the trap is not defined
|
||||
var target = {};
|
||||
for (var key of ['foo', Symbol("quux")]) {
|
||||
Object.defineProperty(Proxy(target, {}), key, {
|
||||
|
||||
var target;
|
||||
function testProxy(p, key) {
|
||||
Object.defineProperty(p, key, {
|
||||
value: 'bar',
|
||||
writable: true,
|
||||
enumerable: false,
|
||||
|
@ -13,3 +14,10 @@ for (var key of ['foo', Symbol("quux")]) {
|
|||
assertEq(desc.enumerable, false);
|
||||
assertEq(desc.configurable, true);
|
||||
}
|
||||
|
||||
for (var key of ['foo', Symbol("quux")]) {
|
||||
target = {};
|
||||
testProxy(new Proxy(target, {}), key);
|
||||
target = {};
|
||||
testProxy(Proxy.revocable(target, {}).proxy, key);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* as the third argument.
|
||||
*/
|
||||
var target = {};
|
||||
var log = [];
|
||||
var handler = {
|
||||
defineProperty: function (target1, key, desc1) {
|
||||
assertEq(this, handler);
|
||||
|
@ -15,9 +14,8 @@ var handler = {
|
|||
assertEq(desc1.writable, true);
|
||||
assertEq(desc1.enumerable, false);
|
||||
assertEq(desc1.configurable, true);
|
||||
called = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
var desc = {
|
||||
value: 'bar',
|
||||
writable: true,
|
||||
|
@ -25,14 +23,11 @@ var desc = {
|
|||
configurable: true
|
||||
};
|
||||
|
||||
var p = new Proxy(target, handler);
|
||||
Object.defineProperty(p, 'foo', desc);
|
||||
Object.defineProperty(p, Symbol.for('quux'), desc);
|
||||
assertEq(log.length, 2);
|
||||
assertEq(log[0], 'foo');
|
||||
assertEq(log[1], Symbol.for('quux'));
|
||||
assertEq(Object.isExtensible(target), true);
|
||||
assertEq(Object.isExtensible(p), true);
|
||||
Object.preventExtensions(target);
|
||||
assertEq(Object.isExtensible(target), false);
|
||||
assertEq(Object.isExtensible(p), false);
|
||||
for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy]) {
|
||||
var log = [];
|
||||
Object.defineProperty(p, 'foo', desc);
|
||||
Object.defineProperty(p, Symbol.for('quux'), desc);
|
||||
assertEq(log.length, 2);
|
||||
assertEq(log[0], 'foo');
|
||||
assertEq(log[1], Symbol.for('quux'));
|
||||
}
|
||||
|
|
|
@ -6,12 +6,11 @@ load(libdir + "asserts.js");
|
|||
*/
|
||||
var target = {};
|
||||
Object.preventExtensions(target);
|
||||
assertThrowsInstanceOf(function () {
|
||||
Object.defineProperty(new Proxy(target, {
|
||||
defineProperty: function (target, name, desc) {
|
||||
return true;
|
||||
}
|
||||
}), 'foo', {
|
||||
configurable: true
|
||||
});
|
||||
}, TypeError);
|
||||
|
||||
var handler = { defineProperty: function (target, name, desc) { return true; } };
|
||||
|
||||
for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy]) {
|
||||
assertThrowsInstanceOf(function () {
|
||||
Object.defineProperty(p, 'foo', { configurable: true });
|
||||
}, TypeError);
|
||||
}
|
||||
|
|
|
@ -4,12 +4,9 @@ load(libdir + "asserts.js");
|
|||
* Throw a TypeError if the trap defines a non-configurable property that does
|
||||
* not exist on the target
|
||||
*/
|
||||
assertThrowsInstanceOf(function () {
|
||||
Object.defineProperty(new Proxy({}, {
|
||||
defineProperty: function (target, name, desc) {
|
||||
return true;
|
||||
}
|
||||
}), 'foo', {
|
||||
configurable: false
|
||||
});
|
||||
}, TypeError);
|
||||
var handler = { defineProperty: function (target, name, desc) { return true; } };
|
||||
for (let p of [new Proxy({}, handler), Proxy.revocable({}, handler).proxy]) {
|
||||
assertThrowsInstanceOf(function () {
|
||||
Object.defineProperty(p, 'foo', { configurable: false });
|
||||
}, TypeError);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
load(libdir + "asserts.js");
|
||||
// Revoked proxies should throw before calling the handler
|
||||
|
||||
var called = false;
|
||||
var target = {};
|
||||
var handler = { defineProperty: () => called = true };
|
||||
var holder = Proxy.revocable(target, handler);
|
||||
|
||||
holder.revoke();
|
||||
|
||||
var p = holder.proxy;
|
||||
assertThrowsInstanceOf(() => Object.defineProperty(p, 'foo', {}), TypeError);
|
||||
assertEq(called, false);
|
|
@ -1,13 +1,12 @@
|
|||
// Forward to the target if the trap is not defined
|
||||
assertEq(Proxy({
|
||||
foo: 'bar'
|
||||
}, {}).foo, 'bar');
|
||||
|
||||
assertEq(Proxy({
|
||||
foo: 'bar'
|
||||
}, {})['foo'], 'bar');
|
||||
var target = { foo: 'bar' };
|
||||
for (let p of [new Proxy(target, {}), Proxy.revocable(target, {}).proxy]) {
|
||||
assertEq(p.foo, 'bar');
|
||||
assertEq(p['foo'], 'bar');
|
||||
}
|
||||
|
||||
var s = Symbol.for("moon");
|
||||
var obj = {};
|
||||
obj[s] = "dust";
|
||||
assertEq(Proxy(obj, {})[s], "dust");
|
||||
for (let p of [new Proxy(obj, {}), Proxy.revocable(obj, {}).proxy])
|
||||
assertEq(p[s], "dust");
|
||||
|
|
|
@ -5,17 +5,18 @@
|
|||
*/
|
||||
var target = {};
|
||||
for (var key of ['foo', Symbol.iterator]) {
|
||||
var called = false;
|
||||
var handler = {
|
||||
get: function (target1, name, receiver) {
|
||||
assertEq(this, handler);
|
||||
assertEq(target1, target);
|
||||
assertEq(name, key);
|
||||
assertEq(receiver, proxy);
|
||||
called = true;
|
||||
}
|
||||
};
|
||||
var proxy = new Proxy(target, handler);
|
||||
assertEq(proxy[key], undefined);
|
||||
assertEq(called, true);
|
||||
handler = {};
|
||||
for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy]) {
|
||||
handler.get =
|
||||
function (target1, name, receiver) {
|
||||
assertEq(this, handler);
|
||||
assertEq(target1, target);
|
||||
assertEq(name, key);
|
||||
assertEq(receiver, p);
|
||||
called = true;
|
||||
};
|
||||
var called = false;
|
||||
assertEq(p[key], undefined);
|
||||
assertEq(called, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,15 @@
|
|||
load(libdir + "asserts.js");
|
||||
|
||||
function testProxy(handlerReturn, prop, shouldThrow) {
|
||||
var handler = { get: function () { return handlerReturn; } };
|
||||
for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy]) {
|
||||
if (shouldThrow)
|
||||
assertThrowsInstanceOf(function () { return p[prop]; }, TypeError);
|
||||
else
|
||||
assertEq(p[prop], handlerReturn);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Throw a TypeError if the trap reports a different value for a non-writable,
|
||||
* non-configurable property
|
||||
|
@ -10,25 +20,12 @@ Object.defineProperty(target, 'foo', {
|
|||
writable: false,
|
||||
configurable: false
|
||||
});
|
||||
assertThrowsInstanceOf(function () {
|
||||
new Proxy(target, {
|
||||
get: function (target, name, receiver) {
|
||||
return 'baz';
|
||||
}
|
||||
})['foo'];
|
||||
}, TypeError);
|
||||
|
||||
testProxy('baz', 'foo', true);
|
||||
/*
|
||||
* Don't throw a TypeError if the trap reports the same value for a non-writable,
|
||||
* non-configurable property
|
||||
*/
|
||||
assertEq(new Proxy(target, {
|
||||
get: function (target, name, receiver) {
|
||||
return 'bar';
|
||||
}
|
||||
})['foo'],
|
||||
'bar');
|
||||
|
||||
testProxy('bar', 'foo', false);
|
||||
|
||||
/*
|
||||
* Don't throw a TypeError if the trap reports a different value for a writable,
|
||||
|
@ -39,13 +36,7 @@ Object.defineProperty(target, 'prop', {
|
|||
writable: true,
|
||||
configurable: false
|
||||
});
|
||||
assertEq(new Proxy(target, {
|
||||
get: function (target, name, receiver) {
|
||||
return 'baz';
|
||||
}
|
||||
})['prop'],
|
||||
'baz');
|
||||
|
||||
testProxy('baz', 'prop', false);
|
||||
|
||||
/*
|
||||
* Don't throw a TypeError if the trap reports a different value for a non-writable,
|
||||
|
@ -56,9 +47,4 @@ Object.defineProperty(target, 'prop2', {
|
|||
writable: false,
|
||||
configurable: true
|
||||
});
|
||||
assertEq(new Proxy(target, {
|
||||
get: function (target, name, receiver) {
|
||||
return 'baz';
|
||||
}
|
||||
})['prop2'],
|
||||
'baz');
|
||||
testProxy('baz', 'prop2', false);
|
||||
|
|
|
@ -9,10 +9,6 @@ Object.defineProperty(target, 'foo', {
|
|||
set: function (value) {},
|
||||
configurable: false
|
||||
});
|
||||
assertThrowsInstanceOf(function () {
|
||||
new Proxy(target, {
|
||||
get: function (target, name, receiver) {
|
||||
return 'baz';
|
||||
}
|
||||
})['foo'];
|
||||
}, TypeError);
|
||||
var handler = { get: function (target, name, receiver) { return 'baz'; } };
|
||||
for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy])
|
||||
assertThrowsInstanceOf(function () { p['foo'] }, TypeError);
|
||||
|
|
|
@ -1,23 +1,16 @@
|
|||
// Return the trap result
|
||||
assertEq(new Proxy({
|
||||
foo: 'bar'
|
||||
}, {
|
||||
get: function (target, name, receiver) {
|
||||
return 'baz';
|
||||
}
|
||||
}).foo, 'baz');
|
||||
|
||||
assertEq(new Proxy({
|
||||
foo: 'bar'
|
||||
}, {
|
||||
get: function (target, name, receiver) {
|
||||
return undefined;
|
||||
}
|
||||
}).foo, undefined);
|
||||
|
||||
var obj = {};
|
||||
var target = { foo: 'bar' };
|
||||
var s1 = Symbol("moon"), s2 = Symbol("sun");
|
||||
obj[s1] = "wrong";
|
||||
assertEq(new Proxy(obj, {
|
||||
get: () => s2
|
||||
})[s1], s2);
|
||||
target[s1] = "wrong";
|
||||
|
||||
var handler = { };
|
||||
for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy]) {
|
||||
handler.get = (() => 'baz');
|
||||
assertEq(p.foo, 'baz');
|
||||
|
||||
handler.get = (() => undefined);
|
||||
assertEq(p.foo, undefined);
|
||||
|
||||
handler.get = (() => s2);
|
||||
assertEq(p[s1], s2);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
load(libdir + "asserts.js");
|
||||
// Revoked proxies should throw before calling the handler
|
||||
|
||||
var called = false;
|
||||
var target = {};
|
||||
var handler = { get: () => called = true };
|
||||
var holder = Proxy.revocable(target, handler);
|
||||
|
||||
holder.revoke();
|
||||
|
||||
assertThrowsInstanceOf(() => holder.proxy.foo, TypeError);
|
||||
assertEq(called, false);
|
|
@ -6,11 +6,14 @@ Object.defineProperty(target, 'foo', {
|
|||
enumerable: false,
|
||||
configurable: true
|
||||
});
|
||||
var desc = Object.getOwnPropertyDescriptor(Proxy(target, {}), 'foo');
|
||||
assertEq(desc.value, 'bar');
|
||||
assertEq(desc.writable, true);
|
||||
assertEq(desc.enumerable, false);
|
||||
assertEq(desc.configurable, true);
|
||||
|
||||
for (let p of [new Proxy(target, {}), Proxy.revocable(target, {}).proxy]) {
|
||||
var desc = Object.getOwnPropertyDescriptor(p, 'foo');
|
||||
assertEq(desc.value, 'bar');
|
||||
assertEq(desc.writable, true);
|
||||
assertEq(desc.enumerable, false);
|
||||
assertEq(desc.configurable, true);
|
||||
}
|
||||
|
||||
var proto = {};
|
||||
Object.defineProperty(proto, 'foo', {
|
||||
|
@ -20,4 +23,5 @@ Object.defineProperty(proto, 'foo', {
|
|||
configurable: true
|
||||
});
|
||||
var target = Object.create(proto);
|
||||
assertEq(Object.getOwnPropertyDescriptor(Proxy(target, {}), 'foo'), undefined);
|
||||
for (let p of [new Proxy(target, {}), Proxy.revocable(target, {}).proxy])
|
||||
assertEq(Object.getOwnPropertyDescriptor(p, 'foo'), undefined);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Return the descriptor returned by the trap
|
||||
// Return a new descriptor object that agrees with that returned by the trap
|
||||
var target = {};
|
||||
Object.defineProperty(target, 'foo', {
|
||||
value: 'bar',
|
||||
|
@ -6,32 +6,30 @@ Object.defineProperty(target, 'foo', {
|
|||
enumerable: false,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
var desc = {
|
||||
value: 'baz',
|
||||
writable: false,
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
};
|
||||
var desc1 = Object.getOwnPropertyDescriptor(new Proxy(target, {
|
||||
getOwnPropertyDescriptor: function (target, name) {
|
||||
return desc;
|
||||
}
|
||||
}), 'foo');
|
||||
assertEq(desc1 == desc, false);
|
||||
assertEq(desc1.value, 'baz');
|
||||
assertEq(desc1.writable, false);
|
||||
assertEq(desc1.enumerable, true);
|
||||
assertEq(desc1.configurable, true);
|
||||
var handler = { getOwnPropertyDescriptor: function () { return desc; } };
|
||||
for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy]) {
|
||||
var desc1 = Object.getOwnPropertyDescriptor(p, 'foo');
|
||||
assertEq(desc1 == desc, false);
|
||||
assertEq(desc1.value, 'baz');
|
||||
assertEq(desc1.writable, false);
|
||||
assertEq(desc1.enumerable, true);
|
||||
assertEq(desc1.configurable, true);
|
||||
}
|
||||
|
||||
// The returned descriptor must agree in configurability.
|
||||
var desc = { configurable : true };
|
||||
var desc1 = Object.getOwnPropertyDescriptor(new Proxy(target, {
|
||||
getOwnPropertyDescriptor: function (target, name) {
|
||||
return desc;
|
||||
}
|
||||
}), 'foo');
|
||||
assertEq(desc1 == desc, false);
|
||||
assertEq(desc1.value, undefined);
|
||||
assertEq(desc1.writable, false);
|
||||
assertEq(desc1.enumerable, false);
|
||||
assertEq(desc1.configurable, true);
|
||||
desc = { configurable : true };
|
||||
for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy]) {
|
||||
var desc1 = Object.getOwnPropertyDescriptor(p, 'foo');
|
||||
assertEq(desc1 == desc, false);
|
||||
assertEq(desc1.value, undefined);
|
||||
assertEq(desc1.writable, false);
|
||||
assertEq(desc1.enumerable, false);
|
||||
assertEq(desc1.configurable, true);
|
||||
}
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
load(libdir + "asserts.js");
|
||||
|
||||
var target = {};
|
||||
Object.getOwnPropertyDescriptor(new Proxy(target, {
|
||||
getOwnPropertyDescriptor: function () {
|
||||
return {value: 2, configurable: true};
|
||||
}
|
||||
}), 'foo');
|
||||
|
||||
var target = {};
|
||||
Object.preventExtensions(target);
|
||||
assertThrowsInstanceOf(function () {
|
||||
Object.getOwnPropertyDescriptor(new Proxy(target, {
|
||||
getOwnPropertyDescriptor: function () {
|
||||
return {value: 2, configurable: true};
|
||||
}
|
||||
}), 'foo');
|
||||
}, TypeError);
|
|
@ -3,7 +3,7 @@
|
|||
* argument, and the name of the property as the second argument
|
||||
*/
|
||||
var target = {};
|
||||
var called = false;
|
||||
var called;
|
||||
var handler = {
|
||||
getOwnPropertyDescriptor: function (target1, name) {
|
||||
assertEq(this, handler);
|
||||
|
@ -12,5 +12,9 @@ var handler = {
|
|||
called = true;
|
||||
}
|
||||
};
|
||||
Object.getOwnPropertyDescriptor(new Proxy(target, handler), 'foo');
|
||||
assertEq(called, true);
|
||||
|
||||
for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy]) {
|
||||
called = false;
|
||||
Object.getOwnPropertyDescriptor(p, 'foo');
|
||||
assertEq(called, true);
|
||||
}
|
||||
|
|
|
@ -1,16 +1,13 @@
|
|||
/*
|
||||
* Call the trap with the handler as the this value, the target as the first
|
||||
* argument, and the name of the property as the second argument
|
||||
*/
|
||||
var target = {};
|
||||
load(libdir + "asserts.js");
|
||||
// Revoked proxies should throw before calling the handler
|
||||
|
||||
var called = false;
|
||||
var handler = {
|
||||
getOwnPropertyDescriptor: function (target1, name) {
|
||||
assertEq(this, handler);
|
||||
assertEq(target1, target);
|
||||
assertEq(name, 'foo');
|
||||
called = true;
|
||||
}
|
||||
};
|
||||
Object.getOwnPropertyDescriptor(new Proxy(target, handler), 'foo');
|
||||
assertEq(called, true);
|
||||
var target = {};
|
||||
var handler = { getOwnPropertyDescriptor: () => called = true };
|
||||
var holder = Proxy.revocable(target, handler);
|
||||
|
||||
holder.revoke();
|
||||
|
||||
var test = function () { Object.getOwnPropertyDescriptor(holder.proxy, 'foo'); }
|
||||
assertThrowsInstanceOf(test, TypeError);
|
||||
assertEq(called, false);
|
||||
|
|
|
@ -8,10 +8,7 @@ var target = {};
|
|||
Object.defineProperty(target, 'foo', {
|
||||
configurable: false
|
||||
});
|
||||
assertThrowsInstanceOf(function () {
|
||||
Object.getOwnPropertyDescriptor(new Proxy(target, {
|
||||
getOwnPropertyDescriptor: function (target, name) {
|
||||
return undefined;
|
||||
}
|
||||
}), 'foo');
|
||||
}, TypeError);
|
||||
|
||||
var handler = { getOwnPropertyDescriptor: () => undefined };
|
||||
for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy])
|
||||
assertThrowsInstanceOf(() => Object.getOwnPropertyDescriptor(p, 'foo'), TypeError);
|
||||
|
|
|
@ -9,10 +9,7 @@ Object.defineProperty(target, 'foo', {
|
|||
configurable: true
|
||||
});
|
||||
Object.preventExtensions(target);
|
||||
assertThrowsInstanceOf(function () {
|
||||
Object.getOwnPropertyDescriptor(new Proxy(target, {
|
||||
getOwnPropertyDescriptor: function (target, name) {
|
||||
return undefined;
|
||||
}
|
||||
}), 'foo');
|
||||
}, TypeError);
|
||||
|
||||
var handler = { getOwnPropertyDescriptor: () => undefined };
|
||||
for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy])
|
||||
assertThrowsInstanceOf(() => Object.getOwnPropertyDescriptor(p, 'foo'), TypeError);
|
||||
|
|
|
@ -3,8 +3,7 @@ var target = {};
|
|||
Object.defineProperty(target, 'foo', {
|
||||
configurable: true
|
||||
});
|
||||
assertEq(Object.getOwnPropertyDescriptor(new Proxy(target, {
|
||||
getOwnPropertyDescriptor: function (target, name) {
|
||||
return undefined;
|
||||
}
|
||||
}), 'foo'), undefined);
|
||||
|
||||
var handler = { getOwnPropertyDescriptor: () => undefined };
|
||||
for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy])
|
||||
assertEq(Object.getOwnPropertyDescriptor(p, 'foo'), undefined);
|
||||
|
|
|
@ -6,10 +6,7 @@ load(libdir + "asserts.js");
|
|||
*/
|
||||
var target = {};
|
||||
Object.preventExtensions(target);
|
||||
assertThrowsInstanceOf(function () {
|
||||
Object.getOwnPropertyDescriptor(new Proxy(target, {
|
||||
getOwnPropertyDescriptor: function (target, name) {
|
||||
return {};
|
||||
}
|
||||
}), 'foo');
|
||||
}, TypeError);
|
||||
|
||||
var handler = { getOwnPropertyDescriptor: () => ({}) };
|
||||
for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy])
|
||||
assertThrowsInstanceOf(() => Object.getOwnPropertyDescriptor(p, 'foo'), TypeError);
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
load(libdir + "asserts.js");
|
||||
|
||||
/*
|
||||
* Throw a TypeError if the trap reports a new own property on a non-extensible
|
||||
* object
|
||||
*/
|
||||
var target = {};
|
||||
var handler = {
|
||||
getOwnPropertyDescriptor: function () { return { value: 2, configurable: true}; }
|
||||
};
|
||||
|
||||
for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy])
|
||||
Object.getOwnPropertyDescriptor(p, 'foo');
|
||||
|
||||
Object.preventExtensions(target);
|
||||
assertThrowsInstanceOf(function () {
|
||||
Object.getOwnPropertyDescriptor(new Proxy(target, {
|
||||
getOwnPropertyDescriptor: function (target, name) {
|
||||
return {};
|
||||
}
|
||||
}), 'foo');
|
||||
}, TypeError);
|
||||
for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy])
|
||||
assertThrowsInstanceOf(() => Object.getOwnPropertyDescriptor(p, 'foo'), TypeError);
|
||||
|
|
|
@ -4,12 +4,6 @@ load(libdir + "asserts.js");
|
|||
* Throw a TypeError if the trap returns a non-configurable descriptor for a
|
||||
* non-existent property
|
||||
*/
|
||||
assertThrowsInstanceOf(function () {
|
||||
Object.getOwnPropertyDescriptor(new Proxy({}, {
|
||||
getOwnPropertyDescriptor: function (target, name) {
|
||||
return {
|
||||
configurable: false
|
||||
};
|
||||
}
|
||||
}), 'foo');
|
||||
}, TypeError);
|
||||
var handler = { getOwnPropertyDescriptor: () => ({ configurable: false }) };
|
||||
for (let p of [new Proxy({}, handler), Proxy.revocable({}, handler).proxy])
|
||||
assertThrowsInstanceOf(() => Object.getOwnPropertyDescriptor(p, 'foo'), TypeError);
|
||||
|
|
|
@ -21,9 +21,10 @@ var objCD = Object.create(objAB, {
|
|||
}
|
||||
});
|
||||
|
||||
var outerProxy = new Proxy(objCD, {});
|
||||
objCD[Symbol("moon")] = "something";
|
||||
var names = Object.getOwnPropertyNames(outerProxy);
|
||||
assertEq(names.length, 2);
|
||||
assertEq(names[0], 'c');
|
||||
assertEq(names[1], 'd');
|
||||
for (let p of [new Proxy(objCD, {}), Proxy.revocable(objCD, {}).proxy]) {
|
||||
var names = Object.getOwnPropertyNames(p);
|
||||
assertEq(names.length, 2);
|
||||
assertEq(names[0], 'c');
|
||||
assertEq(names[1], 'd');
|
||||
}
|
||||
|
|
|
@ -12,5 +12,8 @@ var handler = {
|
|||
return [];
|
||||
}
|
||||
};
|
||||
assertEq(Object.getOwnPropertyNames(new Proxy(target, handler)).length, 0);
|
||||
assertEq(called, true);
|
||||
|
||||
for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy]) {
|
||||
assertEq(Object.getOwnPropertyNames(p).length, 0);
|
||||
assertEq(called, true);
|
||||
}
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
load(libdir + "asserts.js");
|
||||
|
||||
// Throw a TypeError if the trap does not return an object
|
||||
assertThrowsInstanceOf(function () {
|
||||
Object.getOwnPropertyNames(new Proxy({}, {
|
||||
ownKeys: function (target) {
|
||||
return;
|
||||
}
|
||||
}));
|
||||
}, TypeError);
|
||||
var handler = { ownKeys: () => undefined };
|
||||
for (let p of [new Proxy({}, handler), Proxy.revocable({}, handler).proxy])
|
||||
assertThrowsInstanceOf(() => Object.getOwnPropertyNames(p), TypeError);
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
load(libdir + "asserts.js");
|
||||
|
||||
// Throw a TypeError if the trap reports the same property twice
|
||||
assertThrowsInstanceOf(function () {
|
||||
Object.getOwnPropertyNames(new Proxy({}, {
|
||||
ownKeys: function (target) {
|
||||
return [ 'foo', 'foo' ];
|
||||
}
|
||||
}));
|
||||
}, TypeError);
|
||||
var handler = { ownKeys : () => [ 'foo', 'foo' ] };
|
||||
for (let p of [new Proxy({}, handler), Proxy.revocable({}, handler).proxy])
|
||||
assertThrowsInstanceOf(() => Object.getOwnPropertyNames(p), TypeError);
|
||||
|
|
|
@ -6,10 +6,7 @@ load(libdir + "asserts.js");
|
|||
*/
|
||||
var target = {};
|
||||
Object.preventExtensions(target);
|
||||
assertThrowsInstanceOf(function () {
|
||||
Object.getOwnPropertyNames(new Proxy(target, {
|
||||
ownKeys: function (target) {
|
||||
return [ 'foo' ];
|
||||
}
|
||||
}));
|
||||
}, TypeError);
|
||||
|
||||
var handler = { ownKeys: () => [ 'foo' ] };
|
||||
for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy])
|
||||
assertThrowsInstanceOf(() => Object.getOwnPropertyNames(p), TypeError);
|
||||
|
|
|
@ -5,10 +5,7 @@ var target = {};
|
|||
Object.defineProperty(target, 'foo', {
|
||||
configurable: false
|
||||
});
|
||||
assertThrowsInstanceOf(function () {
|
||||
Object.getOwnPropertyNames(new Proxy(target, {
|
||||
ownKeys: function (target) {
|
||||
return [];
|
||||
}
|
||||
}));
|
||||
}, TypeError);
|
||||
|
||||
var handler = { ownKeys: () => [] };
|
||||
for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy])
|
||||
assertThrowsInstanceOf(() => Object.getOwnPropertyNames(p), TypeError);
|
||||
|
|
|
@ -9,10 +9,7 @@ Object.defineProperty(target, 'foo', {
|
|||
configurable: true
|
||||
});
|
||||
Object.preventExtensions(target);
|
||||
assertThrowsInstanceOf(function () {
|
||||
Object.getOwnPropertyNames(new Proxy(target, {
|
||||
ownKeys: function (target) {
|
||||
return [];
|
||||
}
|
||||
}));
|
||||
}, TypeError);
|
||||
|
||||
var handler = { ownKeys: () => [] };
|
||||
for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy])
|
||||
assertThrowsInstanceOf(() => Object.getOwnPropertyNames(p), TypeError);
|
||||
|
|
|
@ -3,15 +3,16 @@ var target = {};
|
|||
Object.defineProperty(target, 'foo', {
|
||||
configurable: true
|
||||
});
|
||||
var names = Object.getOwnPropertyNames(new Proxy(target, {
|
||||
ownKeys: function (target) {
|
||||
return [ 'bar' ];
|
||||
}
|
||||
}));
|
||||
assertEq(names.length, 1);
|
||||
assertEq(names[0], 'bar');
|
||||
|
||||
var names = Object.getOwnPropertyNames(new Proxy(Object.create(Object.create(null, {
|
||||
var handler = { ownKeys: () => [ 'bar' ] };
|
||||
|
||||
for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy]) {
|
||||
var names = Object.getOwnPropertyNames(p);
|
||||
assertEq(names.length, 1);
|
||||
assertEq(names[0], 'bar');
|
||||
}
|
||||
|
||||
var protoWithAB = Object.create(null, {
|
||||
a: {
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
|
@ -20,20 +21,22 @@ var names = Object.getOwnPropertyNames(new Proxy(Object.create(Object.create(nul
|
|||
enumerable: false,
|
||||
configurable: true
|
||||
}
|
||||
}), {
|
||||
});
|
||||
var objWithCD = Object.create(protoWithAB, {
|
||||
c: {
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
},
|
||||
d: {
|
||||
enumerable: false,
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
}
|
||||
}), {
|
||||
ownKeys: function (target) {
|
||||
return [ 'c', 'e' ];
|
||||
}
|
||||
}));
|
||||
assertEq(names.length, 2);
|
||||
assertEq(names[0], 'c');
|
||||
assertEq(names[1], 'e');
|
||||
});
|
||||
|
||||
handler = { ownKeys: () => [ 'c', 'e' ] };
|
||||
for (let p of [new Proxy(objWithCD, handler), Proxy.revocable(objWithCD, handler).proxy]) {
|
||||
var names = Object.getOwnPropertyNames(p);
|
||||
assertEq(names.length, 2);
|
||||
assertEq(names[0], 'c');
|
||||
assertEq(names[1], 'e');
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
load(libdir + "asserts.js");
|
||||
// Revoked proxies should throw before calling the handler
|
||||
|
||||
var called = false;
|
||||
var target = {};
|
||||
var handler = { ownKeys: () => called = true };
|
||||
var holder = Proxy.revocable(target, handler);
|
||||
|
||||
holder.revoke();
|
||||
|
||||
assertThrowsInstanceOf(() => Object.getOwnPropertyNames(holder.proxy), TypeError);
|
||||
assertEq(called, false);
|
|
@ -1,14 +1,18 @@
|
|||
// Forward to the target if the trap is not defined
|
||||
var proxy = Proxy(Object.create(Object.create(null, {
|
||||
var proto = Object.create(null, {
|
||||
'foo': {
|
||||
configurable: true
|
||||
}
|
||||
}), {
|
||||
});
|
||||
var target = Object.create(proto, {
|
||||
'bar': {
|
||||
configurable: true
|
||||
}
|
||||
}), {});
|
||||
assertEq('foo' in proxy, true);
|
||||
assertEq('bar' in proxy, true);
|
||||
assertEq('baz' in proxy, false);
|
||||
assertEq(Symbol() in proxy, false);
|
||||
});
|
||||
|
||||
for (let p of [new Proxy(target, {}), Proxy.revocable(target, {}).proxy]) {
|
||||
assertEq('foo' in p, true);
|
||||
assertEq('bar' in p, true);
|
||||
assertEq('baz' in p, false);
|
||||
assertEq(Symbol() in p, false);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*/
|
||||
var target = {};
|
||||
for (var key of ['foo', Symbol('bar')]) {
|
||||
var called = false;
|
||||
var called;
|
||||
var handler = {
|
||||
has: function (target1, name) {
|
||||
assertEq(this, handler);
|
||||
|
@ -13,6 +13,9 @@ for (var key of ['foo', Symbol('bar')]) {
|
|||
called = true;
|
||||
}
|
||||
};
|
||||
key in new Proxy(target, handler);
|
||||
assertEq(called, true);
|
||||
for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy]) {
|
||||
called = false;
|
||||
key in p;
|
||||
assertEq(called, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,11 +8,6 @@ var target = {};
|
|||
Object.defineProperty(target, 'foo', {
|
||||
configurable: false
|
||||
});
|
||||
var caught = false;
|
||||
assertThrowsInstanceOf(function () {
|
||||
'foo' in new Proxy(target, {
|
||||
has: function (target, name) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}, TypeError);
|
||||
var handler = { has: () => false };
|
||||
for (p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy])
|
||||
assertThrowsInstanceOf(function () { 'foo' in p; }, TypeError);
|
||||
|
|
|
@ -9,10 +9,7 @@ Object.defineProperty(target, 'foo', {
|
|||
configurable: true
|
||||
});
|
||||
Object.preventExtensions(target);
|
||||
assertThrowsInstanceOf(function () {
|
||||
'foo' in new Proxy(target, {
|
||||
has: function (target, name) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}, TypeError);
|
||||
|
||||
var handler = { has: () => false };
|
||||
for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy])
|
||||
assertThrowsInstanceOf(function () { 'foo' in p }, TypeError);
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
// Return the trap result
|
||||
var proxy = new Proxy(Object.create(Object.create(null, {
|
||||
var proto = Object.create(null, {
|
||||
'foo': {
|
||||
configurable: true
|
||||
}
|
||||
}), {
|
||||
});
|
||||
var target = Object.create(proto, {
|
||||
'bar': {
|
||||
configurable: true
|
||||
}
|
||||
}), {
|
||||
has: function (target, name) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
assertEq('foo' in proxy, false);
|
||||
assertEq('bar' in proxy, false);
|
||||
|
||||
var handler = { has: () => false };
|
||||
|
||||
for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy]) {
|
||||
assertEq('foo' in p, false);
|
||||
assertEq('bar' in p, false);
|
||||
}
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
*/
|
||||
var target = {};
|
||||
Object.preventExtensions(target);
|
||||
var p = new Proxy(target, {
|
||||
has: function (target, name) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
assertEq('foo' in p, false);
|
||||
assertEq(Symbol.iterator in p, false);
|
||||
|
||||
var handler = { has: () => false };
|
||||
|
||||
for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy]) {
|
||||
assertEq('foo' in p, false);
|
||||
assertEq(Symbol.iterator in p, false);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
load(libdir + "asserts.js");
|
||||
// Revoked proxies should throw before calling the handler
|
||||
|
||||
var called = false;
|
||||
var target = {};
|
||||
var handler = { has: () => called = true };
|
||||
var holder = Proxy.revocable(target, handler);
|
||||
|
||||
holder.revoke();
|
||||
|
||||
assertThrowsInstanceOf(() => 'foo' in holder.proxy, TypeError);
|
||||
assertEq(called, false);
|
|
@ -11,20 +11,25 @@ var descs = {
|
|||
};
|
||||
descs[Symbol.for("quux")] = {configurable: true};
|
||||
var target = Object.create(proto, descs);
|
||||
var proxy = Proxy(target, {});
|
||||
assertEq(({}).hasOwnProperty.call(proxy, 'foo'), false);
|
||||
assertEq(({}).hasOwnProperty.call(proxy, 'bar'), true);
|
||||
assertEq(({}).hasOwnProperty.call(proxy, 'quux'), false);
|
||||
assertEq(({}).hasOwnProperty.call(proxy, Symbol('quux')), false);
|
||||
assertEq(({}).hasOwnProperty.call(proxy, 'Symbol(quux)'), false);
|
||||
assertEq(({}).hasOwnProperty.call(proxy, Symbol.for('quux')), true);
|
||||
|
||||
for (let p of [new Proxy(target, {}), Proxy.revocable(target, {}).proxy]) {
|
||||
assertEq(({}).hasOwnProperty.call(p, 'foo'), false);
|
||||
assertEq(({}).hasOwnProperty.call(p, 'bar'), true);
|
||||
assertEq(({}).hasOwnProperty.call(p, 'quux'), false);
|
||||
assertEq(({}).hasOwnProperty.call(p, Symbol('quux')), false);
|
||||
assertEq(({}).hasOwnProperty.call(p, 'Symbol(quux)'), false);
|
||||
assertEq(({}).hasOwnProperty.call(p, Symbol.for('quux')), true);
|
||||
}
|
||||
|
||||
// Make sure only the getOwnPropertyDescriptor trap is called, and not the has
|
||||
// trap.
|
||||
var called = false;
|
||||
var called;
|
||||
var handler = { getOwnPropertyDescriptor: function () { called = true; },
|
||||
has: function () { assertEq(false, true, "has trap must not be called"); }
|
||||
}
|
||||
proxy = new Proxy({}, handler);
|
||||
assertEq(({}).hasOwnProperty.call(proxy, 'foo'), false);
|
||||
assertEq(called, true);
|
||||
|
||||
for (let p of [new Proxy({}, handler), Proxy.revocable({}, handler).proxy]) {
|
||||
called = false;
|
||||
assertEq(({}).hasOwnProperty.call(p, 'foo'), false);
|
||||
assertEq(called, true);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
load(libdir + "asserts.js");
|
||||
// Test ES6 Proxy trap compliance for Object.isExtensible() on exotic proxy
|
||||
// objects.
|
||||
var unsealed = {};
|
||||
var sealed = Object.seal({});
|
||||
var handler = {};
|
||||
|
||||
assertEq(Object.isExtensible(unsealed), true);
|
||||
assertEq(Object.isExtensible(sealed), false);
|
||||
|
||||
var targetSealed = new Proxy(sealed, handler);
|
||||
var targetUnsealed = new Proxy(unsealed, handler);
|
||||
|
||||
var handlerCalled = false;
|
||||
|
||||
function testExtensible(target, expectedResult, shouldIgnoreHandler = false)
|
||||
{
|
||||
for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy]) {
|
||||
handlerCalled = false;
|
||||
if (typeof expectedResult === "boolean")
|
||||
assertEq(Object.isExtensible(p), expectedResult, "Must return the correct value.");
|
||||
else
|
||||
assertThrowsInstanceOf(() => Object.isExtensible(p), expectedResult);
|
||||
assertEq(handlerCalled, !shouldIgnoreHandler, "Must call handler appropriately");
|
||||
}
|
||||
}
|
||||
|
||||
// without traps, forward to the target
|
||||
// First, make sure we get the obvious answer on a non-exotic target.
|
||||
testExtensible(sealed, false, /* shouldIgnoreHandler = */true);
|
||||
testExtensible(unsealed, true, /* shouldIgnoreHandler = */true);
|
||||
|
||||
// Now, keep everyone honest. What if the target itself is a proxy?
|
||||
// Note that we cheat a little. |handlerCalled| is true in a sense, just not
|
||||
// for the toplevel handler.
|
||||
// While we're here, test that the argument is passed correctly.
|
||||
var targetsTarget = {};
|
||||
function ensureCalled(target) { assertEq(target, targetsTarget); handlerCalled = true; return true; }
|
||||
var proxyTarget = new Proxy(targetsTarget, { isExtensible : ensureCalled });
|
||||
testExtensible(proxyTarget, true);
|
||||
|
||||
// What if the trap says it's necessarily sealed?
|
||||
function fakeSealed() { handlerCalled = true; return false; }
|
||||
handler.isExtensible = fakeSealed;
|
||||
testExtensible(targetSealed, false);
|
||||
testExtensible(targetUnsealed, TypeError);
|
||||
|
||||
// What if the trap says it's never sealed?
|
||||
function fakeUnsealed() { handlerCalled = true; return true; }
|
||||
handler.isExtensible = fakeUnsealed;
|
||||
testExtensible(targetSealed, TypeError);
|
||||
testExtensible(targetUnsealed, true);
|
||||
|
||||
// make sure we are able to prevent further extensions mid-flight and throw if the
|
||||
// hook tries to lie.
|
||||
function makeSealedTruth(target) { handlerCalled = true; Object.preventExtensions(target); return false; }
|
||||
function makeSealedLie(target) { handlerCalled = true; Object.preventExtensions(target); return true; }
|
||||
handler.isExtensible = makeSealedTruth;
|
||||
testExtensible({}, false);
|
||||
handler.isExtensible = makeSealedLie;
|
||||
testExtensible({}, TypeError);
|
||||
|
||||
// What if the trap doesn't directly return a boolean?
|
||||
function falseyNonBool() { handlerCalled = true; return undefined; }
|
||||
handler.isExtensible = falseyNonBool;
|
||||
testExtensible(sealed, false);
|
||||
testExtensible(unsealed, TypeError);
|
||||
|
||||
function truthyNonBool() { handlerCalled = true; return {}; }
|
||||
handler.isExtensible = truthyNonBool;
|
||||
testExtensible(sealed, TypeError);
|
||||
testExtensible(unsealed, true);
|
||||
|
||||
// What if the trap throws?
|
||||
function ExtensibleError() { }
|
||||
ExtensibleError.prototype = new Error();
|
||||
ExtensibleError.prototype.constructor = ExtensibleError;
|
||||
function throwFromTrap() { throw new ExtensibleError(); }
|
||||
handler.isExtensible = throwFromTrap;
|
||||
|
||||
// exercise some other code paths and make sure that they invoke the trap and
|
||||
// can handle the ensuing error.
|
||||
for (let p of [new Proxy(sealed, handler), Proxy.revocable(sealed, handler).proxy]) {
|
||||
assertThrowsInstanceOf(function () { Object.isExtensible(p); },
|
||||
ExtensibleError, "Must throw if the trap does.");
|
||||
assertThrowsInstanceOf(function () { Object.isFrozen(p); },
|
||||
ExtensibleError, "Must throw if the trap does.");
|
||||
assertThrowsInstanceOf(function () { Object.isSealed(p); },
|
||||
ExtensibleError, "Must throw if the trap does.");
|
||||
}
|
||||
|
||||
// What if the trap likes to re-ask old questions?
|
||||
for (let p of [new Proxy(sealed, handler), Proxy.revocable(sealed, handler).proxy]) {
|
||||
handler.isExtensible = (() => Object.isExtensible(p));
|
||||
assertThrowsInstanceOf(() => Object.isExtensible(p),
|
||||
InternalError, "Should allow and detect infinite recurison.");
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
load(libdir + "asserts.js");
|
||||
// Revoked proxies should throw before calling the handler
|
||||
|
||||
var called = false;
|
||||
var target = {};
|
||||
var handler = { isExtensible: () => called = true };
|
||||
var holder = Proxy.revocable(target, handler);
|
||||
|
||||
holder.revoke();
|
||||
|
||||
assertThrowsInstanceOf(() => Object.isExtensible(holder.proxy), TypeError);
|
||||
assertEq(called, false);
|
|
@ -1,5 +1,5 @@
|
|||
// Forward to the target if the trap is not defined
|
||||
var names = Object.keys(Proxy(Object.create(Object.create(null, {
|
||||
var proto = Object.create(null, {
|
||||
a: {
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
|
@ -8,7 +8,8 @@ var names = Object.keys(Proxy(Object.create(Object.create(null, {
|
|||
enumerable: false,
|
||||
configurable: true
|
||||
}
|
||||
}), {
|
||||
});
|
||||
var target = Object.create(proto, {
|
||||
c: {
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
|
@ -17,6 +18,10 @@ var names = Object.keys(Proxy(Object.create(Object.create(null, {
|
|||
enumerable: false,
|
||||
configurable: true
|
||||
}
|
||||
}), {}));
|
||||
assertEq(names.length, 1);
|
||||
assertEq(names[0], 'c');
|
||||
});
|
||||
|
||||
for (let p of [new Proxy(target, {}), Proxy.revocable(target, {}).proxy]) {
|
||||
var names = Object.keys(p);
|
||||
assertEq(names.length, 1);
|
||||
assertEq(names[0], 'c');
|
||||
}
|
||||
|
|
|
@ -5,19 +5,19 @@ load(libdir + "asserts.js");
|
|||
// called by Object.keys(), as expected.
|
||||
|
||||
var target = {};
|
||||
Object.defineProperty(target, "foo", { configurable: true, enumerable: false });
|
||||
var handler = {
|
||||
getOwnPropertyDescriptor : function (target, P) {
|
||||
var targetDesc = Object.getOwnPropertyDescriptor(target, P);
|
||||
// Lie about enumerability
|
||||
targetDesc.enumerable = !targetDesc.enumerable;
|
||||
return targetDesc;
|
||||
}
|
||||
};
|
||||
|
||||
function getPD(target, P) {
|
||||
var targetDesc = Object.getOwnPropertyDescriptor(target, P);
|
||||
// Lie about enumerability
|
||||
targetDesc.enumerable = !targetDesc.enumerable;
|
||||
return targetDesc;
|
||||
for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy]) {
|
||||
Object.defineProperty(target, "foo", { configurable: true, enumerable: false });
|
||||
assertDeepEq(Object.keys(p), ["foo"]);
|
||||
|
||||
Object.defineProperty(target, "foo", {configurable: true, enumerable: true});
|
||||
assertDeepEq(Object.keys(p), []);
|
||||
}
|
||||
|
||||
var proxy = new Proxy(target, { getOwnPropertyDescriptor: getPD });
|
||||
|
||||
assertDeepEq(Object.keys(proxy), ["foo"]);
|
||||
|
||||
Object.defineProperty(target, "foo", {configurable: true, enumerable: true});
|
||||
|
||||
assertDeepEq(Object.keys(proxy), []);
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
load(libdir + "asserts.js");
|
||||
// Revoked proxies should throw before calling the handler
|
||||
|
||||
var called = false;
|
||||
var target = {};
|
||||
var handler = { ownKeys: () => called = true };
|
||||
var holder = Proxy.revocable(target, handler);
|
||||
|
||||
holder.revoke();
|
||||
|
||||
assertThrowsInstanceOf(() => Object.keys(holder.proxy), TypeError);
|
||||
assertEq(called, false);
|
|
@ -3,7 +3,7 @@
|
|||
* argument
|
||||
*/
|
||||
var target = {};
|
||||
var called = false;
|
||||
var called;
|
||||
var handler = {
|
||||
ownKeys: function (target1) {
|
||||
assertEq(this, handler);
|
||||
|
@ -12,5 +12,9 @@ var handler = {
|
|||
return [];
|
||||
}
|
||||
};
|
||||
Object.keys(new Proxy(target, handler));
|
||||
assertEq(called, true);
|
||||
|
||||
for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy]) {
|
||||
called = false;
|
||||
Object.keys(new Proxy(target, handler));
|
||||
assertEq(called, true);
|
||||
}
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
load(libdir + "asserts.js");
|
||||
|
||||
// Throw a TypeError if the trap does not return an object
|
||||
assertThrowsInstanceOf(function () {
|
||||
Object.keys(new Proxy({}, {
|
||||
ownKeys: function (target) {
|
||||
return;
|
||||
}
|
||||
}));
|
||||
}, TypeError);
|
||||
|
||||
var handler = { ownKeys: () => undefined };
|
||||
for (let p of [new Proxy({}, handler), Proxy.revocable({}, handler).proxy])
|
||||
assertThrowsInstanceOf(() => Object.keys(p), TypeError);
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
load(libdir + "asserts.js");
|
||||
|
||||
// Throw a TypeError if the trap reports the same property twice
|
||||
assertThrowsInstanceOf(function () {
|
||||
Object.keys(new Proxy({}, {
|
||||
ownKeys: function (target) {
|
||||
return [ 'foo', 'foo' ];
|
||||
}
|
||||
}));
|
||||
}, TypeError);
|
||||
var handler = { ownKeys: () => [ 'foo', 'foo' ] };
|
||||
for (let p of [new Proxy({}, handler), Proxy.revocable({}, handler).proxy])
|
||||
assertThrowsInstanceOf(() => Object.keys(p), TypeError);
|
||||
|
|
|
@ -6,10 +6,7 @@ load(libdir + "asserts.js");
|
|||
*/
|
||||
var target = {};
|
||||
Object.preventExtensions(target);
|
||||
assertThrowsInstanceOf(function () {
|
||||
Object.keys(new Proxy(target, {
|
||||
ownKeys: function (target) {
|
||||
return [ 'foo' ];
|
||||
}
|
||||
}));
|
||||
}, TypeError);
|
||||
|
||||
var handler = { ownKeys: () => [ 'foo' ] };
|
||||
for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy])
|
||||
assertThrowsInstanceOf(() => Object.keys(p), TypeError);
|
||||
|
|
|
@ -6,10 +6,7 @@ Object.defineProperty(target, 'foo', {
|
|||
enumerable: true,
|
||||
configurable: false
|
||||
});
|
||||
assertThrowsInstanceOf(function () {
|
||||
Object.keys(new Proxy(target, {
|
||||
ownKeys: function (target) {
|
||||
return [];
|
||||
}
|
||||
}));
|
||||
}, TypeError);
|
||||
|
||||
var handler = { ownKeys: () => [] };
|
||||
for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy])
|
||||
assertThrowsInstanceOf(() => Object.keys(p), TypeError);
|
||||
|
|
|
@ -10,10 +10,7 @@ Object.defineProperty(target, 'foo', {
|
|||
configurable: true
|
||||
});
|
||||
Object.preventExtensions(target);
|
||||
assertThrowsInstanceOf(function () {
|
||||
Object.keys(new Proxy(target, {
|
||||
ownKeys: function (target) {
|
||||
return [];
|
||||
}
|
||||
}));
|
||||
}, TypeError);
|
||||
|
||||
var handler = { ownKeys: () => [] };
|
||||
for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy])
|
||||
assertThrowsInstanceOf(() => Object.keys(p), TypeError);
|
||||
|
|
|
@ -10,11 +10,7 @@ Object.defineProperty(target, 'foo', {
|
|||
configurable: true
|
||||
});
|
||||
Object.preventExtensions(target);
|
||||
var caught = false;
|
||||
assertThrowsInstanceOf(function () {
|
||||
Object.keys(new Proxy(target, {
|
||||
ownKeys: function (target) {
|
||||
return [];
|
||||
}
|
||||
}));
|
||||
}, TypeError);
|
||||
|
||||
var handler = { ownKeys: () => [] };
|
||||
for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy])
|
||||
assertThrowsInstanceOf(() => Object.keys(p), TypeError);
|
||||
|
|
|
@ -21,17 +21,15 @@ var protoABWithCD = Object.create(nullProtoAB, {
|
|||
});
|
||||
|
||||
var returnedNames;
|
||||
var proxyTargetingCDWithKeys = new Proxy(protoABWithCD, {
|
||||
ownKeys: function (target) {
|
||||
return returnedNames;
|
||||
}
|
||||
});
|
||||
var handler = { ownKeys: () => returnedNames };
|
||||
|
||||
returnedNames = [ 'e' ];
|
||||
var names = Object.keys(proxyTargetingCDWithKeys);
|
||||
assertEq(names.length, 0);
|
||||
for (let p of [new Proxy(protoABWithCD, handler), Proxy.revocable(protoABWithCD, handler).proxy]) {
|
||||
returnedNames = [ 'e' ];
|
||||
var names = Object.keys(p);
|
||||
assertEq(names.length, 0);
|
||||
|
||||
returnedNames = [ 'c' ];
|
||||
names = Object.keys(proxyTargetingCDWithKeys);
|
||||
assertEq(names.length, 1);
|
||||
assertEq(names[0], 'c');
|
||||
returnedNames = [ 'c' ];
|
||||
names = Object.keys(p);
|
||||
assertEq(names.length, 1);
|
||||
assertEq(names[0], 'c');
|
||||
}
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
// Forward to the target if the trap is not defined
|
||||
var target = {};
|
||||
Object.preventExtensions(new Proxy(target, {}));
|
||||
var proxy = new Proxy(target, {});
|
||||
Object.preventExtensions(proxy);
|
||||
assertEq(Object.isExtensible(target), false);
|
||||
|
||||
target = {};
|
||||
proxy = Proxy.revocable(target, {}).proxy;
|
||||
Object.preventExtensions(proxy);
|
||||
assertEq(Object.isExtensible(target), false);
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* argument.
|
||||
*/
|
||||
var target = {};
|
||||
var called = false;
|
||||
var handler = {
|
||||
preventExtensions: function (target1) {
|
||||
assertEq(this, handler);
|
||||
|
@ -13,5 +12,14 @@ var handler = {
|
|||
return true;
|
||||
}
|
||||
};
|
||||
Object.preventExtensions(new Proxy(target, handler));
|
||||
|
||||
var proxy = new Proxy(target, handler);
|
||||
var called = false;
|
||||
Object.preventExtensions(proxy);
|
||||
assertEq(called, true);
|
||||
|
||||
target = {};
|
||||
proxy = Proxy.revocable(target, handler).proxy;
|
||||
called = false;
|
||||
Object.preventExtensions(proxy);
|
||||
assertEq(called, true);
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
load(libdir + "asserts.js");
|
||||
|
||||
// Throw a TypeError if the trap reports an extensible object as non-extensible
|
||||
assertThrowsInstanceOf(function () {
|
||||
Object.preventExtensions(new Proxy({}, {
|
||||
preventExtensions: function () {
|
||||
return true;
|
||||
}
|
||||
}));
|
||||
}, TypeError);
|
||||
|
||||
var handler = { preventExtensions: () => true };
|
||||
for (let p of [new Proxy({}, handler), Proxy.revocable({}, handler).proxy])
|
||||
assertThrowsInstanceOf(() => Object.preventExtensions(p), TypeError);
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
load(libdir + "asserts.js");
|
||||
|
||||
// Throw a TypeError if the object refuses to be made non-extensible
|
||||
assertThrowsInstanceOf(function () {
|
||||
Object.preventExtensions(new Proxy({}, {
|
||||
preventExtensions: function () {
|
||||
return false;
|
||||
}
|
||||
}));
|
||||
}, TypeError);
|
||||
var handler = { preventExtensions: () => false };
|
||||
for (let p of [new Proxy({}, handler), Proxy.revocable({}, handler).proxy])
|
||||
assertThrowsInstanceOf(() => Object.preventExtensions(p), TypeError);
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
load(libdir + "asserts.js");
|
||||
// Revoked proxies should throw before calling the handler
|
||||
|
||||
var called = false;
|
||||
var target = {};
|
||||
var handler = { preventExtensions: () => called = true };
|
||||
var holder = Proxy.revocable(target, handler);
|
||||
|
||||
holder.revoke();
|
||||
|
||||
assertThrowsInstanceOf(() => Object.preventExtensions(holder.proxy), TypeError);
|
||||
assertEq(called, false);
|
|
@ -0,0 +1,45 @@
|
|||
load(libdir + "asserts.js");
|
||||
|
||||
// Test for various properties demanded of Proxy.revocable
|
||||
var holder = Proxy.revocable({}, {});
|
||||
|
||||
// The returned object must inherit from Object.prototype
|
||||
assertEq(Object.getPrototypeOf(holder), Object.prototype);
|
||||
|
||||
assertDeepEq(Object.getOwnPropertyNames(holder), [ 'proxy', 'revoke' ]);
|
||||
|
||||
// The revocation function must inherit from Function.prototype
|
||||
assertEq(Object.getPrototypeOf(holder.revoke), Function.prototype);
|
||||
|
||||
// Proxy.revoke should return unique objects from the same opcode call.
|
||||
var proxyLog = []
|
||||
var revokerLog = []
|
||||
var holderLog = []
|
||||
|
||||
function addUnique(l, v)
|
||||
{
|
||||
assertEq(l.indexOf(v), -1);
|
||||
l.push(v);
|
||||
}
|
||||
|
||||
for (let i = 0; i < 5; i++) {
|
||||
holder = Proxy.revocable({}, {});
|
||||
addUnique(holderLog, holder);
|
||||
addUnique(revokerLog, holder.revoke);
|
||||
addUnique(proxyLog, holder.proxy);
|
||||
}
|
||||
|
||||
// The provided revoke function should revoke only the 1 proxy
|
||||
var p = proxyLog.pop();
|
||||
var r = revokerLog.pop();
|
||||
|
||||
// Works before, but not after. This is mostly a token. There are
|
||||
// testDirectProxy* tests to check each trap revokes properly.
|
||||
p.foo;
|
||||
assertEq(r(), undefined, "Revoke trap must return undefined");
|
||||
assertThrowsInstanceOf(() => p.foo, TypeError);
|
||||
assertEq(r(), undefined, "Revoke trap must return undefined");
|
||||
|
||||
// None of this should throw, since these proxies are unrevoked.
|
||||
for (let i = 0; i < proxyLog.length; i++)
|
||||
proxyLog[i].foo;
|
|
@ -2,12 +2,17 @@
|
|||
var target = {
|
||||
foo: 'bar'
|
||||
};
|
||||
Proxy(target, {}).foo = 'baz';
|
||||
assertEq(target.foo, 'baz');
|
||||
Proxy(target, {})['foo'] = 'buz';
|
||||
assertEq(target.foo, 'buz');
|
||||
|
||||
var sym = Symbol.for('quux');
|
||||
Proxy(target, {})[sym] = sym;
|
||||
assertEq(target[sym], sym);
|
||||
for (let p of [new Proxy(target, {}), Proxy.revocable(target, {}).proxy]) {
|
||||
// The sets from the first iteration will affect target, but it doesn't
|
||||
// matter, since the effectiveness of the foo sets is still observable.
|
||||
p.foo = 'baz';
|
||||
assertEq(target.foo, 'baz');
|
||||
p['foo'] = 'buz';
|
||||
assertEq(target.foo, 'buz');
|
||||
|
||||
var sym = Symbol.for('quux');
|
||||
p[sym] = sym;
|
||||
assertEq(target[sym], sym);
|
||||
// Reset for second iteration
|
||||
target[sym] = undefined;
|
||||
}
|
||||
|
|
|
@ -5,18 +5,19 @@
|
|||
*/
|
||||
var target = {};
|
||||
for (var key of ['foo', Symbol.for('quux')]) {
|
||||
var called = false;
|
||||
var handler = {
|
||||
set: function (target1, name, val, receiver) {
|
||||
var handler = { };
|
||||
for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy]) {
|
||||
handler.set = function (target1, name, val, receiver) {
|
||||
assertEq(this, handler);
|
||||
assertEq(target1, target);
|
||||
assertEq(name, key);
|
||||
assertEq(val, 'baz');
|
||||
assertEq(receiver, proxy);
|
||||
assertEq(receiver, p);
|
||||
called = true;
|
||||
}
|
||||
};
|
||||
var proxy = new Proxy(target, handler);
|
||||
proxy[key] = 'baz';
|
||||
assertEq(called, true);
|
||||
|
||||
var called = false;
|
||||
p[key] = 'baz';
|
||||
assertEq(called, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,11 +8,7 @@ for (var key of ['foo', Symbol.for('quux')]) {
|
|||
writable: false,
|
||||
configurable: false
|
||||
});
|
||||
assertThrowsInstanceOf(function () {
|
||||
new Proxy(target, {
|
||||
set: function (target, name, val, receiver) {
|
||||
return true;
|
||||
}
|
||||
})[key] = 'baz';
|
||||
}, TypeError);
|
||||
var handler = { set: () => true };
|
||||
for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy])
|
||||
assertThrowsInstanceOf(() => p[key] = 'baz', TypeError);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
load(libdir + "asserts.js");
|
||||
|
||||
/*
|
||||
/*
|
||||
* Throw a TypeError if the trap sets a non-configurable accessor property that
|
||||
* doest not have a setter
|
||||
*/
|
||||
|
@ -11,10 +11,7 @@ Object.defineProperty(target, 'foo', {
|
|||
},
|
||||
configurable: false
|
||||
});
|
||||
assertThrowsInstanceOf(function () {
|
||||
new Proxy(target, {
|
||||
set: function (target, name, val, receiver) {
|
||||
return true;
|
||||
}
|
||||
})['foo'] = 'baz';
|
||||
}, TypeError);
|
||||
|
||||
var handler = { set: () => true };
|
||||
for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy])
|
||||
assertThrowsInstanceOf(() => p['foo'] = 'baz', TypeError);
|
||||
|
|
|
@ -2,9 +2,12 @@
|
|||
var target = {
|
||||
foo: 'bar'
|
||||
};
|
||||
new Proxy(target, {
|
||||
set: function (target, name, val, receiver) {
|
||||
target[name] = 'qux';
|
||||
}
|
||||
})['foo'] = 'baz';
|
||||
assertEq(target['foo'], 'qux');
|
||||
|
||||
var handler = { set: (target, name) => target[name] = 'qux' };
|
||||
for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy]) {
|
||||
p['foo'] = 'baz';
|
||||
assertEq(target['foo'], 'qux');
|
||||
|
||||
// reset for second iteration
|
||||
target['foo'] = 'bar';
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
load(libdir + "asserts.js");
|
||||
// Revoked proxies should throw before calling the handler
|
||||
|
||||
var called = false;
|
||||
var target = {};
|
||||
var handler = { set: () => called = true };
|
||||
var holder = Proxy.revocable(target, handler);
|
||||
|
||||
holder.revoke();
|
||||
|
||||
assertThrowsInstanceOf(() => holder.proxy.foo = 'bar', TypeError);
|
||||
assertEq(called, false);
|
|
@ -1,94 +0,0 @@
|
|||
// Test ES6 Proxy trap compliance for Object.isExtensible() on exotic proxy
|
||||
// objects.
|
||||
var unsealed = {};
|
||||
var sealed = Object.seal({});
|
||||
var handler = {};
|
||||
|
||||
assertEq(Object.isExtensible(unsealed), true);
|
||||
assertEq(Object.isExtensible(sealed), false);
|
||||
|
||||
var targetSealed = new Proxy(sealed, handler);
|
||||
var targetUnsealed = new Proxy(unsealed, handler);
|
||||
|
||||
var handlerCalled = false;
|
||||
|
||||
// without traps, forward to the target
|
||||
// First, make sure we get the obvious answer on a non-exotic target.
|
||||
assertEq(Object.isExtensible(targetSealed), false, "Must forward to target without hook.");
|
||||
assertEq(Object.isExtensible(targetUnsealed), true, "Must forward to target without hook.");
|
||||
|
||||
// Now, keep everyone honest. What if the target itself is a proxy?
|
||||
function ensureCalled() { handlerCalled = true; return true; }
|
||||
var proxyTarget = new Proxy({}, { isExtensible : ensureCalled });
|
||||
assertEq(Object.isExtensible(new Proxy(proxyTarget, {})), true, "Must forward to target without hook.");
|
||||
assertEq(handlerCalled, true, "Must forward to target without hook.");
|
||||
|
||||
// with traps, makes sure that the handler is called, and that we throw if the
|
||||
// trap disagrees with the target
|
||||
function testExtensible(obj, shouldThrow, expectedResult)
|
||||
{
|
||||
handlerCalled = false;
|
||||
if (shouldThrow)
|
||||
assertThrowsInstanceOf(function () { Object.isExtensible(obj); },
|
||||
TypeError, "Must throw if handler and target disagree.");
|
||||
else
|
||||
assertEq(Object.isExtensible(obj), expectedResult, "Must return the correct value.");
|
||||
assertEq(handlerCalled, true, "Must call handler trap if present");
|
||||
}
|
||||
|
||||
// What if the trap says it's necessarily sealed?
|
||||
function fakeSealed() { handlerCalled = true; return false; }
|
||||
handler.isExtensible = fakeSealed;
|
||||
testExtensible(targetSealed, false, false);
|
||||
testExtensible(targetUnsealed, true);
|
||||
|
||||
// What if the trap says it's never sealed?
|
||||
function fakeUnsealed() { handlerCalled = true; return true; }
|
||||
handler.isExtensible = fakeUnsealed;
|
||||
testExtensible(targetSealed, true);
|
||||
testExtensible(targetUnsealed, false, true);
|
||||
|
||||
// make sure we are able to prevent further extensions mid-flight and throw if the
|
||||
// hook tries to lie.
|
||||
function makeSealedTruth(target) { handlerCalled = true; Object.preventExtensions(target); return false; }
|
||||
function makeSealedLie(target) { handlerCalled = true; Object.preventExtensions(target); return true; }
|
||||
handler.isExtensible = makeSealedTruth;
|
||||
testExtensible(new Proxy({}, handler), false, false);
|
||||
handler.isExtensible = makeSealedLie;
|
||||
testExtensible(new Proxy({}, handler), true);
|
||||
|
||||
// What if the trap doesn't directly return a boolean?
|
||||
function falseyNonBool() { handlerCalled = true; return undefined; }
|
||||
handler.isExtensible = falseyNonBool;
|
||||
testExtensible(targetSealed, false, false);
|
||||
testExtensible(targetUnsealed, true);
|
||||
|
||||
function truthyNonBool() { handlerCalled = true; return {}; }
|
||||
handler.isExtensible = truthyNonBool;
|
||||
testExtensible(targetSealed, true);
|
||||
testExtensible(targetUnsealed, false, true);
|
||||
|
||||
// What if the trap throws?
|
||||
function ExtensibleError() { }
|
||||
ExtensibleError.prototype = new Error();
|
||||
ExtensibleError.prototype.constructor = ExtensibleError;
|
||||
function throwFromTrap() { throw new ExtensibleError(); }
|
||||
handler.isExtensible = throwFromTrap;
|
||||
|
||||
// exercise some other code paths and make sure that they invoke the trap and
|
||||
// can handle the ensuing error.
|
||||
assertThrowsInstanceOf(function () { Object.isExtensible(targetSealed); },
|
||||
ExtensibleError, "Must throw if the trap does.");
|
||||
assertThrowsInstanceOf(function () { Object.isFrozen(targetSealed); },
|
||||
ExtensibleError, "Must throw if the trap does.");
|
||||
assertThrowsInstanceOf(function () { Object.isSealed(targetSealed); },
|
||||
ExtensibleError, "Must throw if the trap does.");
|
||||
|
||||
|
||||
// What if the trap likes to re-ask old questions?
|
||||
function recurse() { return Object.isExtensible(targetSealed); }
|
||||
handler.isExtensible = recurse;
|
||||
assertThrowsInstanceOf(function () { Object.isExtensible(targetSealed); },
|
||||
InternalError, "Should allow and detect infinite recurison.");
|
||||
|
||||
reportCompare(0, 0, "OK");
|
Загрузка…
Ссылка в новой задаче