1 // Copyright 2015 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Flags: --harmony-proxies 6 7 var target = {}; 8 var configurable_desc = { 9 value: 123, 10 configurable: true, 11 writable: true, 12 enumerable: false, 13 }; 14 Object.defineProperty(target, "configurable", configurable_desc); 15 var nonconfigurable_desc = { 16 value: 234, 17 configurable: false, 18 writable: false, 19 enumerable: true 20 } 21 Object.defineProperty(target, "nonconfigurable", nonconfigurable_desc); 22 23 var proxied_desc = { 24 value: 345, 25 configurable: true 26 }; 27 28 var handler = { 29 "getOwnPropertyDescriptor": function(target, name) { 30 if (name === "proxied") { 31 return proxied_desc; 32 } 33 if (name === "return_null") { 34 return null; 35 } 36 return Object.getOwnPropertyDescriptor(target, name); 37 } 38 }; 39 40 var proxy = new Proxy(target, handler); 41 var proxy_without_handler = new Proxy(target, {}); 42 43 // Checking basic functionality: 44 45 assertEquals(configurable_desc, 46 Object.getOwnPropertyDescriptor(proxy, "configurable")); 47 assertEquals(nonconfigurable_desc, 48 Object.getOwnPropertyDescriptor(proxy, "nonconfigurable")); 49 assertEquals({ value: proxied_desc.value, 50 configurable: proxied_desc.configurable, 51 enumerable: false, 52 writable: false }, 53 Object.getOwnPropertyDescriptor(proxy, "proxied")); 54 assertEquals(configurable_desc, 55 Object.getOwnPropertyDescriptor(proxy_without_handler, 56 "configurable")); 57 assertEquals(nonconfigurable_desc, 58 Object.getOwnPropertyDescriptor(proxy_without_handler, 59 "nonconfigurable")); 60 61 assertThrows('Object.getOwnPropertyDescriptor(proxy, "return_null")'); 62 63 handler.getOwnPropertyDescriptor = undefined; 64 assertEquals(configurable_desc, 65 Object.getOwnPropertyDescriptor(proxy, "configurable")); 66 67 // Checking invariants mentioned explicitly by the ES spec: 68 69 // (Inv-1) "A property cannot be reported as non-existent, if it exists as a 70 // non-configurable own property of the target object." 71 handler.getOwnPropertyDescriptor = function(target, name) { return undefined; }; 72 assertThrows('Object.getOwnPropertyDescriptor(proxy, "nonconfigurable")'); 73 assertEquals(undefined, Object.getOwnPropertyDescriptor(proxy, "configurable")); 74 75 // (Inv-2) "A property cannot be reported as non-configurable, if it does not 76 // exist as an own property of the target object or if it exists as a 77 // configurable own property of the target object." 78 handler.getOwnPropertyDescriptor = function(target, name) { 79 return {value: 234, configurable: false, enumerable: true}; 80 }; 81 assertThrows('Object.getOwnPropertyDescriptor(proxy, "nonexistent")'); 82 assertThrows('Object.getOwnPropertyDescriptor(proxy, "configurable")'); 83 assertEquals( 84 false, 85 Object.getOwnPropertyDescriptor(proxy, "nonconfigurable").configurable); 86 87 // (Inv-3) "A property cannot be reported as non-existent, if it exists as an 88 // own property of the target object and the target object is not extensible." 89 Object.seal(target); 90 handler.getOwnPropertyDescriptor = function(target, name) { return undefined; }; 91 assertThrows('Object.getOwnPropertyDescriptor(proxy, "configurable")'); 92 assertThrows('Object.getOwnPropertyDescriptor(proxy, "nonconfigurable")'); 93 assertEquals(undefined, Object.getOwnPropertyDescriptor(proxy, "nonexistent")); 94 95 // (Inv-4) "A property cannot be reported as existent, if it does not exist as 96 // an own property of the target object and the target object is not 97 // extensible." 98 var existent_desc = {value: "yes"}; 99 handler.getOwnPropertyDescriptor = function() { return existent_desc; }; 100 assertThrows('Object.getOwnPropertyDescriptor(proxy, "nonexistent")'); 101 assertEquals( 102 {value: "yes", writable: false, enumerable: false, configurable: false}, 103 Object.getOwnPropertyDescriptor(proxy, "configurable")); 104 105 // Checking individual bailout points in the implementation: 106 107 // Step 6: Trap is not callable. 108 handler.getOwnPropertyDescriptor = {}; 109 assertThrows('Object.getOwnPropertyDescriptor(proxy, "configurable")'); 110 111 // Step 8: Trap throws. 112 handler.getOwnPropertyDescriptor = function() { throw "ball"; }; 113 assertThrows('Object.getOwnPropertyDescriptor(proxy, "configurable")'); 114 115 // Step 9: Trap result is neither undefined nor an object. 116 handler.getOwnPropertyDescriptor = function() { return 1; } 117 assertThrows('Object.getOwnPropertyDescriptor(proxy, "configurable")'); 118 119 // Step 11b: See (Inv-1) above. 120 // Step 11e: See (Inv-3) above. 121 122 // Step 16: Incompatible PropertyDescriptor; a non-configurable property 123 // cannot be reported as configurable. (Inv-4) above checks more cases. 124 handler.getOwnPropertyDescriptor = function(target, name) { 125 return {value: 456, configurable: true, writable: true} 126 }; 127 assertThrows('Object.getOwnPropertyDescriptor(proxy, "nonconfigurable")'); 128 129 // Step 17: See (Inv-2) above. 130