Create `proxyTrapsHelper` to throw on all traps by default.

This commit is contained in:
Jordan Harband 2016-02-13 15:56:47 -08:00
parent cf83ad5e73
commit d530c87b41
6 changed files with 148 additions and 42 deletions

View File

@ -0,0 +1,22 @@
function throwTest262Error(msg) {
return function () { throw new Test262Error(msg); };
}
function allowProxyTraps(overrides) {
if (!overrides) { overrides = {}; }
var traps = {
getPrototypeOf: overrides.getPrototypeOf || throwTest262Error('[[GetPrototypeOf]] trap called'),
setPrototypeOf: overrides.setPrototypeOf || throwTest262Error('[[SetPrototypeOf]] trap called'),
isExtensible: overrides.isExtensible || throwTest262Error('[[IsExtensible]] trap called'),
preventExtensions: overrides.preventExtensions || throwTest262Error('[[PreventExtensions]] trap called'),
getOwnPropertyDescriptor: overrides.getOwnPropertyDescriptor || throwTest262Error('[[GetOwnProperty]] trap called'),
has: overrides.has || throwTest262Error('[[HasProperty]] trap called'),
get: overrides.get || throwTest262Error('[[Get]] trap called'),
set: overrides.set || throwTest262Error('[[Set]] trap called'),
deleteProperty: overrides.deleteProperty || throwTest262Error('[[Delete]] trap called'),
defineProperty: overrides.defineProperty || throwTest262Error('[[DefineOwnProperty]] trap called'),
enumerate: throwTest262Error('[[Enumerate]] trap called: this trap has been removed'),
ownKeys: overrides.ownKeys || throwTest262Error('[[OwnPropertyKeys]] trap called'),
apply: overrides.apply || throwTest262Error('[[Call]] trap called'),
construct: overrides.construct || throwTest262Error('[[Construct]] trap called')
};
}

View File

