| load(libdir + 'asserts.js'); |
| |
| function getObjects() { |
| function func(){} |
| return [func, |
| new func(), |
| {x: 5}, |
| /regexp/, |
| [1, 2, 3], |
| new Date(), |
| new Number(1), |
| new Boolean(true), |
| new String('str'), |
| Object.create(null)]; |
| } |
| |
| var coercibleValues = [1, |
| true, |
| 'string']; |
| |
| var nonCoercibleValues = [undefined, |
| null]; |
| |
| var valuesWithoutNull = coercibleValues.concat(undefined); |
| |
| function TestSetPrototypeOf(object, proto) { |
| assertEq(Object.setPrototypeOf(object, proto), object); |
| assertEq(Object.getPrototypeOf(object), proto); |
| } |
| |
| // check if Object.setPrototypeOf works with coercible values |
| for(var value of coercibleValues) { |
| assertEq(Object.setPrototypeOf(value, {}), value); |
| } |
| |
| // check if Object.setPrototypeOf fails on non-coercible values |
| for (var value of nonCoercibleValues) { |
| assertThrowsInstanceOf(() => Object.setPrototypeOf(value, {}), |
| TypeError, "Object.setPrototypeOf shouldn't work on non-coercible values"); |
| } |
| |
| // check if Object.setPrototypeOf works when prototype is set to non-objects |
| var objects = getObjects(); |
| for (var object of objects) { |
| for (var proto of valuesWithoutNull) { |
| assertThrowsInstanceOf(() => Object.setPrototypeOf(object, proto), |
| TypeError, "Object.setPrototypeOf fails when the prototype is set to non-objects"); |
| } |
| } |
| |
| // check if Object.setPrototypeOf works when prototype is set to objects |
| var objects1 = getObjects(); |
| var objects2 = getObjects(); |
| for (var object1 of objects1) { |
| for (var object2 of objects2) { |
| TestSetPrototypeOf(object1, object2); |
| } |
| } |
| |
| // check if Object.setPrototypeOf works when prototype is set to null |
| objects = getObjects(); |
| for (var object of objects) { |
| TestSetPrototypeOf(object, null); |
| } |
| |
| // check if Object.setPrototypeOf fails when object is not extensible |
| var objects = getObjects(); |
| var proto = {}; |
| for (var object of objects) { |
| Object.preventExtensions(object); |
| assertThrowsInstanceOf(() => Object.setPrototypeOf(object, proto), |
| TypeError, "Object.setPrototypeOf should fail when the object is not extensible"); |
| } |
| |
| // check if Object.setPrototypeof(A, B) succeeds on not extensible object A if |
| // prototype of A == B already |
| var objectProto = {}; |
| var nonExtensibleObject = Object.create(objectProto); |
| Object.preventExtensions(nonExtensibleObject); |
| assertEq(Object.setPrototypeOf(nonExtensibleObject, objectProto), nonExtensibleObject); |
| |
| // check if Object.setPrototypeOf works with prototype lookup |
| var object = {}; |
| assertEq('x' in object, false); |
| assertEq('y' in object, false); |
| |
| var oldProto = { |
| x: 'old x', |
| y: 'old y' |
| }; |
| Object.setPrototypeOf(object, oldProto); |
| assertEq(object.x, 'old x'); |
| assertEq(object.y, 'old y'); |
| |
| var newProto = { |
| x: 'new x' |
| }; |
| Object.setPrototypeOf(object, newProto); |
| assertEq(object.x, 'new x'); |
| assertEq('y' in object, false); |
| |
| // check if Object.setPrototypeOf throws TypeError on fewer arguments |
| assertThrowsInstanceOf(() => Object.setPrototypeOf(), |
| TypeError, "Object.setPrototypeOf throws TypeError when called without any parameters"); |
| assertThrowsInstanceOf(() => Object.setPrototypeOf({}), |
| TypeError, "Object.setPrototypeOf throws TypeError when called with 1 parameter"); |