| function assert(b) { |
| if (!b) |
| throw new Error("Bad assertion"); |
| } |
| |
| { |
| let target = {}; |
| let handler = { |
| defineProperty: 25 |
| }; |
| |
| let proxy = new Proxy(target, handler); |
| for (let i = 0; i < 500; i++) { |
| let threw = false; |
| try { |
| Object.defineProperty(proxy, "x", { |
| enumerable: true, |
| configurable: true, |
| value: 55 |
| }); |
| } catch(e) { |
| threw = true; |
| assert(e.toString() === "TypeError: 'defineProperty' property of a Proxy's handler should be callable"); |
| } |
| |
| assert(threw); |
| } |
| |
| } |
| |
| { |
| let target = {}; |
| let error = null; |
| let handler = { |
| get defineProperty() { |
| error = new Error; |
| throw error; |
| } |
| }; |
| |
| let proxy = new Proxy(target, handler); |
| for (let i = 0; i < 500; i++) { |
| let threw = false; |
| try { |
| Object.defineProperty(proxy, "x", { |
| enumerable: true, |
| configurable: true, |
| value: 55 |
| }); |
| } catch(e) { |
| threw = true; |
| assert(e === error); |
| } |
| |
| assert(threw); |
| } |
| } |
| |
| { |
| let target = {}; |
| let error = null; |
| let handler = { |
| defineProperty: function() { |
| error = new Error; |
| throw error; |
| } |
| }; |
| |
| let proxy = new Proxy(target, handler); |
| for (let i = 0; i < 500; i++) { |
| let threw = false; |
| try { |
| Object.defineProperty(proxy, "x", { |
| enumerable: true, |
| configurable: true, |
| value: 55 |
| }); |
| } catch(e) { |
| threw = true; |
| assert(e === error); |
| } |
| |
| assert(threw); |
| } |
| } |
| |
| { |
| let target = {}; |
| let handler = { |
| defineProperty: null |
| }; |
| |
| let proxy = new Proxy(target, handler); |
| for (let i = 0; i < 500; i++) { |
| Object.defineProperty(proxy, "x", { |
| enumerable: true, |
| configurable: true, |
| value: i |
| }); |
| |
| for (let obj of [target, proxy]) { |
| let pDesc = Object.getOwnPropertyDescriptor(obj, "x"); |
| assert(pDesc.value === i); |
| assert(pDesc.configurable === true); |
| assert(pDesc.enumerable === true); |
| } |
| } |
| } |
| |
| { |
| let target = {}; |
| let handler = { |
| defineProperty: undefined |
| }; |
| |
| let proxy = new Proxy(target, handler); |
| for (let i = 0; i < 500; i++) { |
| let result = Reflect.defineProperty(proxy, "x", { |
| enumerable: true, |
| configurable: true, |
| value: i |
| }); |
| assert(result); |
| |
| for (let obj of [target, proxy]) { |
| let pDesc = Object.getOwnPropertyDescriptor(obj, "x"); |
| assert(pDesc.value === i); |
| assert(pDesc.configurable === true); |
| assert(pDesc.enumerable === true); |
| } |
| } |
| } |
| |
| { |
| let target = {}; |
| let called = false; |
| let handler = { |
| defineProperty: function(theTarget, propName, descriptor) { |
| called = true; |
| return Reflect.defineProperty(theTarget, propName, descriptor); |
| } |
| }; |
| |
| let proxy = new Proxy(target, handler); |
| for (let i = 0; i < 500; i++) { |
| let result = Reflect.defineProperty(proxy, "x", { |
| enumerable: true, |
| configurable: true, |
| value: i |
| }); |
| assert(result); |
| assert(called); |
| called = false; |
| |
| for (let obj of [target, proxy]) { |
| let pDesc = Object.getOwnPropertyDescriptor(obj, "x"); |
| assert(pDesc.value === i); |
| assert(pDesc.configurable === true); |
| assert(pDesc.enumerable === true); |
| } |
| } |
| } |
| |
| { |
| let target = {}; |
| let called = false; |
| let handler = { |
| defineProperty: function(theTarget, propName, descriptor) { |
| called = true; |
| Reflect.defineProperty(theTarget, propName, descriptor); |
| return false; |
| } |
| }; |
| |
| let proxy = new Proxy(target, handler); |
| for (let i = 0; i < 500; i++) { |
| let result = Reflect.defineProperty(proxy, "x", { |
| enumerable: true, |
| configurable: true, |
| value: i |
| }); |
| assert(!result); |
| assert(called); |
| called = false; |
| |
| for (let obj of [target, proxy]) { |
| let pDesc = Object.getOwnPropertyDescriptor(obj, "x"); |
| assert(pDesc.value === i); |
| assert(pDesc.configurable === true); |
| assert(pDesc.enumerable === true); |
| } |
| } |
| } |
| |
| { |
| let target = {}; |
| let called = false; |
| let handler = { |
| defineProperty: function(theTarget, propName, descriptor) { |
| called = true; |
| return true; |
| } |
| }; |
| |
| let proxy = new Proxy(target, handler); |
| for (let i = 0; i < 500; i++) { |
| let threw = false; |
| try { |
| Reflect.defineProperty(proxy, "x", { |
| enumerable: true, |
| configurable: false, |
| value: i |
| }); |
| } catch(e) { |
| threw = true; |
| assert(e.toString() === "TypeError: Proxy's 'defineProperty' trap returned true for a non-configurable field even though getOwnPropertyDescriptor of the Proxy's target returned undefined"); |
| } |
| assert(called); |
| assert(threw); |
| called = false; |
| } |
| } |
| |
| { |
| let target = {}; |
| let called = false; |
| Object.preventExtensions(target); |
| let handler = { |
| defineProperty: function(theTarget, propName, descriptor) { |
| called = true; |
| return true; |
| } |
| }; |
| |
| let proxy = new Proxy(target, handler); |
| for (let i = 0; i < 500; i++) { |
| let threw = false; |
| try { |
| Reflect.defineProperty(proxy, "x", { |
| enumerable: true, |
| configurable: true, |
| value: i |
| }); |
| } catch(e) { |
| threw = true; |
| assert(e.toString() === "TypeError: Proxy's 'defineProperty' trap returned true even though getOwnPropertyDescriptor of the Proxy's target returned undefined and the target is non-extensible"); |
| } |
| assert(called); |
| assert(threw); |
| called = false; |
| } |
| } |
| |
| { |
| let target = {}; |
| let called = false; |
| let handler = { |
| defineProperty: function(theTarget, propName, descriptor) { |
| assert(propName === "x"); |
| assert(descriptor.configurable === false); |
| called = true; |
| return Reflect.defineProperty(theTarget, "x", { |
| enumerable: true, |
| configurable: true, |
| value: descriptor.value |
| }); |
| } |
| }; |
| |
| let proxy = new Proxy(target, handler); |
| for (let i = 0; i < 500; i++) { |
| try { |
| Reflect.defineProperty(proxy, "x", { |
| enumerable: true, |
| configurable: false, |
| value: i |
| }); |
| } catch(e) { |
| threw = true; |
| assert(e.toString() === "TypeError: Proxy's 'defineProperty' trap did not define a non-configurable property on its target even though the input descriptor to the trap said it must do so"); |
| } |
| assert(called); |
| assert(threw); |
| called = false; |
| |
| for (let obj of [target, proxy]) { |
| let pDesc = Object.getOwnPropertyDescriptor(obj, "x"); |
| assert(pDesc.value === i); |
| assert(pDesc.configurable === true); |
| assert(pDesc.enumerable === true); |
| } |
| } |
| } |
| |
| { |
| let target = {}; |
| let called = false; |
| Object.defineProperty(target, "x", { |
| configurable: false, |
| writable: true, |
| value: 55 |
| }); |
| let handler = { |
| defineProperty: function(theTarget, propName, descriptor) { |
| assert(propName === "x"); |
| assert(descriptor.configurable === true); |
| called = true; |
| Reflect.defineProperty(theTarget, "x", { |
| enumerable: true, |
| configurable: true, |
| value: descriptor.value |
| }); |
| return true; |
| } |
| }; |
| |
| let proxy = new Proxy(target, handler); |
| for (let i = 0; i < 500; i++) { |
| let threw = false; |
| try { |
| Reflect.defineProperty(proxy, "x", { |
| configurable: true, |
| writable: false, |
| value: 45 |
| }); |
| } catch(e) { |
| threw = true; |
| assert(e.toString() === "TypeError: Proxy's 'defineProperty' trap did not define a property on its target that is compatible with the trap's input descriptor"); |
| } |
| assert(called); |
| assert(threw); |
| called = false; |
| |
| for (let obj of [target, proxy]) { |
| let pDesc = Object.getOwnPropertyDescriptor(obj, "x"); |
| assert(pDesc.value === 55); |
| assert(pDesc.configurable === false); |
| } |
| } |
| } |
| |
| { |
| let target = {}; |
| let called = false; |
| Object.defineProperty(target, "x", { |
| configurable: false, |
| writable: true, |
| value: 55 |
| }); |
| let handler = { |
| defineProperty: function(theTarget, propName, descriptor) { |
| assert(propName === "x"); |
| assert(descriptor.configurable === true); |
| called = true; |
| Reflect.defineProperty(theTarget, "x", descriptor); |
| return true; |
| } |
| }; |
| |
| let proxy = new Proxy(target, handler); |
| for (let i = 0; i < 500; i++) { |
| let threw = false; |
| try { |
| Reflect.defineProperty(proxy, "x", { |
| configurable: true, |
| set:function(){}, |
| get:function(){} |
| }); |
| } catch(e) { |
| threw = true; |
| assert(e.toString() === "TypeError: Proxy's 'defineProperty' trap did not define a property on its target that is compatible with the trap's input descriptor"); |
| } |
| assert(called); |
| assert(threw); |
| called = false; |
| |
| for (let obj of [target, proxy]) { |
| let pDesc = Object.getOwnPropertyDescriptor(obj, "x"); |
| assert(pDesc.value === 55); |
| assert(pDesc.configurable === false); |
| } |
| } |
| } |
| |
| { |
| let target = {}; |
| let called = false; |
| let setter = function(){}; |
| let getter = function(){}; |
| Object.defineProperty(target, "x", { |
| configurable: false, |
| get: getter, |
| set: setter |
| }); |
| let handler = { |
| defineProperty: function(theTarget, propName, descriptor) { |
| assert(propName === "x"); |
| assert(descriptor.configurable === true); |
| called = true; |
| Reflect.defineProperty(theTarget, "x", descriptor); |
| return true; |
| } |
| }; |
| |
| let proxy = new Proxy(target, handler); |
| for (let i = 0; i < 500; i++) { |
| let threw = false; |
| try { |
| Reflect.defineProperty(proxy, "x", { |
| configurable: true, |
| value: 45 |
| }); |
| } catch(e) { |
| threw = true; |
| assert(e.toString() === "TypeError: Proxy's 'defineProperty' trap did not define a property on its target that is compatible with the trap's input descriptor"); |
| } |
| assert(called); |
| assert(threw); |
| called = false; |
| |
| for (let obj of [target, proxy]) { |
| let pDesc = Object.getOwnPropertyDescriptor(obj, "x"); |
| assert(pDesc.value === undefined); |
| assert(pDesc.configurable === false); |
| assert(pDesc.get === getter); |
| assert(pDesc.set === setter); |
| } |
| } |
| } |
| |
| { |
| let target = {}; |
| let called = false; |
| let setter = function(){}; |
| let getter = function(){}; |
| Object.defineProperty(target, "x", { |
| configurable: false, |
| get: getter, |
| set: setter |
| }); |
| let handler = { |
| defineProperty: function(theTarget, propName, descriptor) { |
| assert(propName === "x"); |
| assert(descriptor.configurable === true); |
| called = true; |
| return Reflect.defineProperty(theTarget, "x", descriptor); |
| } |
| }; |
| |
| let proxy = new Proxy(target, handler); |
| for (let i = 0; i < 500; i++) { |
| let result = Reflect.defineProperty(proxy, "x", { |
| configurable: true, |
| value: 45 |
| }); |
| assert(!result); |
| assert(called); |
| called = false; |
| |
| for (let obj of [target, proxy]) { |
| let pDesc = Object.getOwnPropertyDescriptor(obj, "x"); |
| assert(pDesc.value === undefined); |
| assert(pDesc.configurable === false); |
| assert(pDesc.get === getter); |
| assert(pDesc.set === setter); |
| } |
| } |
| } |
| |
| { |
| let error = false; |
| let target = new Proxy({}, { |
| getOwnPropertyDescriptor: function() { |
| error = new Error; |
| throw error; |
| } |
| }); |
| |
| let handler = { |
| defineProperty: function(theTarget, propName, descriptor) { |
| return Reflect.defineProperty(theTarget, propName, descriptor); |
| } |
| }; |
| |
| let proxy = new Proxy(target, handler); |
| for (let i = 0; i < 500; i++) { |
| let threw = false; |
| try { |
| Reflect.defineProperty(proxy, "x", { |
| configurable: true, |
| value: 45 |
| }); |
| } catch(e) { |
| threw = true; |
| assert(e === error); |
| } |
| assert(threw); |
| } |
| } |
| |
| { |
| let target = {}; |
| Reflect.defineProperty(target, "x", { |
| writable: true, |
| configurable: false, |
| value: 55 |
| }); |
| |
| let handler = { |
| defineProperty: function(theTarget, propName, descriptor) { |
| assert(theTarget === target); |
| return Reflect.defineProperty(theTarget, propName, descriptor); |
| } |
| }; |
| |
| let proxy = new Proxy(target, handler); |
| for (let i = 0; i < 500; i++) { |
| let result = Reflect.defineProperty(proxy, "x", { |
| configurable: false, |
| value: 55 |
| }); |
| assert(result); |
| assert(target.x === 55); |
| delete target.x; |
| assert(target.x === 55); |
| } |
| } |
| |
| { |
| let target = {}; |
| Reflect.defineProperty(target, "x", { |
| writable: false, |
| configurable: false, |
| value: 55 |
| }); |
| |
| let handler = { |
| defineProperty: function(theTarget, propName, descriptor) { |
| assert(theTarget === target); |
| return Reflect.defineProperty(theTarget, propName, descriptor); |
| } |
| }; |
| |
| let proxy = new Proxy(target, handler); |
| for (let i = 0; i < 500; i++) { |
| let result = Reflect.defineProperty(proxy, "x", { |
| writable: false, |
| configurable: false, |
| value: 55 |
| }); |
| assert(result); |
| assert(target.x === 55); |
| delete target.x; |
| assert(target.x === 55); |
| } |
| } |
| |
| { |
| let target = {}; |
| Reflect.defineProperty(target, "x", { |
| writable: false, |
| configurable: false, |
| value: 55 |
| }); |
| |
| let handler = { |
| defineProperty: function(theTarget, propName, descriptor) { |
| assert(theTarget === target); |
| return Reflect.defineProperty(theTarget, propName, descriptor); |
| } |
| }; |
| |
| let proxy = new Proxy(target, handler); |
| for (let i = 0; i < 500; i++) { |
| let result = Reflect.defineProperty(proxy, "x", { |
| writable: false, |
| configurable: false, |
| value: "not 55" |
| }); |
| assert(!result); |
| assert(target.x === 55); |
| delete target.x; |
| assert(target.x === 55); |
| } |
| } |
| |
| { |
| let target = {}; |
| Reflect.defineProperty(target, "x", { |
| writable: false, |
| configurable: false, |
| value: 55 |
| }); |
| |
| let handler = { |
| defineProperty: function(theTarget, propName, descriptor) { |
| assert(theTarget === target); |
| return Reflect.defineProperty(theTarget, propName, descriptor); |
| } |
| }; |
| |
| let proxy = new Proxy(target, handler); |
| for (let i = 0; i < 500; i++) { |
| let result = Reflect.defineProperty(proxy, "x", { |
| writable: true, |
| configurable: false, |
| value: "whatever value goes here" |
| }); |
| assert(!result); |
| assert(target.x === 55); |
| delete target.x; |
| assert(target.x === 55); |
| } |
| } |