blob: 9d9e73f9084cf7913b8f768bbf7565fd8474fb95 [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// 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
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005var target = { target: 1 };
6target.__proto__ = {};
7var handler = { handler: 1 };
8var proxy = new Proxy(target, handler);
9
10assertSame(Object.getPrototypeOf(proxy), target.__proto__ );
11
12
13assertThrows(function() { Object.setPrototypeOf(proxy, undefined) }, TypeError);
14assertThrows(function() { Object.setPrototypeOf(proxy, 1) }, TypeError);
15
16var prototype = [1];
17assertSame(proxy, Object.setPrototypeOf(proxy, prototype));
18assertSame(prototype, Object.getPrototypeOf(proxy));
19assertSame(prototype, Object.getPrototypeOf(target));
20
21var pair = Proxy.revocable(target, handler);
22assertSame(pair.proxy, Object.setPrototypeOf(pair.proxy, prototype));
23assertSame(prototype, Object.getPrototypeOf(pair.proxy));
24pair.revoke();
25assertThrows('Object.setPrototypeOf(pair.proxy, prototype)', TypeError);
26
27handler.setPrototypeOf = function(target, proto) {
28 return false;
29};
30assertThrows(function() { Object.setPrototypeOf(proxy, {a:1}) }, TypeError);
31
32handler.setPrototypeOf = function(target, proto) {
33 return undefined;
34};
35assertThrows(function() { Object.setPrototypeOf(proxy, {a:2}) }, TypeError);
36
37handler.setPrototypeOf = function(proto) {};
38assertThrows(function() { Object.setPrototypeOf(proxy, {a:3}) }, TypeError);
39
40handler.setPrototypeOf = function(target, proto) {
41 throw Error();
42};
43assertThrows(function() { Object.setPrototypeOf(proxy, {a:4}) }, Error);
44
45var seen_prototype;
46var seen_target;
47handler.setPrototypeOf = function(target, proto) {
48 seen_target = target;
49 seen_prototype = proto;
50 return true;
51}
52assertSame(Object.setPrototypeOf(proxy, {a:5}), proxy);
53assertSame(target, seen_target);
54assertEquals({a:5}, seen_prototype);
55
56(function setPrototypeProxyTarget() {
57 var target = { target: 1 };
58 target.__proto__ = {};
59 var handler = {};
60 var handler2 = {};
61 var target2 = new Proxy(target, handler2);
62 var proxy2 = new Proxy(target2, handler);
63 assertSame(Object.getPrototypeOf(proxy2), target.__proto__ );
64
65 var prototype = [2,3];
66 assertSame(proxy2, Object.setPrototypeOf(proxy2, prototype));
67 assertSame(prototype, Object.getPrototypeOf(proxy2));
68 assertSame(prototype, Object.getPrototypeOf(target));
69})();
70
71(function testProxyTrapInconsistent() {
72 var target = { target: 1 };
73 target.__proto__ = {};
74 var handler = {};
75 var handler2 = {
76 };
77
78 var target2 = new Proxy(target, handler);
79 var proxy2 = new Proxy(target2, handler2);
80
81 // If the final target is extensible we can set any prototype.
82 var prototype = [1];
83 Reflect.setPrototypeOf(proxy2, prototype);
84 assertSame(prototype, Reflect.getPrototypeOf(target));
85
86 handler2.setPrototypeOf = function(target, value) {
87 Reflect.setPrototypeOf(target, value);
88 return true;
89 };
90 prototype = [2];
91 Reflect.setPrototypeOf(proxy2, prototype);
92 assertSame(prototype, Reflect.getPrototypeOf(target));
93
94 // Prevent getting the target's prototype used to check the invariant.
95 var gotPrototype = false;
96 handler.getPrototypeOf = function() {
97 gotPrototype = true;
98 throw TypeError()
99 };
100 // If the target is extensible we do not check the invariant.
101 prototype = [3];
102 Reflect.setPrototypeOf(proxy2, prototype);
103 assertFalse(gotPrototype);
104 assertSame(prototype, Reflect.getPrototypeOf(target));
105
106 // Changing the prototype of a non-extensible target will trigger the
107 // invariant-check and throw in the above handler.
108 Reflect.preventExtensions(target);
109 assertThrows(() => {Reflect.setPrototypeOf(proxy2, [4])}, TypeError);
110 assertTrue(gotPrototype);
111 assertEquals([3], Reflect.getPrototypeOf(target));
112
113 // Setting the prototype of a non-extensible target is fine if the prototype
114 // doesn't change.
115 delete handler.getPrototypeOf;
116 Reflect.setPrototypeOf(proxy2, prototype);
117 // Changing the prototype will throw.
118 prototype = [5];
119 assertThrows(() => {Reflect.setPrototypeOf(proxy2, prototype)}, TypeError);
120})();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100121
122(function testProxyTrapReturnsFalse() {
123 var handler = {};
124 handler.setPrototypeOf = () => false;
125 var target = new Proxy({}, {isExtensible: () => assertUnreachable()});
126 var object = new Proxy(target, handler);
127 assertFalse(Reflect.setPrototypeOf(object, {}));
128})();