diff options
Diffstat (limited to '')
-rw-r--r-- | js/src/tests/non262/Proxy/getPrototypeOf.js | 285 |
1 files changed, 285 insertions, 0 deletions
diff --git a/js/src/tests/non262/Proxy/getPrototypeOf.js b/js/src/tests/non262/Proxy/getPrototypeOf.js new file mode 100644 index 0000000000..a0676c0c91 --- /dev/null +++ b/js/src/tests/non262/Proxy/getPrototypeOf.js @@ -0,0 +1,285 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var gTestfile = "getPrototypeOf.js"; +var BUGNUMBER = 888969; +var summary = "Scripted proxies' [[GetPrototypeOf]] behavior"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +const log = []; + +function observe(obj) +{ + var observingHandler = new Proxy({}, { + get(target, p, receiver) { + log.push(p); + return Reflect.get(target, p, receiver); + } + }); + + return new Proxy(obj, observingHandler); +} + +function nop() {} + +var p, h; + +// 1. Let handler be the value of the [[ProxyHandler]] internal slot of O. +// 2. If handler is null, throw a TypeError exception. +// 3. Assert: Type(handler) is Object. +var rev = Proxy.revocable({}, {}); +p = rev.proxy; + +assertEq(Object.getPrototypeOf(p), Object.prototype); +rev.revoke(); +assertThrowsInstanceOf(() => Object.getPrototypeOf(p), TypeError); + +// 4. Let target be the value of the [[ProxyTarget]] internal slot of O. +// 5. Let trap be ? GetMethod(handler, "getPrototypeOf"). + +// Getting handler.getPrototypeOf might throw. +assertThrowsValue(() => Object.getPrototypeOf(new Proxy({}, + { get getPrototypeOf() { + throw 17; + } })), + 17); + +// The handler's getPrototypeOf, once gotten, might throw. +p = new Proxy({}, { getPrototypeOf() { throw 42; } }); + +assertThrowsValue(() => Object.getPrototypeOf(p), 42); + +// The trap might not be callable. +p = new Proxy({}, { getPrototypeOf: 17 }); + +assertThrowsInstanceOf(() => Object.getPrototypeOf(p), + TypeError); + +// 6. If trap is undefined, then +// a. Return ? target.[[GetPrototypeOf]](). + +var x, tp; + +tp = + new Proxy(new Number(8675309), // behavior overridden by getPrototypeOf + { getPrototypeOf() { x = "getPrototypeOf trap"; return null; } }); + +// The target's [[GetPrototypeOf]] should be invoked if the handler's +// .getPrototypeOf is undefined. +p = new Proxy(tp, { getPrototypeOf: undefined }); +x = "unset"; +assertEq(Object.getPrototypeOf(p), null); +assertEq(x, "getPrototypeOf trap"); + +// Likewise if the handler's .getPrototypeOf is null. +p = new Proxy(tp, { getPrototypeOf: null }); +x = "unset"; +assertEq(Object.getPrototypeOf(p), null); +assertEq(x, "getPrototypeOf trap"); + +// Now the target is an empty object with a Number object as its [[Prototype]]. +var customProto = new Number(8675309); +tp = + new Proxy({}, + { getPrototypeOf() { + x = "getPrototypeOf trap"; + return customProto; + } }); + +// The target's [[GetPrototypeOf]] should be invoked if the handler's +// .getPrototypeOf is undefined. +p = new Proxy(tp, { getPrototypeOf: undefined }); +x = "unset"; +assertEq(Object.getPrototypeOf(p), customProto); +assertEq(x, "getPrototypeOf trap"); + +// Likewise if the handler's .getPrototypeOf is null. +p = new Proxy(tp, { getPrototypeOf: null }); +x = "unset"; +assertEq(Object.getPrototypeOf(p), customProto); +assertEq(x, "getPrototypeOf trap"); + +// 7. Let handlerProto be ? Call(trap, handler, « target »). + +// The trap callable might throw. +p = new Proxy({}, { getPrototypeOf() { throw "ohai"; } }); + +assertThrowsValue(() => Object.getPrototypeOf(p), + "ohai"); + +var throwingTrap = + new Proxy(function() { throw "not called"; }, + { apply() { throw 37; } }); + +p = new Proxy({}, { getPrototypeOf: throwingTrap }); + +assertThrowsValue(() => Object.getPrototypeOf(p), + 37); + +// The trap callable must *only* be called. +p = new Proxy({}, + { + getPrototypeOf: observe(function() { throw "boo-urns"; }) + }); + +log.length = 0; +assertThrowsValue(() => Object.getPrototypeOf(p), + "boo-urns"); + +assertEq(log.length, 1); +assertEq(log[0], "apply"); + +// 8. If Type(handlerProto) is neither Object nor Null, throw a TypeError exception. + +var rval; + +var typeTestingTarget = {}; +p = new Proxy(typeTestingTarget, { getPrototypeOf() { return rval; } }); + +function returnsPrimitives() +{ + rval = undefined; + assertThrowsInstanceOf(() => Object.getPrototypeOf(p), + TypeError); + + rval = true; + assertThrowsInstanceOf(() => Object.getPrototypeOf(p), + TypeError); + + rval = false; + assertThrowsInstanceOf(() => Object.getPrototypeOf(p), + TypeError); + + rval = 0.0; + assertThrowsInstanceOf(() => Object.getPrototypeOf(p), + TypeError); + + rval = -0.0; + assertThrowsInstanceOf(() => Object.getPrototypeOf(p), + TypeError); + + rval = 3.141592654; + assertThrowsInstanceOf(() => Object.getPrototypeOf(p), + TypeError); + + rval = NaN; + assertThrowsInstanceOf(() => Object.getPrototypeOf(p), + TypeError); + + rval = -Infinity; + assertThrowsInstanceOf(() => Object.getPrototypeOf(p), + TypeError); + + rval = "[[Prototype]] FOR REALZ"; + assertThrowsInstanceOf(() => Object.getPrototypeOf(p), + TypeError); + + rval = Symbol("[[Prototype]] FOR REALZ"); + assertThrowsInstanceOf(() => Object.getPrototypeOf(p), + TypeError); +} + +returnsPrimitives(); +Object.preventExtensions(typeTestingTarget); +returnsPrimitives(); + +// 9. Let extensibleTarget be ? IsExtensible(target). + +var act, extens; + +var typeTestingProxyTarget = + new Proxy({}, { isExtensible() { + seen = act(); + return extens; + } }); + +p = new Proxy(typeTestingProxyTarget, { getPrototypeOf() { return rval; } }); + +rval = null; +act = () => { throw "fnord" }; +assertThrowsValue(() => Object.getPrototypeOf(p), + "fnord"); + +rval = /abc/; +act = () => { throw "fnord again" }; +assertThrowsValue(() => Object.getPrototypeOf(p), + "fnord again"); + +rval = Object.prototype; +act = () => { throw "fnord" }; +assertThrowsValue(() => Object.getPrototypeOf(p), + "fnord"); + +// 10. If extensibleTarget is true, return handlerProto. + +p = new Proxy({}, { getPrototypeOf() { return rval; } }); + +rval = Number.prototype; +assertEq(Object.getPrototypeOf(p), Number.prototype); + +// 11. Let targetProto be ? target.[[GetPrototypeOf]](). + +var targetProto; + +var targetWithProto = + new Proxy(Object.preventExtensions(Object.create(null)), + { getPrototypeOf() { act2(); return targetProto; } }); + +p = new Proxy(targetWithProto, + { getPrototypeOf() { act1(); return rval; } }); + +rval = null; +targetProto = null; + +var regex = /targetProto/; + +act1 = () => log.push("act1"); +act2 = () => log.push("act2"); + +log.length = 0; +assertEq(Object.getPrototypeOf(p), null); +assertEq(log.length, 2); +assertEq(log[0], "act1"); +assertEq(log[1], "act2"); + +act1 = () => log.push("act1 again"); +act2 = () => { throw "target throw"; }; + +log.length = 0; +assertThrowsValue(() => Object.getPrototypeOf(p), + "target throw"); +assertEq(log.length, 1); +assertEq(log[0], "act1 again"); + +// 12. If SameValue(handlerProto, targetProto) is false, throw a TypeError exception. + +act1 = act2 = nop; +rval = /a/; +assertThrowsInstanceOf(() => Object.getPrototypeOf(p), + TypeError); + +// 13. Return handlerProto. + +rval = null; +targetProto = null; + +assertEq(Object.getPrototypeOf(p), null); + +p = new Proxy(Object.preventExtensions(new Number(55)), + { getPrototypeOf() { return Number.prototype; } }); + +assertEq(Object.getPrototypeOf(p), Number.prototype); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("Tests complete"); |