OLD | NEW |
(Empty) | |
| 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. |
OLD | NEW |