| /* Any copyright is dedicated to the Public Domain. |
| * http://creativecommons.org/licenses/publicdomain/ */ |
| |
| // Very simple initial test that the "length" property of a function is |
| // configurable. More thorough tests follow. |
| var f = function (a1, a2, a3, a4) {}; |
| assertEq(delete f.length, true); |
| assertEq(f.hasOwnProperty("length"), false); |
| assertEq(f.length, 0); // inherited from Function.prototype.length |
| assertEq(delete Function.prototype.length, true); |
| assertEq(f.length, undefined); |
| |
| |
| // Now for the details. |
| // |
| // Many of these tests are poking at the "resolve hook" mechanism SM uses to |
| // lazily create this property, which is wonky and deserving of some extra |
| // skepticism. |
| |
| // We've deleted Function.prototype.length. Check that the resolve hook does |
| // not resurrect it. |
| assertEq("length" in Function.prototype, false); |
| Function.prototype.length = 7; |
| assertEq(Function.prototype.length, 7); |
| delete Function.prototype.length; |
| assertEq(Function.prototype.length, undefined); |
| |
| // OK, define Function.prototype.length back to its original state per spec, so |
| // the remaining tests can run in a more typical environment. |
| Object.defineProperty(Function.prototype, "length", {value: 0, configurable: true}); |
| |
| // Check the property descriptor of a function length property. |
| var g = function f(a1, a2, a3, a4, a5) {}; |
| var desc = Object.getOwnPropertyDescriptor(g, "length"); |
| assertEq(desc.configurable, true); |
| assertEq(desc.enumerable, false); |
| assertEq(desc.writable, false); |
| assertEq(desc.value, 5); |
| |
| // After deleting the length property, assigning to f.length fails because |
| // Function.prototype.length is non-writable. In strict mode it would throw. |
| delete g.length; |
| g.length = 12; |
| assertEq(g.hasOwnProperty("length"), false); |
| assertEq(g.length, 0); |
| |
| // After deleting both the length property and Function.prototype.length, |
| // assigning to f.length creates a new plain old data property. |
| delete Function.prototype.length; |
| g.length = 13; |
| var desc = Object.getOwnPropertyDescriptor(g, "length"); |
| assertEq(desc.configurable, true); |
| assertEq(desc.enumerable, true); |
| assertEq(desc.writable, true); |
| assertEq(desc.value, 13); |
| |
| // Deleting the .length of one instance of a FunctionDeclaration does not |
| // affect other instances. |
| function mkfun() { |
| function fun(a1, a2, a3, a4, a5) {} |
| return fun; |
| } |
| g = mkfun(); |
| var h = mkfun(); |
| delete h.length; |
| assertEq(g.length, 5); |
| assertEq(mkfun().length, 5); |
| |
| // Object.defineProperty on a brand-new function is sufficient to cause the |
| // LENGTH_RESOLVED flag to be set. |
| g = mkfun(); |
| Object.defineProperty(g, "length", {value: 0}); |
| assertEq(delete g.length, true); |
| assertEq(g.hasOwnProperty("length"), false); |
| |
| // Object.defineProperty on a brand-new function correctly merges new |
| // attributes with the builtin ones. |
| g = mkfun(); |
| Object.defineProperty(g, "length", { value: 42 }); |
| desc = Object.getOwnPropertyDescriptor(g, "length"); |
| assertEq(desc.configurable, true); |
| assertEq(desc.enumerable, false); |
| assertEq(desc.writable, false); |
| assertEq(desc.value, 42); |
| |
| reportCompare(0, 0, 'ok'); |