diff --git a/test/built-ins/Function/prototype/caller-arguments/accessor-properties.js b/test/built-ins/Function/prototype/caller-arguments/accessor-properties.js new file mode 100644 index 0000000000..b58d2bc562 --- /dev/null +++ b/test/built-ins/Function/prototype/caller-arguments/accessor-properties.js @@ -0,0 +1,18 @@ +/*--- +description: Function.prototype caller and arguments properties are accessor properties with ThrowTypeError +esid: sec-function.prototype.caller +info: | + Function instances do not inherit the "caller" and "arguments" accessors + from Function.prototype. The accessors exist only on Function.prototype. +---*/ + +const callerDesc = Object.getOwnPropertyDescriptor(Function.prototype, "caller"); +const argumentsDesc = Object.getOwnPropertyDescriptor(Function.prototype, "arguments"); + +assert.sameValue(typeof callerDesc.get, "function"); +assert.sameValue(typeof callerDesc.set, "function"); +assert.sameValue(callerDesc.get, callerDesc.set, "caller getter/setter should be same function"); + +assert.sameValue(typeof argumentsDesc.get, "function"); +assert.sameValue(typeof argumentsDesc.set, "function"); +assert.sameValue(argumentsDesc.get, argumentsDesc.set, "arguments getter/setter should be same function"); diff --git a/test/built-ins/Function/prototype/caller-arguments/cross-realm-behavior.js b/test/built-ins/Function/prototype/caller-arguments/cross-realm-behavior.js new file mode 100644 index 0000000000..925ea5e486 --- /dev/null +++ b/test/built-ins/Function/prototype/caller-arguments/cross-realm-behavior.js @@ -0,0 +1,13 @@ +/*--- +description: Function.prototype caller and arguments properties use the same ThrowTypeError across realms +features: [cross-realm] +---*/ + +const otherRealm = $262.createRealm(); +const otherFunctionProto = otherRealm.evaluate('Function.prototype'); + +const mainCallerDesc = Object.getOwnPropertyDescriptor(Function.prototype, "caller"); +const otherCallerDesc = Object.getOwnPropertyDescriptor(otherFunctionProto, "caller"); + +assert.sameValue(mainCallerDesc.get, otherCallerDesc.get, "caller getter should be same across realms"); +assert.sameValue(mainCallerDesc.set, otherCallerDesc.set, "caller setter should be same across realms"); diff --git a/test/built-ins/Function/prototype/caller-arguments/module-context.js b/test/built-ins/Function/prototype/caller-arguments/module-context.js new file mode 100644 index 0000000000..18944c3c3d --- /dev/null +++ b/test/built-ins/Function/prototype/caller-arguments/module-context.js @@ -0,0 +1,12 @@ +/*--- +description: Function properties behave consistently in module context +flags: [module] +---*/ + +function normalFunc() {} +function strictFunc() { } + +assert(!Object.hasOwnProperty.call(normalFunc, "caller"), "normal function should not have caller"); +assert(!Object.hasOwnProperty.call(strictFunc, "caller"), "strict function should not have caller"); +assert(!Object.hasOwnProperty.call(normalFunc, "arguments"), "normal function should not have arguments"); +assert(!Object.hasOwnProperty.call(strictFunc, "arguments"), "strict function should not have arguments"); diff --git a/test/built-ins/Function/prototype/caller-arguments/strict-vs-nonstrict.js b/test/built-ins/Function/prototype/caller-arguments/strict-vs-nonstrict.js new file mode 100644 index 0000000000..e9c99b400a --- /dev/null +++ b/test/built-ins/Function/prototype/caller-arguments/strict-vs-nonstrict.js @@ -0,0 +1,18 @@ +/*--- +description: Function properties behavior in strict vs non-strict contexts +flags: [noStrict] +---*/ + +function nonStrictFunc() { + return nonStrictFunc.caller; +} + +function strictFunc() { + return strictFunc.caller; +} + +assert(!Object.hasOwnProperty.call(nonStrictFunc, "caller"), "non-strict function should not have own caller property"); +assert(!Object.hasOwnProperty.call(strictFunc, "caller"), "strict function should not have own caller property"); + +assert.throws(TypeError, () => nonStrictFunc(), "accessing caller should throw"); +assert.throws(TypeError, () => strictFunc(), "accessing caller should throw in strict mode");