public void prototype() { // Prototype if (TestUtils.Engine != JSEngine.JScript) { // prototype of built-in object. Assert.AreEqual(PropertyAttributes.Sealed, TestUtils.EvaluateAccessibility("Function", "prototype")); // prototype of new function. Assert.AreEqual(PropertyAttributes.Writable, TestUtils.EvaluateAccessibility("new Function()", "prototype")); // prototype of empty function. Assert.AreEqual(true, TestUtils.Evaluate("Object.getPrototypeOf(Function).prototype === undefined")); // [[Prototype]] Assert.AreEqual(true, TestUtils.Evaluate("Object.getPrototypeOf(new Function()) === Function.prototype")); Assert.AreEqual(true, TestUtils.Evaluate("Object.getPrototypeOf(Function.prototype) === Object.prototype")); Assert.AreEqual(true, TestUtils.Evaluate("Object.getPrototypeOf(new Function().prototype) === Object.prototype")); Assert.AreEqual(true, TestUtils.Evaluate("Object.getPrototypeOf((function() {}).prototype) === Object.prototype")); } // prototype of built-in functions should be undefined. Assert.AreEqual(Undefined.Value, TestUtils.Evaluate("Math.sin.prototype")); // prototype of new functions should be a new object. Assert.AreEqual(true, TestUtils.Evaluate("Function('a+b').prototype !== Object.prototype")); Assert.AreEqual("object", TestUtils.Evaluate("typeof(Function('a+b').prototype)")); // The prototype property becomes the prototype of new objects (as long as the prototype property is an object). Assert.AreEqual(true, TestUtils.Evaluate("f = function() { }; x = {}; f.prototype = x; Object.getPrototypeOf(new f()) === x")); Assert.AreEqual(true, TestUtils.Evaluate("f = function() { }; x = 5; f.prototype = x; Object.getPrototypeOf(new f()) === Object.prototype")); }
public void constructor() { Assert.AreEqual(true, TestUtils.Evaluate("new Function().constructor === Function")); Assert.AreEqual(true, TestUtils.Evaluate("f = Function('a+b'); f.prototype.constructor === f")); // constructor is non-enumerable, writable and configurable. if (TestUtils.Engine != JSEngine.JScript) { Assert.AreEqual(PropertyAttributes.NonEnumerable, TestUtils.EvaluateAccessibility("Function.prototype", "constructor")); } }
public void length() { Assert.AreEqual(0, TestUtils.Evaluate("Function.prototype.length")); Assert.AreEqual(1, TestUtils.Evaluate("new Function('a', 'return this / a').length")); Assert.AreEqual(2, TestUtils.Evaluate("new Function('a,b', 'return a / b').length")); Assert.AreEqual(2, TestUtils.Evaluate("(function(a, b) {}).length")); // length is non-enumerable, non-writable and non-configurable. if (TestUtils.Engine != JSEngine.JScript) { Assert.AreEqual(PropertyAttributes.Sealed, TestUtils.EvaluateAccessibility("Function", "length")); Assert.AreEqual(PropertyAttributes.Sealed, TestUtils.EvaluateAccessibility("new Function", "length")); } }
public void GlobalProperties() { // Global constants: Infinity, NaN and undefined. Assert.AreEqual(double.PositiveInfinity, TestUtils.Evaluate("Infinity")); Assert.AreEqual(double.NaN, TestUtils.Evaluate("NaN")); Assert.AreEqual(Undefined.Value, TestUtils.Evaluate("undefined")); // In ECMAScript 5 these properties are not enumerable, not configurable and not writable. Assert.AreEqual(PropertyAttributes.Sealed, TestUtils.EvaluateAccessibility("this", "Infinity")); Assert.AreEqual(PropertyAttributes.Sealed, TestUtils.EvaluateAccessibility("this", "NaN")); Assert.AreEqual(PropertyAttributes.Sealed, TestUtils.EvaluateAccessibility("this", "undefined")); // In ECMAScript 5 these properties are not enumerable, not configurable and writable. TestUtils.CompatibilityMode = CompatibilityMode.ECMAScript3; try { Assert.AreEqual(PropertyAttributes.Writable, TestUtils.EvaluateAccessibility("this", "Infinity")); Assert.AreEqual(PropertyAttributes.Writable, TestUtils.EvaluateAccessibility("this", "NaN")); Assert.AreEqual(PropertyAttributes.Writable, TestUtils.EvaluateAccessibility("this", "undefined")); } finally { TestUtils.CompatibilityMode = CompatibilityMode.Latest; } // Built-in objects should be writable and configurable but not enumerable. Assert.AreEqual(PropertyAttributes.NonEnumerable, TestUtils.EvaluateAccessibility("this", "Array")); Assert.AreEqual(PropertyAttributes.NonEnumerable, TestUtils.EvaluateAccessibility("this", "Boolean")); Assert.AreEqual(PropertyAttributes.NonEnumerable, TestUtils.EvaluateAccessibility("this", "Date")); Assert.AreEqual(PropertyAttributes.NonEnumerable, TestUtils.EvaluateAccessibility("this", "Error")); Assert.AreEqual(PropertyAttributes.NonEnumerable, TestUtils.EvaluateAccessibility("this", "EvalError")); Assert.AreEqual(PropertyAttributes.NonEnumerable, TestUtils.EvaluateAccessibility("this", "Function")); Assert.AreEqual(PropertyAttributes.NonEnumerable, TestUtils.EvaluateAccessibility("this", "JSON")); Assert.AreEqual(PropertyAttributes.NonEnumerable, TestUtils.EvaluateAccessibility("this", "Math")); Assert.AreEqual(PropertyAttributes.NonEnumerable, TestUtils.EvaluateAccessibility("this", "Number")); Assert.AreEqual(PropertyAttributes.NonEnumerable, TestUtils.EvaluateAccessibility("this", "Object")); Assert.AreEqual(PropertyAttributes.NonEnumerable, TestUtils.EvaluateAccessibility("this", "RangeError")); Assert.AreEqual(PropertyAttributes.NonEnumerable, TestUtils.EvaluateAccessibility("this", "ReferenceError")); Assert.AreEqual(PropertyAttributes.NonEnumerable, TestUtils.EvaluateAccessibility("this", "RegExp")); Assert.AreEqual(PropertyAttributes.NonEnumerable, TestUtils.EvaluateAccessibility("this", "String")); Assert.AreEqual(PropertyAttributes.NonEnumerable, TestUtils.EvaluateAccessibility("this", "SyntaxError")); Assert.AreEqual(PropertyAttributes.NonEnumerable, TestUtils.EvaluateAccessibility("this", "TypeError")); Assert.AreEqual(PropertyAttributes.NonEnumerable, TestUtils.EvaluateAccessibility("this", "URIError")); // Functions are writable and configurable. Assert.AreEqual(PropertyAttributes.NonEnumerable, TestUtils.EvaluateAccessibility("this", "decodeURI")); // length is sealed. Assert.AreEqual(PropertyAttributes.Sealed, TestUtils.EvaluateAccessibility("this.decodeURI", "length")); }
public void preventExtensions() { // Simple object Assert.AreEqual(true, TestUtils.Evaluate("var x = {a: 1, c: 2}; Object.preventExtensions(x) === x")); Assert.AreEqual(2, TestUtils.Evaluate("x.a = 2; x.a")); Assert.AreEqual(true, TestUtils.Evaluate("delete x.a")); Assert.AreEqual(Undefined.Value, TestUtils.Evaluate("x.b = 6; x.b")); Assert.AreEqual(PropertyAttributes.FullAccess, TestUtils.EvaluateAccessibility("x", "c")); // length Assert.AreEqual(1, TestUtils.Evaluate("Object.preventExtensions.length")); // Argument must be an object. Assert.AreEqual("TypeError", TestUtils.EvaluateExceptionType("Object.preventExtensions()")); Assert.AreEqual("TypeError", TestUtils.EvaluateExceptionType("Object.preventExtensions(undefined)")); Assert.AreEqual("TypeError", TestUtils.EvaluateExceptionType("Object.preventExtensions(null)")); Assert.AreEqual("TypeError", TestUtils.EvaluateExceptionType("Object.preventExtensions(true)")); Assert.AreEqual("TypeError", TestUtils.EvaluateExceptionType("Object.preventExtensions(5)")); Assert.AreEqual("TypeError", TestUtils.EvaluateExceptionType("Object.preventExtensions('test')")); }
public void freeze() { // Simple object Assert.AreEqual(true, TestUtils.Evaluate("var x = {a: 1}; Object.freeze(x) === x")); Assert.AreEqual(false, TestUtils.Evaluate("delete x.a")); Assert.AreEqual(1, TestUtils.Evaluate("x.a = 2; x.a")); Assert.AreEqual(Undefined.Value, TestUtils.Evaluate("x.b = 6; x.b")); Assert.AreEqual(PropertyAttributes.Enumerable, TestUtils.EvaluateAccessibility("x", "a")); // length Assert.AreEqual(1, TestUtils.Evaluate("Object.freeze.length")); // Argument must be an object. Assert.AreEqual("TypeError", TestUtils.EvaluateExceptionType("Object.freeze()")); Assert.AreEqual("TypeError", TestUtils.EvaluateExceptionType("Object.freeze(undefined)")); Assert.AreEqual("TypeError", TestUtils.EvaluateExceptionType("Object.freeze(null)")); Assert.AreEqual("TypeError", TestUtils.EvaluateExceptionType("Object.freeze(true)")); Assert.AreEqual("TypeError", TestUtils.EvaluateExceptionType("Object.freeze(5)")); Assert.AreEqual("TypeError", TestUtils.EvaluateExceptionType("Object.freeze('test')")); }
public void Constructor() { // Construct Assert.AreEqual("[object Object]", TestUtils.Evaluate("new Object().toString()")); Assert.AreEqual("[object Object]", TestUtils.Evaluate("new Object(undefined).toString()")); Assert.AreEqual("[object Object]", TestUtils.Evaluate("new Object(null).toString()")); Assert.AreEqual("hi", TestUtils.Evaluate("new Object('hi').valueOf()")); Assert.AreEqual(5501, TestUtils.Evaluate("new Object(5501).valueOf()")); Assert.AreEqual(true, TestUtils.Evaluate("x = new String('test'); new Object(x) === x")); Assert.AreEqual(true, TestUtils.Evaluate("x = new Number(55); new Object(x) === x")); // Call Assert.AreEqual("[object Object]", TestUtils.Evaluate("Object().toString()")); Assert.AreEqual("[object Object]", TestUtils.Evaluate("Object(undefined).toString()")); Assert.AreEqual("[object Object]", TestUtils.Evaluate("Object(null).toString()")); Assert.AreEqual("hi", TestUtils.Evaluate("Object('hi').valueOf()")); Assert.AreEqual(5501, TestUtils.Evaluate("Object(5501).valueOf()")); Assert.AreEqual(true, TestUtils.Evaluate("x = new String('test'); Object(x) === x")); Assert.AreEqual(true, TestUtils.Evaluate("x = new Number(55); Object(x) === x")); // length Assert.AreEqual(1, TestUtils.Evaluate("Object.length")); // toString Assert.AreEqual("function Object() { [native code] }", TestUtils.Evaluate("Object.toString()")); // valueOf Assert.AreEqual(true, TestUtils.Evaluate("Object.valueOf() === Object")); // prototype Assert.AreEqual(true, TestUtils.Evaluate("Object.prototype === Object.getPrototypeOf(new Object())")); Assert.AreEqual(PropertyAttributes.Sealed, TestUtils.EvaluateAccessibility("Object", "prototype")); // constructor Assert.AreEqual(true, TestUtils.Evaluate("Object.prototype.constructor === Object")); Assert.AreEqual(PropertyAttributes.NonEnumerable, TestUtils.EvaluateAccessibility("Object.prototype", "constructor")); // Functions are writable and configurable. Assert.AreEqual(PropertyAttributes.NonEnumerable, TestUtils.EvaluateAccessibility("Object", "keys")); Assert.AreEqual(PropertyAttributes.NonEnumerable, TestUtils.EvaluateAccessibility("Object.prototype", "hasOwnProperty")); }
public void defineProperty() { // Add simple property. Assert.AreEqual(true, TestUtils.Evaluate("var x = {}; Object.defineProperty(x, 'a', {value: 7, enumerable: true, writable: true, configurable: true}) === x")); Assert.AreEqual(7, TestUtils.Evaluate("x.a")); Assert.AreEqual(PropertyAttributes.FullAccess, TestUtils.EvaluateAccessibility("x", "a")); Assert.AreEqual("a", TestUtils.Evaluate("var p = ''; for (var y in x) { p += y } p")); Assert.AreEqual(5, TestUtils.Evaluate("x.a = 5; x.a")); Assert.AreEqual(true, TestUtils.Evaluate("delete x.a")); Assert.AreEqual(Undefined.Value, TestUtils.Evaluate("x.a")); // Add non-writable property. Assert.AreEqual(true, TestUtils.Evaluate("var x = {}; Object.defineProperty(x, 'a', {value: 7, enumerable: true, writable: false, configurable: true}) === x")); Assert.AreEqual(7, TestUtils.Evaluate("x.a")); Assert.AreEqual(PropertyAttributes.Enumerable | PropertyAttributes.Configurable, TestUtils.EvaluateAccessibility("x", "a")); Assert.AreEqual("a", TestUtils.Evaluate("var p = ''; for (var y in x) { p += y } p")); Assert.AreEqual(7, TestUtils.Evaluate("x.a = 5; x.a")); Assert.AreEqual(true, TestUtils.Evaluate("delete x.a")); Assert.AreEqual(Undefined.Value, TestUtils.Evaluate("x.a")); // Non-writable properties can have the value changed (as long as configurable = true). Assert.AreEqual(true, TestUtils.Evaluate("var x = {}; Object.defineProperty(x, 'a', {value: 7, enumerable: true, writable: false, configurable: true}) === x")); Assert.AreEqual(8, TestUtils.Evaluate("Object.defineProperty(x, 'a', {value: 8, enumerable: true, writable: false, configurable: true}); x.a")); Assert.AreEqual(9, TestUtils.Evaluate("Object.defineProperty(x, 'a', {value: 9, enumerable: true, writable: false, configurable: false}); x.a")); Assert.AreEqual("TypeError", TestUtils.EvaluateExceptionType("Object.defineProperty(x, 'a', {value: 10, enumerable: true, writable: false, configurable: false}); x.a")); // Non-writable properties can be switched to accessor properties (as long as configurable = true). Assert.AreEqual(true, TestUtils.Evaluate("var x = {}; Object.defineProperty(x, 'a', {value: 7, enumerable: true, writable: false, configurable: true}) === x")); Assert.AreEqual(1, TestUtils.Evaluate("Object.defineProperty(x, 'a', {get: function() { return 1 }, enumerable: true, configurable: true}); x.a")); // Non-writable properties can go back to writable. Assert.AreEqual(true, TestUtils.Evaluate("var x = {}; Object.defineProperty(x, 'a', {value: 7, enumerable: true, writable: false, configurable: true}) === x")); Assert.AreEqual(8, TestUtils.Evaluate("Object.defineProperty(x, 'a', {value: 8, enumerable: true, writable: true, configurable: true}); x.a")); Assert.AreEqual(true, TestUtils.Evaluate("Object.getOwnPropertyDescriptor(x, 'a').writable")); // Add non-enumerable property. Assert.AreEqual(true, TestUtils.Evaluate("var x = {}; Object.defineProperty(x, 'a', {value: 7, enumerable: false, writable: true, configurable: true}) === x")); Assert.AreEqual(7, TestUtils.Evaluate("x.a")); Assert.AreEqual(PropertyAttributes.NonEnumerable, TestUtils.EvaluateAccessibility("x", "a")); Assert.AreEqual("", TestUtils.Evaluate("var p = ''; for (var y in x) { p += y } p")); Assert.AreEqual(5, TestUtils.Evaluate("x.a = 5; x.a")); Assert.AreEqual(true, TestUtils.Evaluate("delete x.a")); Assert.AreEqual(Undefined.Value, TestUtils.Evaluate("x.a")); // Add non-configurable property. Assert.AreEqual(true, TestUtils.Evaluate("var x = {}; Object.defineProperty(x, 'a', {value: 7, enumerable: true, writable: true, configurable: false}) === x")); Assert.AreEqual(7, TestUtils.Evaluate("x.a")); Assert.AreEqual(PropertyAttributes.Enumerable | PropertyAttributes.Writable, TestUtils.EvaluateAccessibility("x", "a")); Assert.AreEqual("a", TestUtils.Evaluate("var p = ''; for (var y in x) { p += y } p")); Assert.AreEqual(5, TestUtils.Evaluate("x.a = 5; x.a")); Assert.AreEqual(false, TestUtils.Evaluate("delete x.a")); Assert.AreEqual(5, TestUtils.Evaluate("x.a")); // Add read-only accessor property. Assert.AreEqual(true, TestUtils.Evaluate("var x = {}; Object.defineProperty(x, 'a', {get: function() { return 7 }, enumerable: true, configurable: true}) === x")); Assert.AreEqual(7, TestUtils.Evaluate("x.a")); Assert.AreEqual(Undefined.Value, TestUtils.Evaluate("Object.getOwnPropertyDescriptor(x, 'a').value")); Assert.AreEqual("function", TestUtils.Evaluate("typeof(Object.getOwnPropertyDescriptor(x, 'a').get)")); Assert.AreEqual(Undefined.Value, TestUtils.Evaluate("Object.getOwnPropertyDescriptor(x, 'a').set")); Assert.AreEqual(true, TestUtils.Evaluate("Object.getOwnPropertyDescriptor(x, 'a').enumerable")); Assert.AreEqual(Undefined.Value, TestUtils.Evaluate("Object.getOwnPropertyDescriptor(x, 'a').writable")); Assert.AreEqual(true, TestUtils.Evaluate("Object.getOwnPropertyDescriptor(x, 'a').configurable")); Assert.AreEqual(7, TestUtils.Evaluate("x.a = 5; x.a")); Assert.AreEqual(true, TestUtils.Evaluate("delete x.a")); Assert.AreEqual(Undefined.Value, TestUtils.Evaluate("x.a")); // Add read-write accessor property. Assert.AreEqual(true, TestUtils.Evaluate("var x = {a2: 10}; Object.defineProperty(x, 'a', {get: function() { return this.a2 }, set: function(value) { this.a2 = value }, enumerable: true, configurable: true}) === x")); Assert.AreEqual(10, TestUtils.Evaluate("x.a")); Assert.AreEqual(Undefined.Value, TestUtils.Evaluate("Object.getOwnPropertyDescriptor(x, 'a').value")); Assert.AreEqual("function", TestUtils.Evaluate("typeof(Object.getOwnPropertyDescriptor(x, 'a').get)")); Assert.AreEqual("function", TestUtils.Evaluate("typeof(Object.getOwnPropertyDescriptor(x, 'a').set)")); Assert.AreEqual(true, TestUtils.Evaluate("Object.getOwnPropertyDescriptor(x, 'a').enumerable")); Assert.AreEqual(Undefined.Value, TestUtils.Evaluate("Object.getOwnPropertyDescriptor(x, 'a').writable")); Assert.AreEqual(true, TestUtils.Evaluate("Object.getOwnPropertyDescriptor(x, 'a').configurable")); Assert.AreEqual(5, TestUtils.Evaluate("x.a = 5; x.a")); Assert.AreEqual(true, TestUtils.Evaluate("delete x.a")); Assert.AreEqual(Undefined.Value, TestUtils.Evaluate("x.a")); // Add write-only accessor property. Assert.AreEqual(true, TestUtils.Evaluate("var x = {}; Object.defineProperty(x, 'a', {set: function(value) { this.a2 = value }, enumerable: true, configurable: true}) === x")); Assert.AreEqual(Undefined.Value, TestUtils.Evaluate("x.a")); Assert.AreEqual(Undefined.Value, TestUtils.Evaluate("Object.getOwnPropertyDescriptor(x, 'a').value")); Assert.AreEqual(Undefined.Value, TestUtils.Evaluate("Object.getOwnPropertyDescriptor(x, 'a').get")); Assert.AreEqual("function", TestUtils.Evaluate("typeof(Object.getOwnPropertyDescriptor(x, 'a').set)")); Assert.AreEqual(true, TestUtils.Evaluate("Object.getOwnPropertyDescriptor(x, 'a').enumerable")); Assert.AreEqual(Undefined.Value, TestUtils.Evaluate("Object.getOwnPropertyDescriptor(x, 'a').writable")); Assert.AreEqual(true, TestUtils.Evaluate("Object.getOwnPropertyDescriptor(x, 'a').configurable")); Assert.AreEqual(Undefined.Value, TestUtils.Evaluate("x.a = 5; x.a")); Assert.AreEqual(5, TestUtils.Evaluate("x.a = 5; x.a2")); Assert.AreEqual(true, TestUtils.Evaluate("delete x.a")); Assert.AreEqual(Undefined.Value, TestUtils.Evaluate("x.a")); // An empty property descriptor defines a default property (if the property doesn't already exist). Assert.AreEqual(true, TestUtils.Evaluate("var x = {}; Object.defineProperty(x, 'a', {}) === x")); Assert.AreEqual(Undefined.Value, TestUtils.Evaluate("x.a")); Assert.AreEqual(true, TestUtils.Evaluate("x.hasOwnProperty('a')")); Assert.AreEqual(Undefined.Value, TestUtils.Evaluate("Object.getOwnPropertyDescriptor(x, 'a').value")); Assert.AreEqual(Undefined.Value, TestUtils.Evaluate("Object.getOwnPropertyDescriptor(x, 'a').get")); Assert.AreEqual(Undefined.Value, TestUtils.Evaluate("Object.getOwnPropertyDescriptor(x, 'a').set")); Assert.AreEqual(false, TestUtils.Evaluate("Object.getOwnPropertyDescriptor(x, 'a').enumerable")); Assert.AreEqual(false, TestUtils.Evaluate("Object.getOwnPropertyDescriptor(x, 'a').writable")); Assert.AreEqual(false, TestUtils.Evaluate("Object.getOwnPropertyDescriptor(x, 'a').configurable")); // An empty property descriptor does nothing if the property already exists. Assert.AreEqual(true, TestUtils.Evaluate("var x = {a: 5}; Object.defineProperty(x, 'a', {}) === x")); Assert.AreEqual(5, TestUtils.Evaluate("x.a")); Assert.AreEqual(true, TestUtils.Evaluate("x.hasOwnProperty('a')")); Assert.AreEqual(5, TestUtils.Evaluate("Object.getOwnPropertyDescriptor(x, 'a').value")); Assert.AreEqual(Undefined.Value, TestUtils.Evaluate("Object.getOwnPropertyDescriptor(x, 'a').get")); Assert.AreEqual(Undefined.Value, TestUtils.Evaluate("Object.getOwnPropertyDescriptor(x, 'a').set")); Assert.AreEqual(true, TestUtils.Evaluate("Object.getOwnPropertyDescriptor(x, 'a').enumerable")); Assert.AreEqual(true, TestUtils.Evaluate("Object.getOwnPropertyDescriptor(x, 'a').writable")); Assert.AreEqual(true, TestUtils.Evaluate("Object.getOwnPropertyDescriptor(x, 'a').configurable")); // A property descriptor without a value does not change the existing value. Assert.AreEqual(true, TestUtils.Evaluate("var x = {a: 5}; Object.defineProperty(x, 'a', {writable: false}) === x")); Assert.AreEqual(5, TestUtils.Evaluate("x.a")); Assert.AreEqual(true, TestUtils.Evaluate("x.hasOwnProperty('a')")); Assert.AreEqual(5, TestUtils.Evaluate("Object.getOwnPropertyDescriptor(x, 'a').value")); Assert.AreEqual(Undefined.Value, TestUtils.Evaluate("Object.getOwnPropertyDescriptor(x, 'a').get")); Assert.AreEqual(Undefined.Value, TestUtils.Evaluate("Object.getOwnPropertyDescriptor(x, 'a').set")); Assert.AreEqual(true, TestUtils.Evaluate("Object.getOwnPropertyDescriptor(x, 'a').enumerable")); Assert.AreEqual(false, TestUtils.Evaluate("Object.getOwnPropertyDescriptor(x, 'a').writable")); Assert.AreEqual(true, TestUtils.Evaluate("Object.getOwnPropertyDescriptor(x, 'a').configurable")); // get and set can be undefined. Assert.AreEqual(true, TestUtils.Evaluate("var x = {}; Object.defineProperty(x, 'a', {get: function() { return 1; }, set: undefined, configurable: true}) === x")); Assert.AreEqual(1, TestUtils.Evaluate("x.a")); Assert.AreEqual(true, TestUtils.Evaluate("Object.defineProperty(x, 'a', {get: undefined, set: undefined}) === x")); Assert.AreEqual(Undefined.Value, TestUtils.Evaluate("x.a")); // Non-extensible objects cannot have properties added. Assert.AreEqual(true, TestUtils.Evaluate("var x = {}; Object.preventExtensions(x) === x")); Assert.AreEqual("TypeError", TestUtils.EvaluateExceptionType("Object.defineProperty(x, 'a', {value: 7, enumerable: true, writable: true, configurable: true})")); // Non-configurable properties can only have the value changed. Assert.AreEqual(true, TestUtils.Evaluate("var x = {}; Object.defineProperty(x, 'a', {value: 7, enumerable: true, writable: true, configurable: false}) === x")); Assert.AreEqual(10, TestUtils.Evaluate("Object.defineProperty(x, 'a', {value: 10, enumerable: true, writable: true, configurable: false}); x.a")); Assert.AreEqual("TypeError", TestUtils.EvaluateExceptionType("Object.defineProperty(x, 'a', {get: function() { return 7; }, enumerable: true, writable: true, configurable: false}); x.a")); Assert.AreEqual("TypeError", TestUtils.EvaluateExceptionType("Object.defineProperty(x, 'a', {value: 10, enumerable: false, writable: true, configurable: false})")); Assert.AreEqual("TypeError", TestUtils.EvaluateExceptionType("Object.defineProperty(x, 'a', {value: 10, enumerable: true, writable: false, configurable: false})")); Assert.AreEqual("TypeError", TestUtils.EvaluateExceptionType("Object.defineProperty(x, 'a', {value: 10, enumerable: true, writable: true, configurable: true})")); Assert.AreEqual(true, TestUtils.Evaluate("var x = {}; var f = function() { return 1; }; Object.defineProperty(x, 'a', {get: f}); Object.defineProperty(x, 'a', {get: f}) === x")); Assert.AreEqual(true, TestUtils.Evaluate("var x = {}; Object.defineProperty(x, 'a', {get: function() { return 1; }}); Object.defineProperty(x, 'a', {set: undefined}) === x")); // Value is not allowed when specifying an accessor property. Assert.AreEqual("TypeError", TestUtils.EvaluateExceptionType("var x = {}; Object.defineProperty(x, 'a', {get: function() { return 7 }, enumerable: true, configurable: true, value: 5})")); Assert.AreEqual("TypeError", TestUtils.EvaluateExceptionType("var x = {}; Object.defineProperty(x, 'a', {get: function() { return 7 }, set: function() { }, enumerable: true, configurable: true, value: 5})")); Assert.AreEqual("TypeError", TestUtils.EvaluateExceptionType("var x = {}; Object.defineProperty(x, 'a', {set: function() { }, enumerable: true, configurable: true, value: 5})")); // Writable is not allowed when specifying an accessor property. Assert.AreEqual("TypeError", TestUtils.EvaluateExceptionType("var x = {}; Object.defineProperty(x, 'a', {get: function() { return 7 }, enumerable: true, writable: false, configurable: true})")); Assert.AreEqual("TypeError", TestUtils.EvaluateExceptionType("var x = {}; Object.defineProperty(x, 'a', {get: function() { return 7 }, set: function() { }, enumerable: true, writable: true, configurable: true})")); Assert.AreEqual("TypeError", TestUtils.EvaluateExceptionType("var x = {}; Object.defineProperty(x, 'a', {set: function() { }, enumerable: true, writable: true, configurable: true})")); // Get and set must be a function. Assert.AreEqual("TypeError", TestUtils.EvaluateExceptionType("var x = {}; Object.defineProperty(x, 'a', {get: 5, enumerable: true, configurable: true})")); Assert.AreEqual("TypeError", TestUtils.EvaluateExceptionType("var x = {}; Object.defineProperty(x, 'a', {get: 5, set: 5, enumerable: true, configurable: true})")); Assert.AreEqual("TypeError", TestUtils.EvaluateExceptionType("var x = {}; Object.defineProperty(x, 'a', {set: 5, enumerable: true, configurable: true})")); // length Assert.AreEqual(3, TestUtils.Evaluate("Object.defineProperty.length")); // Argument must be an object. Assert.AreEqual("TypeError", TestUtils.EvaluateExceptionType("Object.defineProperty()")); Assert.AreEqual("TypeError", TestUtils.EvaluateExceptionType("Object.defineProperty({})")); Assert.AreEqual("TypeError", TestUtils.EvaluateExceptionType("Object.defineProperty(undefined, {})")); Assert.AreEqual("TypeError", TestUtils.EvaluateExceptionType("Object.defineProperty(null, {})")); Assert.AreEqual("TypeError", TestUtils.EvaluateExceptionType("Object.defineProperty(true, {})")); Assert.AreEqual("TypeError", TestUtils.EvaluateExceptionType("Object.defineProperty(5, {})")); Assert.AreEqual("TypeError", TestUtils.EvaluateExceptionType("Object.defineProperty('test', {})")); // Property descriptors must be objects. Assert.AreEqual("TypeError", TestUtils.EvaluateExceptionType("Object.defineProperty({}, 'a', 5)")); Assert.AreEqual("TypeError", TestUtils.EvaluateExceptionType("Object.defineProperty({}, 'a', undefined)")); Assert.AreEqual("TypeError", TestUtils.EvaluateExceptionType("Object.defineProperty({}, 'a', null)")); }