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