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:
Eric Faust 2014-07-22 14:10:34 -07:00
Родитель 9db4e68792
Коммит b80dee55dd
73 изменённых файлов: 690 добавлений и 584 удалений

Просмотреть файл

@ -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");