| description('Test caller and arguments properties in function in non strict mode'); |
| |
| function foo() { |
| return 1; |
| } |
| |
| shouldBe('Object.getOwnPropertyNames(function () {}).length', '3'); |
| |
| shouldBeFalse('Object.getOwnPropertyNames(function () {}).includes("caller")'); |
| shouldBeFalse('Object.getOwnPropertyNames(function () {}).includes("arguments")'); |
| |
| shouldBeFalse('(function(){}).hasOwnProperty("caller")'); |
| shouldBeTrue('(function(){}).__proto__.hasOwnProperty("caller")'); |
| |
| shouldBeFalse('(function(){}).hasOwnProperty("arguments")'); |
| shouldBeTrue('(function(){}).__proto__.hasOwnProperty("arguments")'); |
| |
| shouldBe('typeof Object.getOwnPropertyDescriptor(foo, "arguments")', '"undefined"'); |
| shouldBe('typeof Object.getOwnPropertyDescriptor(foo, "caller")', '"undefined"'); |
| |
| shouldBe('foo.caller', 'null'); |
| shouldBe('foo.arguments', 'null'); |
| |
| foo.caller = 10; |
| foo.arguments = 10; |
| |
| shouldBe('foo.caller', 'null'); |
| shouldBe('foo.arguments', 'null'); |
| |
| var boo = function () { return boo.arguments; }; |
| |
| shouldBe('boo("abc")[0]','"abc"'); |
| |
| boo.arguments = 'not-expected-value'; |
| shouldBe('boo("expected-value")[0]','"expected-value"'); |
| |
| var f = function () { return f.caller; }; |
| var g = function (cb) { return cb(); }; |
| |
| shouldBe('g(f)','g'); |
| |
| var doSetCaller = function (value, doDelete) { |
| var f = function () {}; |
| if (doDelete) |
| delete f.__proto__.caller; |
| f.__proto__.caller = value; |
| return f; |
| }; |
| |
| var value = "property-value"; |
| |
| shouldThrow("doSetCaller(value, false)", "'TypeError: \\'arguments\\', \\'callee\\', and \\'caller\\' cannot be accessed in this context.'"); |
| shouldBe("doSetCaller(value, true).__proto__.caller", "value"); |
| |
| |
| var doSetArguments = function (value, doDelete) { |
| var f = function () {}; |
| if (doDelete) |
| delete f.__proto__.arguments; |
| f.__proto__.arguments = value; |
| return f; |
| }; |
| |
| shouldThrow("doSetArguments(value, false)", "'TypeError: \\'arguments\\', \\'callee\\', and \\'caller\\' cannot be accessed in this context.'"); |
| shouldBe("doSetArguments(value, true).__proto__.arguments", "value"); |