@ -6,11 +6,12 @@ id: sec-object.entries
description: Object.entries should perform observable operations in the correct order description: Object.entries should perform observable operations in the correct order
author: Jordan Harband author: Jordan Harband
features: [Proxy] features: [Proxy]
includes: [proxyTrapsHelper.js]
---*/ ---*/
var log = ""; var log = "";
var object = { a: 0, b: 0, c: 0 }; var object = { a: 0, b: 0, c: 0 };
var handler = { var handler = allowProxyTraps({
get: function (target, propertyKey, receiver) { get: function (target, propertyKey, receiver) {
assert.sameValue(target, object, "get target"); assert.sameValue(target, object, "get target");
assert.sameValue(receiver, proxy, "get receiver"); assert.sameValue(receiver, proxy, "get receiver");
@ -26,23 +27,14 @@ var handler = {
assert.sameValue(target, object, "ownKeys"); assert.sameValue(target, object, "ownKeys");
log += "|ownKeys"; log += "|ownKeys";
return Object.getOwnPropertyNames(target); return Object.getOwnPropertyNames(target);
},
deleteProperty: function (oTarget, sKey) {
throw new Test262Error('properties should not be deleted');
},
defineProperty: function (oTarget, sKey, oDesc) {
throw new Test262Error('properties should not be defined');
},
set: function (oTarget, sKey, vValue) {
throw new Test262Error('properties should not be assigned');
} }
}; });
var check = { var check = allowProxyTraps({
get: function (target, propertyKey, receiver) { get: function (target, propertyKey, receiver) {
assert(propertyKey in target, "handler check: " + propertyKey); assert(propertyKey in target, "handler check: " + propertyKey);
return target[propertyKey]; return target[propertyKey];
} }
}; });
var proxy = new Proxy(object, new Proxy(handler, check)); var proxy = new Proxy(object, new Proxy(handler, check));
var result = Object.entries(proxy); var result = Object.entries(proxy);
assert.sameValue(log, "|ownKeys|getOwnPropertyDescriptor:a|get:a|getOwnPropertyDescriptor:b|get:b|getOwnPropertyDescriptor:c|get:c", log); assert.sameValue(log, "|ownKeys|getOwnPropertyDescriptor:a|get:a|getOwnPropertyDescriptor:b|get:b|getOwnPropertyDescriptor:c|get:c", log);

View File

@ -6,14 +6,12 @@ description: Object.getOwnPropertyDescriptors should perform observable operatio
id: pending id: pending
author: Jordan Harband author: Jordan Harband
features: [Proxy] features: [Proxy]
includes: [proxyTrapsHelper.js]
---*/ ---*/
var log = ""; var log = "";
var object = { a: 0, b: 0, c: 0 }; var object = { a: 0, b: 0, c: 0 };
var handler = { var handler = allowProxyTraps({
get: function (target, propertyKey, receiver) {
throw new Test262Error('no values should be retrieved via [[Get]]');
},
getOwnPropertyDescriptor: function (target, propertyKey) { getOwnPropertyDescriptor: function (target, propertyKey) {
assert.sameValue(target, object, "getOwnPropertyDescriptor"); assert.sameValue(target, object, "getOwnPropertyDescriptor");
log += "|getOwnPropertyDescriptor:" + propertyKey; log += "|getOwnPropertyDescriptor:" + propertyKey;
@ -23,23 +21,14 @@ var handler = {
assert.sameValue(target, object, "ownKeys"); assert.sameValue(target, object, "ownKeys");
log += "|ownKeys"; log += "|ownKeys";
return Object.getOwnPropertyNames(target); return Object.getOwnPropertyNames(target);
},
deleteProperty: function (oTarget, sKey) {
throw new Test262Error('properties should not be deleted');
},
defineProperty: function (oTarget, sKey, oDesc) {
throw new Test262Error('properties should not be defined');
},
set: function (oTarget, sKey, vValue) {
throw new Test262Error('properties should not be assigned');
} }
}; });
var check = { var check = allowProxyTraps({
get: function (target, propertyKey, receiver) { get: function (target, propertyKey, receiver) {
assert(propertyKey in target, "handler check: " + propertyKey); assert(propertyKey in target, "handler check: " + propertyKey);
return target[propertyKey]; return target[propertyKey];
} }
}; });
var proxy = new Proxy(object, new Proxy(handler, check)); var proxy = new Proxy(object, new Proxy(handler, check));
var result = Object.getOwnPropertyDescriptors(proxy); var result = Object.getOwnPropertyDescriptors(proxy);
assert.sameValue(log, "|ownKeys|getOwnPropertyDescriptor:a|getOwnPropertyDescriptor:b|getOwnPropertyDescriptor:c", 'log'); assert.sameValue(log, "|ownKeys|getOwnPropertyDescriptor:a|getOwnPropertyDescriptor:b|getOwnPropertyDescriptor:c", 'log');

View File

@ -6,11 +6,12 @@ id: sec-object.values
description: Object.values should perform observable operations in the correct order description: Object.values should perform observable operations in the correct order
author: Jordan Harband author: Jordan Harband
features: [Proxy] features: [Proxy]
includes: [proxyTrapsHelper.js]
---*/ ---*/
var log = ""; var log = "";
var object = { a: 0, b: 0, c: 0 }; var object = { a: 0, b: 0, c: 0 };
var handler = { var handler = allowProxyTraps({
get: function (target, propertyKey, receiver) { get: function (target, propertyKey, receiver) {
assert.sameValue(target, object, "get target"); assert.sameValue(target, object, "get target");
assert.sameValue(receiver, proxy, "get receiver"); assert.sameValue(receiver, proxy, "get receiver");
@ -26,23 +27,14 @@ var handler = {
assert.sameValue(target, object, "ownKeys"); assert.sameValue(target, object, "ownKeys");
log += "|ownKeys"; log += "|ownKeys";
return Object.getOwnPropertyNames(target); return Object.getOwnPropertyNames(target);
},
deleteProperty: function (oTarget, sKey) {
throw new Test262Error('properties should not be deleted');
},
defineProperty: function (oTarget, sKey, oDesc) {
throw new Test262Error('properties should not be defined');
},
set: function (oTarget, sKey, vValue) {
throw new Test262Error('properties should not be assigned');
} }
}; });
var check = { var check = allowProxyTraps({
get: function (target, propertyKey, receiver) { get: function (target, propertyKey, receiver) {
assert(propertyKey in target, "handler check: " + propertyKey); assert(propertyKey in target, "handler check: " + propertyKey);
return target[propertyKey]; return target[propertyKey];
} }
}; });
var proxy = new Proxy(object, new Proxy(handler, check)); var proxy = new Proxy(object, new Proxy(handler, check));
var result = Object.values(proxy); var result = Object.values(proxy);
assert.sameValue(log, "|ownKeys|getOwnPropertyDescriptor:a|get:a|getOwnPropertyDescriptor:b|get:b|getOwnPropertyDescriptor:c|get:c", log); assert.sameValue(log, "|ownKeys|getOwnPropertyDescriptor:a|get:a|getOwnPropertyDescriptor:b|get:b|getOwnPropertyDescriptor:c|get:c", log);

View File

@ -0,0 +1,40 @@
// Copyright (C) 2016 Jordan Harband. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: allowProxyTraps helper should default throw on all the proxy trap named methods being invoked
id: pending
author: Jordan Harband
includes: [proxyTrapsHelper.js]
---*/
var traps = allowProxyTraps();
function assertTrapThrows(trap) {
if (typeof traps[trap] !== 'function') {
throw new Test262Error('trap ' + trap + ' is not a function');
}
var failedToThrow = false;
try {
traps[trap]();
failedToThrow = true;
} catch (e) {}
if (failedToThrow) {
throw new Test262Error('trap ' + trap + ' did not throw an error');
}
}
assertTrapThrows('getPrototypeOf');
assertTrapThrows('setPrototypeOf');
assertTrapThrows('isExtensible');
assertTrapThrows('preventExtensions');
assertTrapThrows('getOwnPropertyDescriptor');
assertTrapThrows('has');
assertTrapThrows('get');
assertTrapThrows('set');
assertTrapThrows('deleteProperty');
assertTrapThrows('defineProperty');
assertTrapThrows('enumerate');
assertTrapThrows('ownKeys');
assertTrapThrows('apply');
assertTrapThrows('construct');

View File

@ -0,0 +1,71 @@
// Copyright (C) 2016 Jordan Harband. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: allowProxyTraps helper should default throw on all the proxy trap named methods being invoked
id: pending
author: Jordan Harband
includes: [proxyTrapsHelper.js]
---*/
var traps = allowProxyTraps({
getPrototypeOf: function () {},
setPrototypeOf: function () {},
isExtensible: function () {},
preventExtensions: function () {},
getOwnPropertyDescriptor: function () {},
has: function () {},
get: function () {},
set: function () {},
deleteProperty: function () {},
defineProperty: function () {},
enumerate: function () {},
ownKeys: function () {},
apply: function () {},
construct: function () {},
});
function assertTrapSucceeds(trap) {
if (typeof traps[trap] !== 'function') {
throw new Test262Error('trap ' + trap + ' is not a function');
}
var threw = false;
try {
traps[trap]();
threw = true;
} catch (e) {}
if (threw) {
throw new Test262Error('trap ' + trap + ' threw an error');
}
}
function assertTrapThrows(trap) {
if (typeof traps[trap] !== 'function') {
throw new Test262Error('trap ' + trap + ' is not a function');
}
var failedToThrow = false;
try {
traps[trap]();
failedToThrow = true;
} catch (e) {}
if (failedToThrow) {
throw new Test262Error('trap ' + trap + ' did not throw an error');
}
}
assertTrapSucceeds('getPrototypeOf');
assertTrapSucceeds('setPrototypeOf');
assertTrapSucceeds('isExtensible');
assertTrapSucceeds('preventExtensions');
assertTrapSucceeds('getOwnPropertyDescriptor');
assertTrapSucceeds('has');
assertTrapSucceeds('get');
assertTrapSucceeds('set');
assertTrapSucceeds('deleteProperty');
assertTrapSucceeds('defineProperty');
assertTrapSucceeds('ownKeys');
assertTrapSucceeds('apply');
assertTrapSucceeds('construct');
// enumerate should always throw because the trap has been removed
assertTrapThrows('enumerate');