Index: test/mjsunit/harmony/proxies-set-prototype-of.js |
diff --git a/test/mjsunit/harmony/proxies-set-prototype-of.js b/test/mjsunit/harmony/proxies-set-prototype-of.js |
index 64b3d72b0ae99cc70947e7a6786ed0c532916a67..bc60ff492c45ea126f911e27fb35ffffe81cf0ee 100644 |
--- a/test/mjsunit/harmony/proxies-set-prototype-of.js |
+++ b/test/mjsunit/harmony/proxies-set-prototype-of.js |
@@ -2,7 +2,7 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
-// Flags: --harmony-proxies |
+// Flags: --harmony-proxies --harmony-reflect |
var target = { target: 1 }; |
target.__proto__ = {}; |
@@ -11,6 +11,7 @@ var proxy = new Proxy(target, handler); |
assertSame(Object.getPrototypeOf(proxy), target.__proto__ ); |
+ |
assertThrows(function() { Object.setPrototypeOf(proxy, undefined) }, TypeError); |
assertThrows(function() { Object.setPrototypeOf(proxy, 1) }, TypeError); |
@@ -19,6 +20,12 @@ assertSame(proxy, Object.setPrototypeOf(proxy, prototype)); |
assertSame(prototype, Object.getPrototypeOf(proxy)); |
assertSame(prototype, Object.getPrototypeOf(target)); |
+var pair = Proxy.revocable(target, handler); |
+assertSame(pair.proxy, Object.setPrototypeOf(pair.proxy, prototype)); |
+assertSame(prototype, Object.getPrototypeOf(pair.proxy)); |
+pair.revoke(); |
+assertThrows('Object.setPrototypeOf(pair.proxy, prototype)', TypeError); |
+ |
handler.setPrototypeOf = function(target, proto) { |
return false; |
}; |
@@ -48,12 +55,68 @@ assertSame(Object.setPrototypeOf(proxy, {a:5}), proxy); |
assertSame(target, seen_target); |
assertEquals({a:5}, seen_prototype); |
-// Target is a Proxy: |
-var target2 = new Proxy(target, {}); |
-var proxy2 = new Proxy(target2, {}); |
-assertSame(Object.getPrototypeOf(proxy2), target.__proto__ ); |
+(function setPrototypeProxyTarget() { |
+ var target = { target: 1 }; |
+ target.__proto__ = {}; |
+ var handler = {}; |
+ var handler2 = {}; |
+ var target2 = new Proxy(target, handler2); |
+ var proxy2 = new Proxy(target2, handler); |
+ assertSame(Object.getPrototypeOf(proxy2), target.__proto__ ); |
-prototype = [2,3]; |
-assertSame(proxy2, Object.setPrototypeOf(proxy2, prototype)); |
-assertSame(prototype, Object.getPrototypeOf(proxy2)); |
-assertSame(prototype, Object.getPrototypeOf(target)); |
+ var prototype = [2,3]; |
+ assertSame(proxy2, Object.setPrototypeOf(proxy2, prototype)); |
+ assertSame(prototype, Object.getPrototypeOf(proxy2)); |
+ assertSame(prototype, Object.getPrototypeOf(target)); |
+})(); |
+ |
+(function testProxyTrapInconsistent() { |
+ var target = { target: 1 }; |
+ target.__proto__ = {}; |
+ var handler = {}; |
+ var handler2 = { |
+ }; |
+ |
+ var target2 = new Proxy(target, handler); |
+ var proxy2 = new Proxy(target2, handler2); |
+ |
+ // If the final target is extensible we can set any prototype. |
+ var prototype = [1]; |
+ Reflect.setPrototypeOf(proxy2, prototype); |
+ assertSame(prototype, Reflect.getPrototypeOf(target)); |
+ |
+ handler2.setPrototypeOf = function(target, value) { |
+ Reflect.setPrototypeOf(target, value); |
+ return true; |
+ }; |
+ prototype = [2]; |
+ Reflect.setPrototypeOf(proxy2, prototype); |
+ assertSame(prototype, Reflect.getPrototypeOf(target)); |
+ |
+ // Prevent getting the target's prototype used to check the invariant. |
+ var gotPrototype = false; |
+ handler.getPrototypeOf = function() { |
+ gotPrototype = true; |
+ throw TypeError() |
+ }; |
+ // If the target is extensible we do not check the invariant. |
+ prototype = [3]; |
+ Reflect.setPrototypeOf(proxy2, prototype); |
+ assertFalse(gotPrototype); |
+ assertSame(prototype, Reflect.getPrototypeOf(target)); |
+ |
+ // Changing the prototype of a non-extensible target will trigger the |
+ // invariant-check and throw in the above handler. |
+ Reflect.preventExtensions(target); |
+ assertThrows(() => {Reflect.setPrototypeOf(proxy2, [4])}, TypeError); |
+ assertTrue(gotPrototype); |
+ assertEquals([3], Reflect.getPrototypeOf(target)); |
+ |
+ // Setting the prototype of a non-extensible target is fine if the prototype |
+ // doesn't change. |
+ delete handler.getPrototypeOf; |
+ Reflect.setPrototypeOf(proxy2, prototype); |
+ // Changing the prototype will throw. |
+ prototype = [5]; |
+ assertThrows(() => {Reflect.setPrototypeOf(proxy2, prototype)}, TypeError); |
+})(); |