Home | History | Annotate | Download | only in harmony
      1 // Copyright 2011 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 // Flags: --harmony-proxies
     29 
     30 
     31 // Helper.
     32 
     33 function TestWithProxies(test, x, y, z) {
     34   test(function(h){ return new Proxy({}, h) }, x, y, z)
     35   test(function(h) {
     36     return new Proxy(function() {}, h)
     37   }, x, y, z)
     38 }
     39 
     40 
     41 // Iterate over a proxy.
     42 
     43 Array.prototype.values = function() { return this[Symbol.iterator]() }
     44 
     45 function TestForIn(properties, handler) {
     46   TestWithProxies(TestForIn2, properties, handler)
     47 }
     48 
     49 function TestForIn2(create, properties, handler) {
     50   var p = create(handler)
     51   var found = []
     52   for (var x in p) found.push(x)
     53   assertArrayEquals(properties, found)
     54 }
     55 
     56 TestForIn(["0", "a"], {
     57   enumerate() { return ["0", "a"].values() },
     58   has(target, property) { return true }
     59 })
     60 
     61 TestForIn(["null", "a"], {
     62   enumerate() { return this.enumerate2() },
     63   enumerate2() { return ["null", "a"].values() },
     64   has(target, property) { return true }
     65 })
     66 
     67 TestForIn(["b", "a", "0", "c"], new Proxy({}, {
     68   get: function(pr, pk) {
     69     return function() { return ["b", "a", "0", "c"].values() }
     70   }
     71 }))
     72 
     73 
     74 
     75 // Iterate over an object with a proxy prototype.
     76 
     77 function TestForInDerived(properties, handler) {
     78   TestWithProxies(TestForInDerived2, properties, handler)
     79 }
     80 
     81 function TestForInDerived2(create, properties, handler) {
     82   var p = create(handler)
     83   var o = Object.create(p)
     84   o.z = 0
     85   var found = []
     86   for (var x in o) found.push(x)
     87   assertArrayEquals(["z"].concat(properties), found)
     88 
     89   var oo = Object.create(o)
     90   oo.y = 0
     91   var found = []
     92   for (var x in oo) found.push(x)
     93   assertArrayEquals(["y", "z"].concat(properties), found)
     94 }
     95 
     96 TestForInDerived(["0", "a"], {
     97   enumerate: function() { return ["0", "a"].values() },
     98   has: function(t, k) { return k == "0" || k == "a" }
     99 })
    100 
    101 TestForInDerived(["null", "a"], {
    102   enumerate: function() { return this.enumerate2() },
    103   enumerate2: function() { return ["null", "a"].values() },
    104   has: function(t, k) { return k == "null" || k == "a" }
    105 })
    106 
    107 
    108 
    109 // Throw exception in enumerate trap.
    110 
    111 function TestForInThrow(handler) {
    112   TestWithProxies(TestForInThrow2, handler)
    113 }
    114 
    115 function TestForInThrow2(create, handler) {
    116   var p = create(handler)
    117   var o = Object.create(p)
    118   assertThrowsEquals(function(){ for (var x in p) {} }, "myexn")
    119   assertThrowsEquals(function(){ for (var x in o) {} }, "myexn")
    120 }
    121 
    122 TestForInThrow({
    123   enumerate: function() { throw "myexn" }
    124 })
    125 
    126 TestForInThrow({
    127   enumerate: function() { return this.enumerate2() },
    128   enumerate2: function() { throw "myexn" }
    129 })
    130 
    131 TestForInThrow(new Proxy({}, {
    132   get: function(pr, pk) {
    133     return function() { throw "myexn" }
    134   }
    135 }));
    136 
    137 (function() {
    138   var p = new Proxy({}, {enumerate:function() { return ["0"].values(); }});
    139   var o = [0];
    140   o.__proto__ = p;
    141   var keys = [];
    142   for (var k in o) { keys.push(k); };
    143   assertEquals(["0"], keys);
    144 })();
    145 
    146 (function () {
    147   var p = new Proxy({}, {ownKeys: function() { return ["1", Symbol(), "2"] }});
    148   assertEquals(["1","2"], Object.getOwnPropertyNames(p));
    149 })();
    150