Home | History | Annotate | Download | only in harmony
      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