blob: d2c7bfa10ea60323bf4ca83481ec4e15a37fa074 [file] [log] [blame]
function assert(b) {
if (!b)
throw new Error("bad assertion");
}
{
let target = {x: 20};
let called = false;
let handler = {
getOwnPropertyDescriptor: function(theTarget, propName) {
called = true;
assert(theTarget === target);
assert(propName === "x");
return undefined;
}
};
let proxy = new Proxy(target, handler);
for (let i = 0; i < 500; i++) {
assert(Object.getOwnPropertyDescriptor(proxy, "x") === undefined);
assert(called);
called = false;
}
}
{
let target = {};
let handler = {
getOwnPropertyDescriptor: function(theTarget, propName) {
return 25;
}
};
let proxy = new Proxy(target, handler);
for (let i = 0; i < 500; i++) {
let threw = false;
try {
Object.getOwnPropertyDescriptor(proxy, "x");
} catch(e) {
assert(e.toString() === "TypeError: result of 'getOwnPropertyDescriptor' call should either be an Object or undefined");
threw = true;
}
assert(threw);
}
}
{
let target = {};
Object.defineProperty(target, "x", {
enumerable: true,
configurable: false
});
let handler = {
getOwnPropertyDescriptor: function(theTarget, propName) {
assert(theTarget === target);
assert(propName === "x");
return undefined;
}
};
let proxy = new Proxy(target, handler);
for (let i = 0; i < 500; i++) {
let threw = false;
try {
Object.getOwnPropertyDescriptor(proxy, "x");
} catch(e) {
assert(e.toString() === "TypeError: When the result of 'getOwnPropertyDescriptor' is undefined the target must be configurable");
threw = true;
}
assert(threw);
}
}
{
let target = Object.preventExtensions({x: 1});
let handler = {
getOwnPropertyDescriptor: function(theTarget, propName) {
assert(theTarget === target);
assert(propName === "x");
return undefined;
}
};
let proxy = new Proxy(target, handler);
for (let i = 0; i < 500; i++) {
let threw = false;
try {
Object.getOwnPropertyDescriptor(proxy, "x");
} catch(e) {
assert(e.toString() === "TypeError: When 'getOwnPropertyDescriptor' returns undefined, the 'target' of a Proxy should be extensible");
threw = true;
}
assert(threw);
}
}
{
let isExtensibleTrapCalls = 0;
let target = new Proxy({x: 1}, {
isExtensible: function() {
isExtensibleTrapCalls++;
return true;
}
});
let handler = {
getOwnPropertyDescriptor: function(theTarget, propName) {
assert(theTarget === target);
assert(propName === "x");
return undefined;
}
};
let proxy = new Proxy(target, handler);
for (let i = 1; i <= 500; i++) {
assert(Object.getOwnPropertyDescriptor(proxy, "x") === undefined);
assert(isExtensibleTrapCalls === i);
}
}
{
let target = {};
Object.defineProperty(target, "x", {
enumerable: true,
configurable: true
});
let handler = {
getOwnPropertyDescriptor: function(theTarget, propName) {
assert(theTarget === target);
assert(propName === "x");
return {configurable: false};
}
};
let proxy = new Proxy(target, handler);
for (let i = 0; i < 500; i++) {
let threw = false;
try {
Object.getOwnPropertyDescriptor(proxy, "x");
} catch(e) {
assert(e.toString() === "TypeError: Result from 'getOwnPropertyDescriptor' can't be non-configurable when the 'target' doesn't have it as an own property or if it is a configurable own property on 'target'");
threw = true;
}
assert(threw);
}
}
{
let target = {};
Object.defineProperty(target, "x", {
enumerable: false,
configurable: false
});
let handler = {
getOwnPropertyDescriptor: function(theTarget, propName) {
assert(theTarget === target);
assert(propName === "x");
return {enumerable: true};
}
};
let proxy = new Proxy(target, handler);
for (let i = 0; i < 500; i++) {
let threw = false;
try {
Object.getOwnPropertyDescriptor(proxy, "x");
} catch(e) {
assert(e.toString() === "TypeError: Result from 'getOwnPropertyDescriptor' fails the IsCompatiblePropertyDescriptor test");
threw = true;
}
assert(threw);
}
}
{
let target = {};
let handler = {
getOwnPropertyDescriptor: 45
};
let proxy = new Proxy(target, handler);
for (let i = 0; i < 500; i++) {
let threw = false;
try {
Object.getOwnPropertyDescriptor(proxy, "x");
} catch(e) {
assert(e.toString() === "TypeError: 'getOwnPropertyDescriptor' property of a Proxy's handler should be callable");
threw = true;
}
assert(threw);
}
}
{
let target = {};
let handler = {
getOwnPropertyDescriptor: null
};
Object.defineProperty(target, "x", {
enumerable: true,
configurable: false
});
let proxy = new Proxy(target, handler);
for (let i = 0; i < 500; i++) {
let pDesc = Object.getOwnPropertyDescriptor(proxy, "x");
assert(pDesc.configurable === false);
assert(pDesc.enumerable === true);
}
}
{
let target = {};
let handler = {
getOwnPropertyDescriptor: undefined
};
Object.defineProperty(target, "x", {
enumerable: true,
configurable: false
});
let proxy = new Proxy(target, handler);
for (let i = 0; i < 500; i++) {
let pDesc = Object.getOwnPropertyDescriptor(proxy, "x");
assert(pDesc.configurable === false);
assert(pDesc.enumerable === true);
}
}
{
let target = {};
let handler = { };
Object.defineProperty(target, "x", {
enumerable: true,
configurable: false
});
let proxy = new Proxy(target, handler);
for (let i = 0; i < 500; i++) {
let pDesc = Object.getOwnPropertyDescriptor(proxy, "x");
assert(pDesc.configurable === false);
assert(pDesc.enumerable === true);
}
}
{
let target = {};
let error = null;
let handler = { get getOwnPropertyDescriptor() {
error = new Error("blah");
throw error;
}};
Object.defineProperty(target, "x", {
enumerable: true,
configurable: false
});
let proxy = new Proxy(target, handler);
for (let i = 0; i < 500; i++) {
let threw = false;
try {
let pDesc = Object.getOwnPropertyDescriptor(proxy, "x");
} catch(e) {
threw = true;
assert(e === error);
}
assert(threw);
}
}
Object.prototype.fooBarBaz = 20; // Make for-in go over the prototype chain to the top.
{
let target = {};
let called = false;
let handler = {
getOwnPropertyDescriptor: function() {
called = true;
return undefined;
}
};
let proxy = new Proxy(target, handler);
for (let i = 0; i < 1000; i++) {
let set = new Set();
for (let p in proxy) {
set.add(p);
}
assert(set.has("fooBarBaz"));
assert(called);
called = false;
}
}
{
let target = {};
let called = false;
let handler = {
getOwnPropertyDescriptor: function() {
called = true;
return undefined;
}
};
let proxy = new Proxy(target, handler);
let proxyish = Object.create(proxy, {
x: {value: 20, enumerable: true},
y: {value: 20, enumerable: true}
});
for (let i = 0; i < 1000; i++) {
let set = new Set;
for (let p in proxyish) {
set.add(p);
}
assert(set.has("x"));
assert(set.has("y"));
assert(set.has("fooBarBaz"));
assert(called);
called = false;
}
}
{
let target = {};
Object.defineProperty(target, "x", {
enumerable: false,
configurable: false,
writable: true,
value: 50
});
let handler = {
getOwnPropertyDescriptor: function(theTarget, propName) {
return {enumerable: false, value: 45};
}
};
let proxy = new Proxy(target, handler);
for (let i = 0; i < 500; i++) {
let threw = false;
try {
Object.getOwnPropertyDescriptor(proxy, "x");
} catch(e) {
assert(e.toString() === "TypeError: Result from 'getOwnPropertyDescriptor' can't be non-configurable and non-writable when the target's property is writable");
threw = true;
}
assert(threw);
}
}
{
let target = {};
Object.defineProperty(target, "x", {
enumerable: true,
configurable: true,
writable: true
});
let handler = {
getOwnPropertyDescriptor: function(theTarget, propName) {
return {configurable: true, value: 45, enumerable: true};
}
};
let proxy = new Proxy(target, handler);
for (let i = 0; i < 500; i++) {
let desc = Object.getOwnPropertyDescriptor(proxy, "x");
assert(desc.configurable === true);
assert(desc.enumerable === true);
assert(desc.writable === false);
assert(desc.value === 45);
}
}
{
let target = {};
let handler = {
getOwnPropertyDescriptor: function(theTarget, propName) {
return {configurable: true, value: 45, enumerable: true};
}
};
let proxy = new Proxy(target, handler);
for (let i = 0; i < 500; i++) {
let desc = Object.getOwnPropertyDescriptor(proxy, "x");
assert(desc.configurable === true);
assert(desc.enumerable === true);
assert(desc.writable === false);
assert(desc.value === 45);
}
}
{
let target = {};
Object.defineProperty(target, "x", {
get: function() { return 25; },
set: function() { return 50; },
configurable: false
});
let handler = {
getOwnPropertyDescriptor: function(theTarget, propName) {
return {configurable: false, set:function(){}, get:function(){} };
}
};
let proxy = new Proxy(target, handler);
for (let i = 0; i < 500; i++) {
let threw = false;
try {
Object.getOwnPropertyDescriptor(proxy, "x");
} catch(e) {
threw = true;
assert(e.toString() === "TypeError: Result from 'getOwnPropertyDescriptor' fails the IsCompatiblePropertyDescriptor test");
}
assert(threw);
}
}
{
let target = {};
Object.defineProperty(target, "x", {
get: function() { return 25; },
set: function() { return 50; },
configurable: true
});
let a = function() { };
let b = function() {}
let handler = {
getOwnPropertyDescriptor: function(theTarget, propName) {
return {configurable: true, set: a, get: b };
}
};
let proxy = new Proxy(target, handler);
for (let i = 0; i < 500; i++) {
let result = Object.getOwnPropertyDescriptor(proxy, "x");
assert(result.configurable);
assert(result.set === a);
assert(result.get === b);
}
}
{
let target = {};
Object.defineProperty(target, "x", {
get: function() { return 25; },
set: function() { return 50; },
configurable: false
});
let handler = {
getOwnPropertyDescriptor: function(theTarget, propName) {
return {configurable: false, set:function(){}, get:function(){} };
}
};
let proxy = new Proxy(target, handler);
for (let i = 0; i < 500; i++) {
let threw = false;
try {
Object.getOwnPropertyDescriptor(proxy, "x");
} catch(e) {
threw = true;
assert(e.toString() === "TypeError: Result from 'getOwnPropertyDescriptor' fails the IsCompatiblePropertyDescriptor test");
}
assert(threw);
}
}
{
let target = {};
let setter = function() { };
let getter = function() { };
Object.defineProperty(target, "x", {
get: getter,
set: setter,
configurable: false
});
let handler = {
getOwnPropertyDescriptor: function(theTarget, propName) {
return {
configurable: false,
set: setter,
get: getter
};
}
};
let proxy = new Proxy(target, handler);
for (let i = 0; i < 500; i++) {
let desc = Object.getOwnPropertyDescriptor(proxy, "x");
assert(desc.configurable === false);
assert(desc.get === getter);
assert(desc.set === setter);
assert(desc.enumerable === false);
assert(desc.writable === undefined);
}
}