1// Copyright 2014 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
8function TestBasics() {
9  var log = [];
10
11  var proxy = new Proxy({}, {
12    get: function(target, key) {
13      log.push("get " + String(key));
14      if (key === 'x') return 1;
15    },
16    has: function(target, key) {
17      log.push("has " + String(key));
18      if (key === 'x') return true;
19      return false;
20    }
21  });
22
23  var x = 'local';
24
25  with (proxy) {
26    assertEquals(1, x);
27  }
28
29  assertEquals(['has assertEquals', 'has x', 'get Symbol(Symbol.unscopables)',
30                'get x'], log);
31}
32TestBasics();
33
34
35function TestInconsistent() {
36  var log = [];
37
38  var proxy = new Proxy({}, {
39    get: function(target, key) {
40      log.push("get " + String(key));
41      return undefined;
42    },
43    has: function(target, key) {
44      log.push("has " + String(key));
45      if (key === 'x') return true;
46      return false;
47    }
48  });
49
50  var x = 'local';
51
52  with (proxy) {
53    assertEquals(void 0, x);
54  }
55
56  assertEquals(['has assertEquals', 'has x', 'get Symbol(Symbol.unscopables)',
57                'get x'], log);
58}
59TestInconsistent();
60
61
62function TestUseProxyAsUnscopables() {
63  var x = 1;
64  var object = {
65    x: 2
66  };
67  var calls = 0;
68  var proxy = new Proxy({}, {
69    has: function() {
70      assertUnreachable();
71    },
72    get: function(target, key) {
73      assertEquals('x', key);
74      calls++;
75      return calls === 2 ? true : undefined;
76    }
77  });
78
79  object[Symbol.unscopables] = proxy;
80
81  with (object) {
82    assertEquals(2, x);
83    assertEquals(1, x);
84  }
85
86  // HasBinding, HasBinding
87  assertEquals(2, calls);
88}
89TestUseProxyAsUnscopables();
90
91
92function TestThrowInHasUnscopables() {
93  var x = 1;
94  var object = {
95    x: 2
96  };
97
98  function CustomError() {}
99
100  var calls = 0;
101  var proxy = new Proxy({}, {
102    has: function() {
103      assertUnreachable();
104    },
105    get: function(target, key) {
106      if (calls++ === 0) {
107        throw new CustomError();
108      }
109      assertUnreachable();
110    }
111  });
112
113  object[Symbol.unscopables] = proxy;
114
115  assertThrows(function() {
116    with (object) {
117      x;
118    }
119  }, CustomError);
120}
121TestThrowInHasUnscopables();
122
123
124var global = this;
125function TestGlobalShouldIgnoreUnscopables() {
126  global.x = 1;
127  var proxy = new Proxy({}, {
128    get: function() {
129      assertUnreachable();
130    },
131    has: function() {
132      assertUnreachable();
133    }
134  });
135  global[Symbol.unscopables] = proxy;
136
137  assertEquals(1, global.x);
138  assertEquals(1, x);
139
140  global.x = 2;
141  assertEquals(2, global.x);
142  assertEquals(2, x);
143
144  x = 3;
145  assertEquals(3, global.x);
146  assertEquals(3, x);
147}
148TestGlobalShouldIgnoreUnscopables();
149