michael@0: // Any copyright is dedicated to the Public Domain. michael@0: // http://creativecommons.org/licenses/publicdomain/ michael@0: michael@0: //----------------------------------------------------------------------------- michael@0: var BUGNUMBER = 948583; michael@0: var summary = michael@0: "Make __proto__ in object literals a special form not influenced by " + michael@0: "|Object.prototype|"; michael@0: michael@0: print(BUGNUMBER + ": " + summary); michael@0: michael@0: /************** michael@0: * BEGIN TEST * michael@0: **************/ michael@0: michael@0: var passed = true; michael@0: michael@0: function performProtoTests(msg) michael@0: { michael@0: print("Testing " + msg); michael@0: assertEq(passed, true, "passed wrong at start of test set"); michael@0: michael@0: assertEq(Object.getPrototypeOf({ __proto__: null }), null); michael@0: assertEq(Object.getPrototypeOf({ __proto__: undefined }), Object.prototype); michael@0: assertEq(Object.getPrototypeOf({ __proto__: 17 }), Object.prototype); michael@0: michael@0: var obj = {}; michael@0: assertEq(Object.getPrototypeOf({ __proto__: obj }), obj); michael@0: michael@0: assertEq(passed, true, "passed wrong at end of test set"); michael@0: print("Tests of " + msg + " passed!"); michael@0: } michael@0: michael@0: function poisonProto(obj) michael@0: { michael@0: Object.defineProperty(obj, "__proto__", michael@0: { michael@0: configurable: true, michael@0: enumerable: true, michael@0: set: function(v) { passed = false; }, michael@0: }); michael@0: } michael@0: michael@0: performProtoTests("initial behavior"); michael@0: michael@0: var desc = Object.getOwnPropertyDescriptor(Object.prototype, "__proto__"); michael@0: var setProto = desc.set; michael@0: delete Object.prototype.__proto__; michael@0: michael@0: performProtoTests("behavior after Object.prototype.__proto__ deletion"); michael@0: michael@0: Object.defineProperty(Object.prototype, "__proto__", michael@0: { michael@0: configurable: true, michael@0: enumerable: false, michael@0: set: function(v) { passed = false; }, michael@0: }); michael@0: michael@0: performProtoTests("behavior after making Object.prototype.__proto__ a " + michael@0: "custom setter"); michael@0: michael@0: Object.defineProperty(Object.prototype, "__proto__", { set: undefined }); michael@0: michael@0: performProtoTests("behavior after making Object.prototype.__proto__'s " + michael@0: "[[Set]] === undefined"); michael@0: michael@0: michael@0: var superProto = Object.create(null); michael@0: poisonProto(superProto); michael@0: setProto.call(Object.prototype, superProto); michael@0: michael@0: performProtoTests("behavior after mutating Object.prototype.[[Prototype]]"); michael@0: michael@0: // Note: The handler below will have to be updated to exempt a scriptable michael@0: // getPrototypeOf trap (to instead consult the target whose [[Prototype]] michael@0: // is safely non-recursive), if we ever implement one. michael@0: var death = new Proxy(Object.create(null), michael@0: new Proxy({}, { get: function() { passed = false; } })); michael@0: michael@0: setProto.call(Object.prototype, death); michael@0: michael@0: performProtoTests("behavior after making Object.prototype.[[Prototype]] a " + michael@0: "proxy that throws for any access"); michael@0: michael@0: michael@0: if (typeof reportCompare === "function") michael@0: reportCompare(true, true); michael@0: michael@0: print("Tests complete");