19d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org// Copyright 2014 the V8 project authors. All rights reserved.
29d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be
39d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org// found in the LICENSE file.
49d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
59d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org// Flags: --harmony-proxies
69d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
79d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
89d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org// TODO(arv): Once proxies can intercept symbols, add more tests.
99d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
109d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
119d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgfunction TestBasics() {
129d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  var log = [];
139d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
149d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  var proxy = Proxy.create({
159d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    getPropertyDescriptor: function(key) {
169d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org      log.push(key);
179d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org      if (key === 'x') {
189d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org        return {
199d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org          value: 1,
209d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org          configurable: true
219d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org        };
229d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org      }
239d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org      return undefined;
249d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    }
259d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  });
269d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
279d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  var x = 'local';
289d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
299d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  with (proxy) {
309d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    assertEquals(1, x);
319d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  }
329d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
339d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  // One 'x' for HasBinding and one for GetBindingValue
349d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  assertEquals(['assertEquals', 'x', 'x'], log);
359d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org}
369d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgTestBasics();
379d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
389d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
399d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgfunction TestInconsistent() {
409d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  var log = [];
419d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  var calls = 0;
429d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
439d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  var proxy = Proxy.create({
449d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    getPropertyDescriptor: function(key) {
459d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org      log.push(key);
469d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org      if (key === 'x' && calls < 1) {
479d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org        calls++;
489d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org        return {
499d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org          value: 1,
509d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org          configurable: true
519d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org        };
529d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org      }
539d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org      return undefined;
549d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    }
559d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  });
569d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
579d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  var x = 'local';
589d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
599d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  with (proxy) {
609d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    assertEquals(void 0, x);
619d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  }
629d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
639d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  // One 'x' for HasBinding and one for GetBindingValue
649d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  assertEquals(['assertEquals', 'x', 'x'], log);
659d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org}
669d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgTestInconsistent();
679d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
689d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
699d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgfunction TestUseProxyAsUnscopables() {
709d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  var x = 1;
719d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  var object = {
729d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    x: 2
739d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  };
749d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  var calls = 0;
759d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  var proxy = Proxy.create({
769d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    has: function(key) {
779d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org      calls++;
789d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org      assertEquals('x', key);
799d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org      return calls === 2;
809d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    },
819d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    getPropertyDescriptor: function(key) {
829d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org      assertUnreachable();
839d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    }
849d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  });
859d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
869d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  object[Symbol.unscopables] = proxy;
879d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
889d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  with (object) {
899d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    assertEquals(2, x);
909d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    assertEquals(1, x);
919d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  }
929d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
939d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  // HasBinding, HasBinding
949d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  assertEquals(2, calls);
959d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org}
969d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgTestUseProxyAsUnscopables();
979d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
989d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
999d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgfunction TestThrowInHasUnscopables() {
1009d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  var x = 1;
1019d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  var object = {
1029d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    x: 2
1039d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  };
1049d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
1059d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  function CustomError() {}
1069d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
1079d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  var calls = 0;
1089d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  var proxy = Proxy.create({
1099d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    has: function(key) {
1109d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org      if (calls++ === 0) {
1119d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org        throw new CustomError();
1129d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org      }
1139d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org      assertUnreachable();
1149d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    },
1159d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    getPropertyDescriptor: function(key) {
1169d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org      assertUnreachable();
1179d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    }
1189d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  });
1199d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
1209d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  object[Symbol.unscopables] = proxy;
1219d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
1229d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  assertThrows(function() {
1239d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    with (object) {
1249d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org      x;
1259d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    }
1269d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  }, CustomError);
1279d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org}
1289d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgTestThrowInHasUnscopables();
1299d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
1309d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
1319d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgvar global = this;
1329d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgfunction TestGlobalShouldIgnoreUnscopables() {
1339d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  global.x = 1;
1349d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  var proxy = Proxy.create({
1359d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    getPropertyDescriptor: function() {
1369d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org      assertUnreachable();
1379d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    }
1389d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  });
1399d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  global[Symbol.unscopables] = proxy;
1409d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
1419d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  assertEquals(1, global.x);
1429d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  assertEquals(1, x);
1439d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
1449d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  global.x = 2;
1459d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  assertEquals(2, global.x);
1469d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  assertEquals(2, x);
1479d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
1489d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  x = 3;
1499d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  assertEquals(3, global.x);
1509d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  assertEquals(3, x);
1519d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org}
1529d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgTestGlobalShouldIgnoreUnscopables();
153