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(Proxy.create, x, y, z)
     35   test(function(h) {return Proxy.createFunction(h, function() {})}, x, y, z)
     36 }
     37 
     38 
     39 // Iterate over a proxy.
     40 
     41 function TestForIn(properties, handler) {
     42   TestWithProxies(TestForIn2, properties, handler)
     43 }
     44 
     45 function TestForIn2(create, properties, handler) {
     46   var p = create(handler)
     47   var found = []
     48   for (var x in p) found.push(x)
     49   assertArrayEquals(properties, found)
     50 }
     51 
     52 TestForIn(["0", "a"], {
     53   enumerate: function() { return [0, "a"] }
     54 })
     55 
     56 TestForIn(["null", "a"], {
     57   enumerate: function() { return this.enumerate2() },
     58   enumerate2: function() { return [null, "a"] }
     59 })
     60 
     61 TestForIn(["b", "d"], {
     62   getPropertyNames: function() { return ["a", "b", "c", "d", "e"] },
     63   getPropertyDescriptor: function(k) {
     64     switch (k) {
     65       case "a": return {enumerable: false, value: "3"};
     66       case "b": return {enumerable: true, get get() {}};
     67       case "c": return {value: 4};
     68       case "d": return {get enumerable() { return true }};
     69       default: return undefined;
     70     }
     71   }
     72 })
     73 
     74 TestForIn(["b", "a", "0", "c"], Proxy.create({
     75   get: function(pr, pk) {
     76     return function() { return ["b", "a", 0, "c"] }
     77   }
     78 }))
     79 
     80 
     81 
     82 // Iterate over an object with a proxy prototype.
     83 
     84 function TestForInDerived(properties, handler) {
     85   TestWithProxies(TestForInDerived2, properties, handler)
     86 }
     87 
     88 function TestForInDerived2(create, properties, handler) {
     89   var p = create(handler)
     90   var o = Object.create(p)
     91   o.z = 0
     92   var found = []
     93   for (var x in o) found.push(x)
     94   assertArrayEquals(["z"].concat(properties), found)
     95 
     96   var oo = Object.create(o)
     97   oo.y = 0
     98   var found = []
     99   for (var x in oo) found.push(x)
    100   assertArrayEquals(["y", "z"].concat(properties), found)
    101 }
    102 
    103 TestForInDerived(["0", "a"], {
    104   enumerate: function() { return [0, "a"] },
    105   getPropertyDescriptor: function(k) {
    106     return k == "0" || k == "a" ? {} : undefined
    107   }
    108 })
    109 
    110 TestForInDerived(["null", "a"], {
    111   enumerate: function() { return this.enumerate2() },
    112   enumerate2: function() { return [null, "a"] },
    113   getPropertyDescriptor: function(k) {
    114     return k == "null" || k == "a" ? {} : undefined
    115   }
    116 })
    117 
    118 TestForInDerived(["b", "d"], {
    119   getPropertyNames: function() { return ["a", "b", "c", "d", "e"] },
    120   getPropertyDescriptor: function(k) {
    121     switch (k) {
    122       case "a": return {enumerable: false, value: "3"};
    123       case "b": return {enumerable: true, get get() {}};
    124       case "c": return {value: 4};
    125       case "d": return {get enumerable() { return true }};
    126       default: return undefined;
    127     }
    128   }
    129 })
    130 
    131 
    132 
    133 // Throw exception in enumerate trap.
    134 
    135 function TestForInThrow(handler) {
    136   TestWithProxies(TestForInThrow2, handler)
    137 }
    138 
    139 function TestForInThrow2(create, handler) {
    140   var p = create(handler)
    141   var o = Object.create(p)
    142   assertThrows(function(){ for (var x in p) {} }, "myexn")
    143   assertThrows(function(){ for (var x in o) {} }, "myexn")
    144 }
    145 
    146 TestForInThrow({
    147   enumerate: function() { throw "myexn" }
    148 })
    149 
    150 TestForInThrow({
    151   enumerate: function() { return this.enumerate2() },
    152   enumerate2: function() { throw "myexn" }
    153 })
    154 
    155 TestForInThrow({
    156   getPropertyNames: function() { throw "myexn" }
    157 })
    158 
    159 TestForInThrow({
    160   getPropertyNames: function() { return ["a"] },
    161   getPropertyDescriptor: function() { throw "myexn" }
    162 })
    163 
    164 TestForInThrow(Proxy.create({
    165   get: function(pr, pk) {
    166     return function() { throw "myexn" }
    167   }
    168 }))
    169