mirror of
https://github.com/RGBCube/serenity
synced 2025-07-13 19:37:34 +00:00
LibJS: Add Proxy objects
Includes all traps except the following: [[Call]], [[Construct]], [[OwnPropertyKeys]]. An important implication of this commit is that any call to any virtual Object method has the potential to throw an exception. These methods were not checked in this commit -- a future commit will have to protect these various method calls throughout the codebase.
This commit is contained in:
parent
58a72e9b81
commit
39ad42defd
29 changed files with 1697 additions and 54 deletions
107
Libraries/LibJS/Tests/Proxy.handler-defineProperty.js
Normal file
107
Libraries/LibJS/Tests/Proxy.handler-defineProperty.js
Normal file
|
@ -0,0 +1,107 @@
|
|||
load("test-common.js");
|
||||
|
||||
try {
|
||||
let p = new Proxy({}, { defineProperty: null });
|
||||
assert(Object.defineProperty(p, "foo", {}) === p);
|
||||
p = new Proxy({}, { defineProperty: undefined });
|
||||
assert(Object.defineProperty(p, "foo", {}) === p);
|
||||
p = new Proxy({}, {});
|
||||
assert(Object.defineProperty(p, "foo", {}) == p);
|
||||
|
||||
let o = {};
|
||||
p = new Proxy(o, {
|
||||
defineProperty(target, name, descriptor) {
|
||||
assert(target === o);
|
||||
assert(name === "foo");
|
||||
assert(descriptor.configurable === true);
|
||||
assert(descriptor.enumerable === undefined);
|
||||
assert(descriptor.writable === true);
|
||||
assert(descriptor.value === 10);
|
||||
assert(descriptor.get === undefined);
|
||||
assert(descriptor.set === undefined);
|
||||
return true;
|
||||
},
|
||||
});
|
||||
|
||||
Object.defineProperty(p, "foo", { configurable: true, writable: true, value: 10 });
|
||||
|
||||
p = new Proxy(o, {
|
||||
defineProperty(target, name, descriptor) {
|
||||
if (target[name] === undefined)
|
||||
Object.defineProperty(target, name, descriptor);
|
||||
return true;
|
||||
},
|
||||
});
|
||||
|
||||
Object.defineProperty(p, "foo", { value: 10, enumerable: true, configurable: false, writable: true });
|
||||
let d = Object.getOwnPropertyDescriptor(p, "foo");
|
||||
assert(d.enumerable === true);
|
||||
assert(d.configurable === false);
|
||||
assert(d.writable === true);
|
||||
assert(d.value === 10);
|
||||
assert(d.get === undefined);
|
||||
assert(d.set === undefined);
|
||||
|
||||
Object.defineProperty(p, "foo", { value: 20, enumerable: true, configurable: false, writable: true });
|
||||
d = Object.getOwnPropertyDescriptor(p, "foo");
|
||||
assert(d.enumerable === true);
|
||||
assert(d.configurable === false);
|
||||
assert(d.writable === true);
|
||||
assert(d.value === 10);
|
||||
assert(d.get === undefined);
|
||||
assert(d.set === undefined);
|
||||
|
||||
|
||||
// Invariants
|
||||
|
||||
p = new Proxy({}, {
|
||||
defineProperty() { return false; }
|
||||
});
|
||||
|
||||
assertThrowsError(() => {
|
||||
Object.defineProperty(p, "foo", {});
|
||||
}, {
|
||||
error: TypeError,
|
||||
message: "Proxy handler's defineProperty method returned false",
|
||||
});
|
||||
|
||||
o = {};
|
||||
Object.preventExtensions(o);
|
||||
p = new Proxy(o, {
|
||||
defineProperty() {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
assertThrowsError(() => {
|
||||
Object.defineProperty(p, "foo", {});
|
||||
}, {
|
||||
error: TypeError,
|
||||
message: "Proxy handler's defineProperty trap violates invariant: a property cannot be reported as being defined if the property does not exist on the target and the target is non-extensible",
|
||||
});
|
||||
|
||||
o = {};
|
||||
Object.defineProperty(o, "foo", { value: 10, configurable: true });
|
||||
p = new Proxy(o, {
|
||||
defineProperty() {
|
||||
return true;
|
||||
},
|
||||
});
|
||||
|
||||
assertThrowsError(() => {
|
||||
Object.defineProperty(p, "bar", { value: 6, configurable: false });
|
||||
}, {
|
||||
error: TypeError,
|
||||
message: "Proxy handler's defineProperty trap violates invariant: a property cannot be defined as non-configurable if it does not already exist on the target object",
|
||||
});
|
||||
|
||||
assertThrowsError(() => {
|
||||
Object.defineProperty(p, "foo", { value: 6, configurable: false });
|
||||
}, {
|
||||
error: TypeError,
|
||||
message: "Proxy handler's defineProperty trap violates invariant: a property cannot be defined as non-configurable if it already exists on the target object as a configurable property",
|
||||
});
|
||||
|
||||
console.log("PASS");
|
||||
} catch (e) {
|
||||
console.log("FAIL: " + e);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue