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 --harmony-reflect --allow-natives-syntax
6
7(function testBasicFunctionality() {
8   var target = {
9     target_one: 1,
10     property: "value"
11   };
12
13   var handler = {handler:1};
14
15   var proxy = new Proxy(target, handler);
16   assertEquals("value", proxy.property);
17   assertEquals(undefined, proxy.nothing);
18   assertEquals(undefined, proxy.handler);
19
20   handler.get = function() { return "value 2" };
21   assertEquals("value 2", proxy.property);
22   assertEquals("value 2", proxy.nothing);
23   assertEquals("value 2", proxy.handler);
24
25   var handler2 = new Proxy({get: function() { return "value 3" }},{});
26   var proxy2 = new Proxy(target, handler2);
27   assertEquals("value 3", proxy2.property);
28   assertEquals("value 3", proxy2.nothing);
29   assertEquals("value 3", proxy2.handler);
30})();
31
32(function testThrowOnGettingTrap() {
33  var handler = new Proxy({}, {get: function(){ throw Error() }});
34  var proxy = new Proxy({}, handler);
35  assertThrows("proxy.property", Error);
36})();
37
38(function testFallback() {
39  var target = {property:"value"};
40  var proxy = new Proxy(target, {});
41  assertEquals("value", proxy.property);
42  assertEquals(undefined, proxy.property2);
43})();
44
45(function testFallbackUndefinedTrap() {
46  var handler = new Proxy({}, {get: function(){ return undefined }});
47  var target = {property:"value"};
48  var proxy = new Proxy(target, handler);
49  assertEquals("value", proxy.property);
50  assertEquals(undefined, proxy.property2);
51})();
52
53(function testFailingInvariant() {
54  var target = {};
55  var handler = { get: function(r, p){ if (p != "key4") return "value" }}
56  var proxy = new Proxy(target, handler);
57  assertEquals("value", proxy.property);
58  assertEquals("value", proxy.key);
59  assertEquals("value", proxy.key2);
60  assertEquals("value", proxy.key3);
61
62  // Define a non-configurable, non-writeable property on the target for
63  // which the handler will return a different value.
64  Object.defineProperty(target, "key", {
65    configurable: false,
66    writable: false,
67    value: "different value"
68  });
69  assertEquals("value", proxy.property);
70  assertThrows(function(){ proxy.key }, TypeError);
71  assertEquals("value", proxy.key2);
72  assertEquals("value", proxy.key3);
73
74  // Define a non-configurable getter on the target for which the handler
75  // will return a value, according to the spec we do not throw.
76  Object.defineProperty(target, "key2", {
77    configurable: false,
78    get: function() { return "different value" }
79  });
80  assertEquals("value", proxy.property);
81  assertThrows(function(){ proxy.key }, TypeError);
82  assertEquals("value", proxy.key2);
83  assertEquals("value", proxy.key3);
84
85  // Define a non-configurable setter without a corresponding getter on the
86  // target for which the handler will return a value.
87  Object.defineProperty(target, "key3", {
88    configurable: false,
89    set: function() { }
90  });
91  assertEquals("value", proxy.property);
92  assertThrows(function(){ proxy.key }, TypeError);
93  assertEquals("value", proxy.key2);
94  assertThrows(function(){ proxy.key3 }, TypeError);
95
96  // Define a non-configurable setter without a corresponding getter on the
97  // target for which the handler will return undefined.
98  Object.defineProperty(target, "key4", {
99    configurable: false,
100    set: function() { }
101  });
102  assertSame(undefined, proxy.key4);
103})();
104
105(function testGetInternalIterators() {
106  var log = [];
107  var array = [1,2,3,4,5]
108  var origIt = array[Symbol.iterator]();
109  var it = new Proxy(origIt, {
110    get(t, name) {
111      log.push(`[[Get]](iterator, ${String(name)})`);
112      return Reflect.get(t, name);
113    },
114    set(t, name, val) {
115      log.push(`[[Set]](iterator, ${String(name)}, ${String(val)})`);
116      return Reflect.set(t, name, val);
117    }
118  });
119
120  assertThrows(function() {
121    for (var v of it) log.push(v);
122  }, TypeError);
123  assertEquals([
124    "[[Get]](iterator, Symbol(Symbol.iterator))",
125    "[[Get]](iterator, next)"
126  ], log);
127})();
128