| 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 |